Is it possible to write a program that outputs its own code in Perl?

  • Context: Undergrad 
  • Thread starter Thread starter daniel_i_l
  • Start date Start date
  • Tags Tags
    Program
Click For Summary

Discussion Overview

The discussion revolves around the possibility of writing a program that outputs its own source code, commonly referred to as a "quine." Participants explore this concept across various programming languages, particularly focusing on Perl and C++. The scope includes theoretical considerations, practical implementations, and challenges associated with creating such programs.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • Some participants assert that it is indeed possible to write a program that outputs its own code, referencing the concept of a quine.
  • One participant describes a method involving a function that outputs a string representing the program's code, suggesting that any program can be assumed to have access to its own source code.
  • A Perl example is provided that attempts to read its own source code from a file, though some participants express uncertainty about the implementation details.
  • Another participant discusses a C++ approach that involves reading the program's own filename, but raises concerns about the assumptions made regarding file locations and types.
  • Some participants challenge the idea that reading from a file constitutes a true quine, arguing that it relies on external processes rather than self-replication.
  • One participant notes the potential for infinite regress when trying to include the printing code within the output itself, suggesting that this complicates the creation of a true quine.
  • A later reply emphasizes that clever mechanisms exist to avoid infinite regress, referencing solutions discussed in linked resources.
  • A participant shares a Perl implementation of a quine, detailing how it avoids reading from external files and instead constructs the output programmatically.

Areas of Agreement / Disagreement

Participants express a mix of agreement on the feasibility of creating quines while also presenting competing views on the methods and assumptions involved. The discussion remains unresolved regarding the best approach and the definitions of a true quine.

Contextual Notes

Some participants highlight limitations in their proposed methods, such as assumptions about file locations and the nature of input/output processes. The discussion also reflects varying interpretations of what constitutes a program outputting its own code.

daniel_i_l
Gold Member
Messages
864
Reaction score
0
Is it possible to write a program (in any language) so that the output is the code of the program itself?
 
Mathematics news on Phys.org
10 LIST

On ZX Spectrum :smile:
 
Last edited:
daniel_i_l said:
Is it possible to write a program (in any language) so that the output is the code of the program itself?

Yes.

I wrote a mini-compiler in interpreted basic about 30 years ago who's output was a machine level code that would perform the exact same function.

Of course the machine level program was about 10,000 times faster.

Though "10 LIST" is much simpler and doesn't take 10 hours to write. :-p
 
Such a program is called a "quine" (presumably after Willard Quine).
 
A formulaic way to do it is:

Choose a specific function f so that f(S) is a program that outputs the string S.

Let A be a program that inputs a string S, prints it, then prints f(S).

Now, run the program:
1. f(A)
2. A​

Tweak the details as appropriate for your programming language. An important variation on this method proves the important theoretical result that we can assume any program has access to its own source code.
 
#!/usr/bin/perl
while(<>){
print;
}save in a file called "program", then do ./program program. Actually, it's entirely possible to do that without needing to pass the name as an argument to perl (this is stored in the variable $0, I think) so something like

#!/usr/bin/perl
open($_,"<$0");
while(<>){
print;
}
close($_);

should do it, but I've no intention of trying it to find out if I got the right interpolation in the string"<$0".
 
in c++ (or any language which produces a separate compiled file) you can do it easily..
write a program which reads a text file with name same as that of itself..

int main(int argc, char* argv[])
{
string filename = argv[0];
readFile(filename);
}

it ll work coz the executable and the source code are in different files.. don't know how u ll get it work for a programme spanning multiple files..
 
The idea (although not listed in the OP) is that the program doesn't accept any input nor doesn't read external files. Besides, you are making several faulty assumptions.

int main(int argc, char* argv[])
{
string filename = argv[0];
readFile(filename);
}

It will not work - first of all, executable and the source files are different, second, files don't have to be in the same directory.

This approach may work for interpreted languages. In fact LIST command does just that, although it doesn't need path nor filename.
 
Borek said:
The idea (although not listed in the OP) is that the program doesn't accept any input nor doesn't read external files. Besides, you are making several faulty assumptions.
It will not work - first of all, executable and the source files are different, second, files don't have to be in the same directory.

it will work if u have only 1 source code file(*.cpp) and keep the exe file in the same directory. of course, u ll have to get the filename correctly.

ya i know, i made several assumptions. however, in the OP when he says code of the program, does he mean the machine code? i d be very interested to know of a way to do that in c++..
 
  • #10
jablonsky27 said:
it will work if u have only 1 source code file(*.cpp) and keep the exe file in the same directory. of course, u ll have to get the filename correctly.

Not only exe must be in the same directory, but both exe and cpp files have to share the same name. It won't work.



 
  • #12
I was going to recommend the Turing award acceptance speech of Ken Thompson, "Reflections on trusting trust",
http://cm.bell-labs.com/who/ken/trust.html

but I see it's one of the links in the Wikipedia page cited above. So I did it anyway. :)
 
Last edited by a moderator:
  • #13
I would do it like this in C++:

Code:
#include <iostream>  // Standard header

int main()
{
 
std::cout << "Hello, world!\n";
  
std::cout << "#include <iostream>  // Standard header\n";
std::cout << "\n";
std::cout << "int main()\n";
std::cout << "{\n";
std::cout << "\n";
std::cout << "std::cout \<\< \"Hello, world!\\n\";\n";
std::cout << "}\n";

}

but I just realized that now the parts that print out the code, would also be needed to be inlcuded, but in doing so would add more lines representing those lines, in effect it would be an infinate regress. I can't see how this would be solved?

EDIT:::

D'oh I just realized the solution is the method one poster above has done, just read a file and print it to screen, but just make sure that file is code itself!
 
Last edited:
  • #14
Anhar Miah said:
D'oh I just realized the solution is the method one poster above has done, just read a file and print it to screen, but just make sure that file is code itself!
That's not a program producing it's source code: that's a program asking an external process for some text, and then displaying it.
 
  • #15
Reading in a file is a boring semi-solution to a clever challenge. The solutions which are discussed and linked to on the wikipedia page exploit much more clever mechanisms to avoid the infinite regress that Anhar found above.
 
  • #16
I used to have a quine I wrote in C, but I lost it. This should do it in perl, without reading in a file:

Code:
#!/usr/bin/perl
use strict;

sub quote;

$string = <<"HERE";
#!/usr/bin/perl
use strict;

sub quote;

\$string = <<"HERE";
placeholder

\$quoted = quote(\$string);
\$string ~= s/^placeholder\$/\$quoted/m;

print \$string;

sub quote {
  my \$s = shift;
  \$s ~= s/\\\$/\\\\\\\$/sg;
  \$s ~= s/\\\\/\\\\\\\\/sg;
  \$s .= "\\nHERE";
  return \$s;
}
HERE

$quoted = quote($string);
$string ~= s/^placeholder$/$quoted/m;

print $string;

sub quote {
  my $s = shift;
  $s ~= s/\$/\\\$/sg;
  $s ~= s/\\/\\\\/sg;
  $s .= "\nHERE";
  return $s;
}
 

Similar threads

Replies
4
Views
6K
Replies
38
Views
4K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 4 ·
Replies
4
Views
1K
  • · Replies 40 ·
2
Replies
40
Views
2K
  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 18 ·
Replies
18
Views
3K
  • · Replies 16 ·
Replies
16
Views
3K
  • · Replies 12 ·
Replies
12
Views
2K