What is (lambda lambda lambda)?
Asked Answered
S

1

8

My friend shows this to me, and I am really curious why it works like this. I at first thought that it's gonna be a syntax error, but it doesn't... Here're some of my experiments:

> (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)

So it seems:

  1. In lambda, lambda could be arg-ids?
  2. In lambda, lambda could be a list constructor?
Spinoza answered 16/2, 2016 at 7:29 Comment(0)
S
8

Ohhh I got it. lambda could be shadowed!

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

Also, the syntax given at https://docs.racket-lang.org/guide/lambda.html is not entirely correct because at arg-ids position, an identifier could be there! This will bind the list of arguments with the identifier:

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

These explain it!

Spinoza answered 16/2, 2016 at 7:37 Comment(2)
Thx :) In fact, the link I posted mentioned rest-id as well in 4.4.1, but I didn't see it!Spinoza
Yes. However, there is one more strange case that this doesn't explain. (lambda lambda foo) = #<procedure>. And that's because this is in a REPL, where you can do (define (f x) foo) and then define foo later, so that for instance mutual recursion works. But for these things, you really should put them in a file, because that's what will show their true behavior. In a file by itself, (lambda lambda foo) will be an error, as it should.Rubi

© 2022 - 2024 — McMap. All rights reserved.