2011-06-27 6 views
15

¿Alguien ha construido un quine ("Un programa que genera una copia de su propio texto fuente como su salida completa": http://www.nyx.net/~gthompso/quine.htm) en R? (La etiqueta [Quine] se detiene en un montón de ejemplos en Python, Java, ... pero al parecer ninguno en R.)Construir quines (funciones de autorreproducción)

f <- function() { body() } 

se acerca:

> f() 
{ 
    body() 
} 

pero carece del nombre de la función .

¿Qué tal la posibilidad más corta? ¿Más ofuscado?

edición: a partir de la variedad de respuestas a continuación, parece que hay una variedad de maneras de definir autorreferencialidad y el medio ambiente en el que tiene que ocurrir:

  • en el medio ambiente: R: Función -> función (@ bill_080)
  • dentro del entorno OS/shell: programa programa -> [más o menos equivalente a programar -> texto]: (@kohske)
  • otro: función -> texto (@JoshUlrich, @ James, problema como d efined arriba)

Notas:

  • El thread from R-help pointed out by @Spacedman (que parece enfatizar la ofuscación más de brevedad) sugiere que identical(quine,quine()) es un buen caso de prueba, aunque es difícil porque los ambientes se deja llevar por: fuerza identical(quine,quine(),ignore.environment=TRUE) ser más fácil.
  • Un reciente (octubre de 2015) blog post proporciona otra respuesta ...

Respuesta

22

Esta es la más corta que puedo llegar a:

> "f" <- function() call("<-", "f", f) 
> f() 
"f" <- function() 
call("<-", "f", f) 
6

Usando lo hace body como fuente de inspiración, call se puede utilizar para reproducir el mandato que llama:

f <- function() 
{ 
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent())) 
} 

que da salida:

> f() 
f <- function() 
{ 
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent())) 
} 
+0

Pero 'f() <- function() ...' es un error. –

+0

@Joshua Ulrich Oops, lo arregló ahora. Como una ventaja adicional, la complejidad añadida hace que sea menos fácil de leer y, por lo tanto, más ofuscado. ;) – James

1

Si desea una función que devuelva una función ..... ¿tal vez esto?

junk <- function(...) { 
    function(...) { 
    structure(junk(...)) 
    } 
} 

La salida es:

> junk() 

function(...) { 
    structure(junk(...)) 
    } 
<environment: 01ef8e50> 


> boo <- junk(999) 
> boo 

function(...) { 
    structure(junk(...)) 
    } 
<environment: 020e1048> 


>dput(boo) 

function (...) 
{ 
    structure(junk(...)) 
} 
+1

Algunos enlaces útiles: http://www.stat.auckland.ac.nz/~ihaka/downloads/lexical.pdf http://www.stat.auckland.ac.nz/~ihaka/downloads/Compstat- 2008.pdf –

+0

Me gusta esto, pero la definición específica dada anteriormente es "una función que genera una copia de su propio texto fuente", aunque "una función que genera una copia de sí misma" está más cerca del espíritu de auto-reproducibilidad . En su ejemplo, la función devuelta no es exactamente idéntica a la función original aunque quizás podría reemplazar 'inp' con' ... 'y sería? –

+0

@Ben B, tienes razón. 'inp' era de mí, tratando de ampliar las capacidades. Lo arreglaré. –

21

Aquí es un verdadero Quine, un programa (no una función) que genera una copia de su propio texto fuente como su salida completa.

En la consola,

# 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 

probablemente este no es el más corto.

ACTUALIZADO:

y la versión ligeramente más corto:

(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})") 
+0

+1 para _real_ quine. ;-) –

1

Aunque no estoy seguro de si esta "cuenta" desde una perspectiva de Quine (yo me encontré con esta pregunta al tratar de verificar si lo hace), el script

function(){} 

dará salida a function(){}. Esto funciona según el mismo principio que la respuesta de Joshua Ulrich, solo reducido a lo esencial.