Has anyone constructed a quine ("A program that generates a copy of its own source text as its complete output": http://www.nyx.net/~gthompso/quine.htm) in R? (The [quine] tag pulls up lots of examples in Python, Java, ... but apparently none in R.)
f <- function() { body() }
comes close:
> f()
{
body()
}
but lacks the name of the function.
How about the shortest possibility? Most obfuscated?
edit: from the variety of answers below, it seems that there are a variety of ways to define self-referentiality and the environment in which it must occur:
->
function (@bill_080)->
program [more or less equivalent to program ->
text]: (@kohske)->
text (@JoshUlrich, @James, problem as defined above)Notes:
identical(quine,quine())
is a good test case, although it's tricky because environments get carried along: identical(quine,quine(),ignore.environment=TRUE)
might be easier.This is the shortest I can come up with:
> "f" <- function() call("<-", "f", f)
> f()
"f" <- function ()
call("<-", "f", f)
Here is a real Quine, a program (not a function) that generates a copy of its own source text as its complete output.
On console,
# y1.R is a quine program
$ cat y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")
# execute y1.R and show output
$ /usr/bin/R --vanilla --slave < y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")
# save the output of the execution of y1
$ /usr/bin/R --vanilla --slave < y1.R > y2.R
# compare input and output -- exactly same.
$ diff y1.R y2.R
probably this is not the shortest one.
UPDATED:
and slightly shorter version:
(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})")
Using what body
does as inspiration, call
can be used to reproduce the calling command:
f <- function ()
{
call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}
Which outputs:
> f()
f <- function ()
{
call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With