我正在通过这本书学习球拍Realm of Racket.我注意到定义变量和定义函数是通过相同的关键字完成的define.这让我想到了一个不带参数的函数和简单地返回值之间的根本区别5,以及一个返回值的变量5.即:
(define fiveVar 5)
(define (fiveFun)
5)
Run Code Online (Sandbox Code Playgroud)
(抱歉,如果驼峰不是正确的命名惯例 - 只是拿起书而不知道任何Lisp).
乍一看,在我看来,我只是5在这两种情况下都给出了一个名称.事实上,我甚至可以重新附加名称fiveFun:(set fiveFun 6),就像我可以使用变量一样.
因此,在我看来,定义变量和定义函数之间没有区别.在这两种情况下,我都给数据类型命名.在函数数据类型的情况下,可以应用它,而数字则不能.
差不多,是的.实际上,(define (f x ...) ...)符号只是Scheme和其他Lisp-1中的一个方便的缩写,与Common Lisp和其他将函数和值分离为单独的命名空间的Lisp-2形成对比.
在Racket和Scheme中,当你写这个:
(define (f x) (+ x 1))
Run Code Online (Sandbox Code Playgroud)
它实际上只是写这个的简写符号:
(define f (lambda (x) (+ x 1)))
Run Code Online (Sandbox Code Playgroud)
的lambda形式是产生一种特殊形式的过程值,但所述结合时创建,在这种情况下f,是从普通值的结合没有什么不同.由于过程只是与其他过程一样的值,因此使用所谓的"高阶"函数 - 接受函数作为参数的函数 - 易于编写和使用.例如,filter将函数作为其第一个参数:
> (filter even? '(1 2 3 4))
'(2 4)
Run Code Online (Sandbox Code Playgroud)
现在,考虑到这一点,你在问题中写的函数定义实际上就是这样,没有简写:
(define fiveFun (lambda () 5))
Run Code Online (Sandbox Code Playgroud)
那么,考虑这两件事之间的区别:
(define fiveVar 5)
(define fiveFun (lambda () 5))
Run Code Online (Sandbox Code Playgroud)
好吧,其中一个是数字,5另一个是没有参数的函数,当应用时,产生 5.有些语言,大多数是纯函数的,甚至没有一个不带参数的函数的概念,所以没有有意义的方式来表达fiveFun这些语言.但是,在Racket中,有几个原因可能需要这样的功能:
您可以使用无参数函数将评估"延迟"到另一个时间,甚至多次运行,这在运行该函数时会产生副作用.例如:
> (define x (begin (displayln "Hello!") 5))
Hello!
> x
5
> x
5
> (define f (lambda () (displayln "Hello!") 5))
> f
#<procedure:f>
> (f)
Hello!
5
> (f)
Hello!
5
Run Code Online (Sandbox Code Playgroud)此外,值可能需要很长时间才能生成,您可能希望将其评估推迟到实际需要时.当实际使用该函数时,您可以使用零参数函数来"懒惰地"运行计算.
作为一小段术语,零参数函数通常被称为"thunk",您可能会在Racket文档中的某些位置看到它.甚至还有一个调用的形式thunk,racket/function它是零参数lambda的小简写.
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |