英文:
Scheme lambda or define?
问题
What's the difference between the two lines?
这两行之间有什么区别?
I want to make an adder function.
我想创建一个加法函数。
It turned out the first line works but the second not.
结果发现第一行有效,但第二行不行。
I'm new to scheme, thanks.
我对Scheme不太熟悉,谢谢。
英文:
What's the difference between the two lines?
I want to make an adder function.
It turned out the first line works but the second not.
I'm new to scheme, thanks.
(define (make-adder num) (lambda (x) (+ num x)))
(define (make-adder num) (define (foo x) (+ num x)))
答案1
得分: 0
lambda
定义一个函数并返回它。define
定义一个值(可能是一个函数),但不返回它。所以你关于这两种形式定义的函数等价性的观点是正确的,但在第二种形式中需要返回 foo
:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
英文:
lambda
defines a function and returns it. define
defines a value (potentially a function), but does not return it. So you're right about the equivalence of the functions defined by the two forms, but you need to return foo
in the second:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
答案2
得分: 0
The form
(define (name args ...)
defines ... body ...)
Is just syntactic sugar for:
(define name
(lambda (args ...)
defines ... body ...))
Now inside a lambda form you may zero or more local `define` then followed with at least one body expression. In your first example you have zero defines and one body expression, namely the lambda expression that turns into a closure once applied.
Your second version has one define of the local variable `foo` but since there is no body expression this is not valid Scheme code. In order to be equivalent to the first code you need to have the variable you just defined as the body, returning the newly created closure, like this:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
Now the two versions are identical. You can also write it fully out so that the Scheme implementation doesn't need to expand the sugar like this:
(define make-adder
(lambda (num)
(define foo (lambda (x) (+ num x)))
foo))
Of course it doesn't hurt to use sytactic sugar, but books like The little Schemer has avoided using the short form just because it might give the impression the procedures are more than just variables that evaluate to procedure objects. eg. in (a b c)
a
is just a variable, just like b
and c
. The only difference is that there is a requirement that a
evaluates to a procedure, just like in (+ c d)
c
and d
needs to be numbers to avoid a runtime error.
<details>
<summary>英文:</summary>
The form
(define (name args ...)
defines ... body ...)
Is just syntactic sugar for:
(define name
(lambda (args ...)
defines ... body ...))
Now inside a lambda form you may zero or more local `define` then followed with at least one body expression. In your first example you have zero defines and one body expression, namely the lambda expression that turns into a closure once applied.
Your second version has one define of the local variable `foo` but since there is no body expression this is not valid Scheme code. In order to be equivalent to the first code you need to have the variable you just defined as the body, returning the newly created closure, like this:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
Now the two versions are identical. You can also write it fully out so that the Scheme implementation doesn't need to expand the sugar like this:
(define make-adder
(lambda (num)
(define foo (lambda (x) (+ num x)))
foo))
Of course it doesn't hurt to use sytactic sugar, but books like The little Schemer has avoided using the short form just because it might give the impression the procedures are more than just variables that evaluate to procedure objects. eg. in `(a b c)` `a` is just a variable, just like `b` and `c`. The only difference is that there is a requirement that `a` evaluates to a procedure, just like in `(+ c d)` `c` and `d` needs to be numbers to avoid a runtime error.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论