Это легко. Я не хочу писать решение, поэтому вместо этого я сделаю - но это будет дрянная версия elisp, которая может привести к неожиданному просветлению, если вы выполните:
(defun so-function (f str)
(let (x '())
(while str (setq x (cons str x)) (setq str (funcall f str)))
(reverse x)))
Чтобы попробовать это, вам понадобится meta
, но я не знаю, как вы решите, где поставить пробелы, поэтому вместо этого я подделаю:
(defun meta (x)
(cadr (assoc x '(("I'm So Meta, Even This Acronym" "Is Meta")
("Is Meta" "Im")
("GNU is Not UNIX" "GNU")))))
Это делает код, который вы хотите работать. Что касается просветления - попробуйте написать его так, чтобы вместо того, что вы хотите, so-function
будет функцией более высокого порядка - той, которая будет работать так:
(funcall (so-function #'meta) "GNU is Not UNIX")
или, на схеме:
((so-function meta) "GNU is Not UNIX")
Большой намек здесь заключается в том, что вы не можете сделать это обычным образом (по крайней мере, без трюков из библиотеки cl
). Чтобы получить полную оценку, избегайте мутаций - это приведет к тому, что вы напишите это в Scheme естественным образом, и даже может выглядеть более читабельным, чем версия setq
.