是否可以在下面编写方案函数symtab
?
(define x 1)
(define y 2)
(symtab x) ; => (x . 1)
(symtab y) ; => (y . 2)
如果不可能,是否可以定义一个带有引号的类似函数?
(symtab 'x) ; => (x . 1)
(symtab 'y) ; => (y . 2)
答案 0 :(得分:1)
是的,带有宏。
> (define-syntax symtab
(syntax-rules ()
((_ x)
(cons 'x x))))
> (define x 1)
> (define y 2)
> (symtab x)
'(x . 1)
> (symtab y)
'(y . 2)
>
宏实际上不是函数(因此从技术上来说,对您的问题的基本回答是“否”)。仅使用功能,您的任务在大多数语言中甚至是不可能的。但是Scheme为我们提供了宏,这些宏允许我们从自身内部操作程序。有关宏以及它们与函数的区别的更多信息,我建议您看以下教程:http://www.greghendershott.com/fear-of-macros/all.html#%28part..Transform%29
它基于球拍,但实际上可适用于各种方言。享受吧!
答案 1 :(得分:1)
带引号的参数是可能的:
(define (symtab s)
(cons s (eval s (interaction-environment))))
现在让我们对其进行测试:
(define xy 12)
(symtab 'xy)
=> (xy . 12)
编辑:但是,它也不是很可靠(也使用宏)-请仔细阅读相关的Why isn't there an unquote
Lisp primitive?
这是因为像大多数语言一样,Scheme在词法范围内。这意味着在定义函数时解析变量名,而不是在运行时解析变量名时的动态作用域。所以
(define xy 12)
(define (getXY) xy)
(getXY)
=> 12
该代码有效,因为当我们定义getXY
时,名称xy
是已知的,并且可以解析为顶级xy
。但是
(define (getXY) xy)
(let ((xy 21))
(getXY))
=> Unbound variable: xy
这是行不通的,因为在定义getXY
时,xy
是未知的(并且在定义getXY
时,我的Guile Scheme也给了我警告“警告:可能未绑定变量“ xy”” )。
它将在Emacs Lisp中工作-动态调整范围。