gpt4 book ai didi

lisp - 执行一个函数直到它返回一个 nil,将它的值收集到一个列表中

转载 作者:太空宇宙 更新时间:2023-11-03 18:34:31 25 4
gpt4 key购买 nike

我从 XKCD's Hofstadter comic 得到这个想法;在(任何)Lisp 方言中创建条件循环的最佳方法是什么,该循环执行函数直到返回 NIL,此时它将返回的值收集到列表中。

对于那些还没有看过这个笑话的人来说,道格拉斯·霍夫施塔特的“八字”自传只有六个字:“我太元了,即使是这个首字母缩略词”也包含笑话的延续:(一些奇怪的meta-paraprosdokian?)“Is Meta”——自传实际上是“I'm So Meta,Even This Acronym Is Meta”的笑话。但为什么不更深入呢?

假设首字母缩略函数 META 从字符串创建首字母缩略词并将其拆分为单词,如果字符串只包含一个单词,则返回 NIL:

(meta "I'm So Meta, Even This Acronym") ⇒ "Is Meta"
(meta (meta "I'm So Meta, Even This Acronym")) ⇒ "Im"
(meta (meta (meta "I'm So Meta, Even This Acronym"))) ⇒ NIL

(meta "GNU is Not UNIX") ⇒ "GNU"
(meta (meta "GNU is Not UNIX")) ⇒ NIL

现在我正在寻找如何实现一个函数以便:

(so-function #'meta "I'm So Meta, Even This Acronym") 
⇒ ("I'm So Meta, Even This Acronym" "Is Meta" "Im")
(so-function #'meta "GNU is Not Unix")
⇒ ("GNU is Not Unix" "GNU")

这样做的最佳方法是什么?

最佳答案

这很简单。我不想写一个解决方案,所以我会——但它将是蹩脚的 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 而不是你想要的,so-function 将是一个高阶函数——一个像这样工作的函数:

(funcall (so-function #'meta) "GNU is Not UNIX")

或者,在方案中:

((so-function meta) "GNU is Not UNIX")

这里的重要提示是您不能在普通的 elisp 中完成它(至少不能没有 cl 库的技巧)。要获得完整的信用,请避免突变——这将导致您在 Scheme 中以自然的方式编写它,甚至可能看起来比 setq 版本更具可读性。

关于lisp - 执行一个函数直到它返回一个 nil,将它的值收集到一个列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6510681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com