有谁知道如何找出 lambda 表达式中的自由变量?自由变量是不属于 lambda 参数的变量。
我当前的方法(这对我毫无帮助)是简单地使用 car 和 cdr 来遍历表达式。我的主要问题是确定一个值是否是一个变量或者它是否是方案原语之一。有没有办法测试某些内容是否评估为方案的内置函数之一?例如:
(is-scheme-primitive? 'and)
;Value: #t
我正在使用麻省理工学院的方案。
对于任意的 MIT 计划程序,没有任何方法可以做到这一点。一个问题是您描述的功能无法工作。例如,这不使用“方案原语”and
:
(let ((and 7)) (+ and 1))
但它确实使用了这个符号'and
.
另一个问题是很多事情,比如and
,是用宏实现的特殊形式。您需要知道程序中的所有宏扩展为什么,才能弄清楚程序中使用了哪些变量。
要实现此目的,您需要限制接受作为输入的程序集。最好的选择是将其限制为“完全扩展”的程序。换句话说,您要确保您的输入中没有留下任何宏的使用。free-variables
功能。
为此,您可以使用expand
许多Scheme系统提供的功能。不幸的是,从在线文档 http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/index.html#Top,好像MITScheme没有提供这个功能。如果您能够使用其他系统,Racket http://racket-lang.org/提供了expand http://docs.racket-lang.org/reference/Expanding_Top-Level_Forms.html#%28def._%28%28quote._~23~25kernel%29._expand%29%29功能以及local-expand http://docs.racket-lang.org/reference/stxtrans.html?q=local-expand#%28def._%28%28quote._~23~25kernel%29._local-expand%29%29它在宏内可以正常工作。
Racket实际上还提供了一个实现free-variables功能 http://docs.racket-lang.org/syntax/syntax-helpers.html#%28mod-path._syntax/free-vars%29正如我所描述的,这需要完全扩展的程序作为输入(例如expand
or local-expand
)。您可以看到源代码 https://github.com/plt/racket/blob/master/collects/syntax/free-vars.rkt#L46以及。
有关完全扩展源代码所涉及问题的详细讨论,请参见这篇即将发表的论文 http://www.cs.utah.edu/plt/expmodel-6/作者:弗拉特、卡尔佩珀、达赖斯和芬德勒。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)