Racket 变量定义和函数定义的根本区别
我正在通过《球拍王国》一书学习球拍。我注意到定义变量和定义函数是通过相同的关键字来完成的-Racket 变量定义和函数定义的根本区别,racket,Racket,我正在通过《球拍王国》一书学习球拍。我注意到定义变量和定义函数是通过相同的关键字来完成的-define。这让我思考了不带参数且仅返回值5的函数与返回值5的变量之间的根本区别。i、 e: (define fiveVar 5) (define (fiveFun) 5) (如果camel case不是正确的命名约定,则表示歉意-只是拿起书,不知道任何Lisp) 乍一看,在这两种情况下,我似乎只是给值5起了个名字。事实上,我甚至可以重新附加名称fiveFun:(set fiveFun 6),就像
define
。这让我思考了不带参数且仅返回值5
的函数与返回值5
的变量之间的根本区别。i、 e:
(define fiveVar 5)
(define (fiveFun)
5)
(如果camel case不是正确的命名约定,则表示歉意-只是拿起书,不知道任何Lisp)
乍一看,在这两种情况下,我似乎只是给值5
起了个名字。事实上,我甚至可以重新附加名称fiveFun
:(set fiveFun 6)
,就像使用变量一样
所以,在我看来,定义变量和定义函数之间没有区别。在这两种情况下,我都为数据类型命名。对于函数数据类型,可以应用它,而数字不能 差不多,是的。事实上,
(define(f x…)
符号只是Scheme和其他Lisp-1中的一个方便的缩写,这与将函数和值分离到不同名称空间的普通Lisp和其他Lisp-2不同
在Racket and Scheme中,当您编写以下内容时:
(define (f x) (+ x 1))
实际上,这只是写这篇文章的简写符号:
(define f (lambda (x) (+ x 1)))
lambda
表单是一种生成过程值的特殊表单,但是创建的绑定(在本例中为f
)与普通值的绑定没有什么不同。由于过程和其他过程一样都是值,因此使用所谓的“高阶”函数(接受函数作为参数)很容易编写和使用。例如,filter
将函数作为其第一个参数:
> (filter even? '(1 2 3 4))
'(2 4)
现在,考虑到这一点,您在问题中编写的函数定义实际上是这样的,没有简写:
(define fiveFun (lambda () 5))
所以,考虑这两件事的区别:
(define fiveVar 5)
(define fiveFun (lambda () 5))
其中一个是数字,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
>(定义x(开始(显示“Hello!”)5))
你好
>x
5.
>x
5.
>(定义f(lambda()(displayln“Hello!”)5))
>f
#
>(f)
你好
5.
>(f)
你好
5.
作为一个小术语,零参数函数通常被称为“thunk”,您可能会在Racket文档的某些地方看到它。甚至还有一个叫做
thunk
的表单,来自racket/function
,它是零参数lambda的一个小缩写。Alexis,谢谢你的解释。这张长手稿清楚地表达了我的想法。在这个意义上与哈斯克尔非常相似。@StevenL。是的,非常相似!当然,区别在于Haskell没有无参数函数的概念,因为Haskell既懒惰又纯粹,所以它们没有用处。