gpt4 book ai didi

racket - 变量定义和函数定义之间的根本区别

转载 作者:行者123 更新时间:2023-12-02 09:54:01 25 4
gpt4 key购买 nike

我正在通过Realm of Racket这本书学习Racket。我注意到定义变量和定义函数是通过相同的关键字 - define 完成的。这让我开始思考不带参数且仅返回值 5 的函数与返回值 5 的变量之间的根本区别是什么。即:

(define fiveVar 5)

(define (fiveFun)
5)

(如果驼峰命名法不是正确的命名约定,我深表歉意 - 只是拿起这本书,不了解任何 Lisp)。

乍一看,在我看来,我只是在这两种情况下为值 5 命名。事实上,我什至可以重新附加名称 FiveFun :(set FiveFun 6),就像使用变量一样。

再说一次,在我看来,定义变量和定义函数之间没有区别。在这两种情况下,我都为数据类型命名。对于函数数据类型,可以应用它,而数字则不能。

最佳答案

差不多,是的。事实上,(define (f x ...) ...) 表示法只是Scheme 和其他Lisp-1 中的一个方便的缩写,这与Common Lisp 和其他Lisp-2 形成对比。将函数和值分离到单独的命名空间中。

在Racket和Scheme中,当你这样写时:

(define (f x) (+ x 1))

这实际上只是编写此内容的简写符号:

(define f (lambda (x) (+ x 1)))

lambda 形式是一种特殊形式,可生成过程值,但创建的绑定(bind)(在本例中为 f)是与普通值的绑定(bind)没有什么不同。由于过程只是像其他任何值一样的值,这使得使用所谓的“高阶”函数(接受函数作为参数的函数)易于编写和使用。例如,filter 将函数作为其第一个参数:

> (filter even? '(1 2 3 4))
'(2 4)

现在,考虑到这一点,您在问题中编写的函数定义实际上是这样的,没有简写:

(define fiveFun (lambda () 5))

那么,考虑一下这两件事之间的区别:

(define fiveVar 5)
(define fiveFun (lambda () 5))

嗯,其中一个是数字,5,另一个是没有参数的函数,应用时产生 5。有些语言,大多是纯粹的函数式的,甚至没有不带参数的函数的概念,因此在这些语言中没有有意义的方式来表达 FiveFun 。然而,在 Racket 中,您可能需要这样的功能有几个原因:

  1. 您可以使用无参数函数将计算“延迟”到另一时间,甚至多次运行它,如果运行该函数有副作用,这非常有用。例如:

    > (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
  2. 此外,一个值可能需要很长的时间才能生成,您可能希望将其计算推迟到实际需要时为止。当实际使用该函数时,您可以使用零参数函数“延迟”运行计算。

作为一个小术语,零参数函数通常称为“thunk”,您可能会在 Racket 文档的某些地方看到它。甚至还有一种来自 racket/function 的名为 thunk 的形式,它是零参数 lambda 的一个小简写。

关于racket - 变量定义和函数定义之间的根本区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41417430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com