Построение quines (функции самовоспроизведения)

Кто-нибудь построил quine ( "Программа, которая генерирует копию собственного исходного текста в качестве своего полного вывода": http://www.nyx.net/~gthompso/quine.htm) в R? (Тег [quine] вытаскивает множество примеров в Python, Java,... но, по-видимому, ни один в R.)

f <- function() { body() }

близок:

> f()
{
    body()
}

но не имеет имени функции.

Как насчет кратчайшей возможности? Большинство запутанных?

edit: из множества ответов ниже, кажется, что существует множество способов определить самореференцию и среду, в которой она должна произойти:

  • в среде R: функция -> (@bill_080)
  • в среде OS/shell: программа -> [более или менее эквивалентна программе -> text]: (@kohske)
  • other: function -> text (@JoshUlrich, @James, проблема, как определено выше)

Примечания:

  • поток из R-справки, отмеченный @Spacedman (который, кажется, подчеркивает обфускацию по краткости) предполагает, что identical(quine,quine()) является хороший тестовый пример, хотя это сложно, потому что окружающая среда переносится вдоль: identical(quine,quine(),ignore.environment=TRUE) может быть проще.
  • Последнее сообщение (октябрь 2015 г.) сообщение в блоге дает другой ответ...

Ответы

Ответ 1

Это самое короткое, что я могу придумать:

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

Ответ 2

Вот настоящий Quine, программа (а не функция), которая генерирует копию собственного исходного текста в качестве его полного вывода.

На консоли,

# 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

возможно, это не самый короткий.

ОБНОВЛЕНО:

и немного более короткая версия:

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

Ответ 3

Используя то, что body делает в качестве вдохновения, call может использоваться для воспроизведения вызывающей команды:

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

Какие выходы:

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

Ответ 4

Если вы хотите функцию, которая возвращает функцию..... возможно, это?

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

Вывод:

> junk()

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


> boo <- junk(999)
> boo

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


>dput(boo)

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

Ответ 5

Хотя я не уверен, что это "считается" с точки зрения перспективы (я наткнулся на этот вопрос, пытаясь проверить, если он это делает), script

function(){}

выводит function(){}. Это работает по тому же принципу, что и ответ Джошуа Ульриха, только что сведенный к делу.