2016-02-16 84 views
7

我的朋友向我展示了这一点,我很好奇它为什么像这样工作。我起初以为,这会是一个语法错误,但它不...我这里还有我的一些实验:什么是(lambda lambda lambda)?

> (lambda lambda lambda) 
#<procedure> 
> ((lambda lambda lambda)) 
'() 
> ((lambda lambda lambda) 1 2 3 4 5 6 7) 
'(1 2 3 4 5 6 7) 
> (lambda lambda foo) 
#<procedure> 
> ((lambda lambda foo)) 
foo: undefined; 
cannot reference an identifier before its definition 
> (lambda lambda 1 2 3 4 5) 
#<procedure> 
> ((lambda lambda 1 2 3 4 5)) 
5 
> (lambda foo lambda) 
. lambda: bad syntax in: lambda 
> (lambda 1 2 3) 
. lambda: bad argument sequence in: 1 
> ((lambda) 1 2 3) 
. lambda: bad syntax in: (lambda) 

如此看来:

  1. lambdalambda可能是arg-ids?
  2. lambdalambda可能是一个列表构造函数?

回答

7

哦,我知道了。 lambda可能会被遮蔽!

> ((lambda (lambda) (+ 1 lambda)) 7) 
8 

此外,在https://docs.racket-lang.org/guide/lambda.html给出的语法并不完全正确,因为在arg-ids位置,标识可以有!这将绑定与标识符的参数列表:

> ((lambda foo foo) 1 2 3 4) 
'(1 2 3 4) 

这些解释它!

+1

此链接有更多详细信息:https://docs.racket-lang.org/reference/lambda.html –

+0

Thx :)事实上,我发布的链接在4.4.1中提到了“rest-id”但我没看到它! –

+1

是的。但是,还有一个奇怪的例子,这不解释。 '(lambda lambda foo)'='#'。这是因为这是在REPL中,你可以在其中执行'(define(f x)foo)',然后在后面定义foo,以便实现相互递归。但对于这些事情,你真的应该把它们放在一个文件中,因为这将显示它们的真实行为。在文件本身中,“(lambda lambda foo)”将是错误的,因为它应该是。 –