scheme函数能否返回全局符号及其值?

scheme函数能否返回全局符号及其值?,scheme,Scheme,是否可以在下面编写scheme函数symtab (define x 1) (define y 2) (symtab x) ; => (x . 1) (symtab y) ; => (y . 2) 如果不可能,是否可以定义具有引用参数的类似函数 (symtab 'x) ; => (x . 1) (symtab 'y) ; => (y . 2) 是的,有宏 > (define-syntax symtab (syntax-rules () ((_ x)

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

(define x 1)
(define y 2)
(symtab x) ; => (x . 1)
(symtab y) ; => (y . 2)
如果不可能,是否可以定义具有引用参数的类似函数

(symtab 'x) ; => (x . 1)
(symtab 'y) ; => (y . 2)
是的,有宏

> (define-syntax symtab
  (syntax-rules ()
    ((_ x)
     (cons 'x x))))

> (define x 1)
> (define y 2)
> (symtab x) 
'(x . 1)
> (symtab y)
'(y . 2)
> 
宏实际上不是一个函数(因此从技术上来说,您的问题的基本答案是否定的)。在大多数语言中,仅仅使用函数甚至不可能完成任务。但Scheme为我们提供了宏,允许我们从程序内部操纵程序。有关宏以及宏与函数的区别的详细信息,我建议查看以下教程:


它基于Racket,但基本上适用于各种Scheme方言。享受吧

引用参数也可以:

(define (symtab s)
  (cons s (eval s (interaction-environment))))
现在让我们测试一下:

(define xy 12)

(symtab 'xy)
=> (xy . 12)
编辑:但是它不是很可靠(也使用宏)-请仔细阅读相关内容

这是因为Scheme和大多数语言一样是词汇范围的。这意味着在定义函数时解析变量名,而不是在运行时解析变量名时解析动态范围。所以

(define xy 12)

(define (getXY) xy)

(getXY)
=> 12
这段代码有效,因为当我们定义
getXY
时,名称
xy
是已知的,可以解析为顶级
xy
。然而

(define (getXY) xy)

(let ((xy 21))
  (getXY))
=> Unbound variable: xy
这不起作用,因为当定义
getXY
时,
xy
是未知的(并且我的Guile方案在定义
getXY
时也给了我警告:“警告:可能是未绑定的变量'xy'”


它将在Emacs Lisp中工作-动态范围。

为了澄清,不可能创建一个使用无引号参数的Scheme函数,但可以创建一个Scheme宏(您的示例)。还可以创建一个Scheme函数,该函数使用带引号的参数(rsm的示例)。对吗?对,对。这不能使用函数来完成,因为参数是经过计算的(所以不能得到参数的原始名称,仅值)。这可以用宏来完成,但在这两种情况下都不太可靠-请阅读密切相关的@rsm。你能给出两种解决方案中每种解决方案不可靠的例子吗?@cfgauss嗨,请检查我更新的答案。希望现在清楚了。