gpt4 book ai didi

scope - 如何编写不使用其参数隐藏变量的 PicoLisp 函数

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

我正在随意探索 PicoLisp,发现自己对如何编写传统上用宏(在其他 lisp 方言中)处理的元编程函数感到困惑。我最担心的是我不知道如何防止变量名隐藏。查看 Metaprogramming 101 中的示例有,如果有的话,只是让我更加困惑。

有关如何实现函数 mapeach 的示例,如链接文章中所示:

   [de mapeach "Args"    # expression
(let [(@Var @List . @Body) "Args"]
(macro
(mapcar
'((@Var) . @Body)
@List ]

(de mapeach "Args"
(mapcar
(cons (cons (car "Args")) (cddr "Args"))
(eval (cadr "Args")) ) )

(de mapeach "Args"
(mapcar
'(("E")
(bind (car "Args")
(set (car "Args") "E")
(run (cddr "Args")) ) )
(eval (cadr "Args")) ) )

(de mapeach "Args"
(let "Vars" (pop '"Args")
(apply mapcar
(mapcar eval (cut (length "Vars") '"Args"))
(cons "Vars" "Args") ) ) )

我已经通过调用 (let "Args"* (mapeach N (1 2 3) ("Args"N N))) 测试了其中的每一个。正如预期的那样,PicoLisp 解释器(使用命令 pil + 启动)遇到段错误并崩溃。我认为这是因为 mapeach"Args" 隐藏了在调用点定义的 "Args"

我还尝试了他们对 map@ 的两种实现(mapeach 的“更可爱”替代方案)。

   (de map@ "Args"
(mapcar
'(("E") (and "E" (run (cdr "Args")))) # 'and' sets '@'
(eval (car "Args")) ) )

(de map@ "Args"
(mapcar
'((@) (run (cdr "Args")))
(eval (car "Args")) ) )

我使用 (let "Args"* (map@ (1 2 3) ("Args"@ @))) 来测试每个实现。奇怪的是,我第一次测试第一个实现时,它不仅没有段错误,而且实际上产生了正确的结果 (1 4 9)。随后的每个测试都会导致段错误。为清楚起见,提示中的片段:

:  (de map@ "Args"
(mapcar
'(("E") (and "E" (run (cdr "Args")))) # 'and' sets '@'
(eval (car "Args")) ) )
-> map@
: (let "Args" * (mapeach N (1 2 3) ("Args" N N)))
!? (mapeach N (1 2 3) ("Args" N N))
mapeach -- Undefined
?
: (let "Args" * (map@ (1 2 3) ("Args" @ @)))
-> (1 4 9)

我相信通过调用(当时的)未定义函数 mapeach 以某种方式阻止了段错误,我还尝试了 (ooga booga),这同样阻止了段错误.如果我没有将定义与正确调用分开的错误调用,则总会发生段错误。

这最终会导致 2 个问题:

  1. 如何防止姓名隐藏?显然,这些例子在这方面没有成功。
  2. 为什么对 map@ 的调用不会导致段错误?

最佳答案

According to this “临时符号的索引在加载源文件之前和之后自动清除,或者可以使用 ==== 函数显式重置”。它没有指定在常规 REPL 使用期间自动清除它的任何方式,这是我测试它的上下文。

这段代码运行正常:

[de mapeach "Args"    # expression
(let [(@Var @List . @Body) "Args"]
(macro
(mapcar
'((@Var) . @Body)
@List ]
(====)
(let "Args" * (mapeach N (1 2 3) ("Args" N N)))

它也可以在不调用 ==== 的情况下按预期运行,但前提是对 mapeach 的调用不在同一文件中。

解决我问题的两个部分:

  1. 您可以通过在不同文件中使用 transient 符号或在调用 ==== 后防止名称隐藏。
  2. 这些调用可能有效,因为调试器清除了包含 transient 符号的索引。

关于scope - 如何编写不使用其参数隐藏变量的 PicoLisp 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55697674/

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