方案函数可以返回全局符号及其值吗?

时间:2018-11-19 16:46:42

标签: scheme

是否可以在下面编写方案函数symtab

(define x 1)
(define y 2)
(symtab x) ; => (x . 1)
(symtab y) ; => (y . 2)

如果不可能,是否可以定义一个带有引号的类似函数?

(symtab 'x) ; => (x . 1)
(symtab 'y) ; => (y . 2)

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中工作-动态调整范围。