Scheme 何时使用define和何时使用let-in球拍
我正在学习球拍,我有一个问题,关于什么时候使用Scheme 何时使用define和何时使用let-in球拍,scheme,racket,Scheme,Racket,我正在学习球拍,我有一个问题,关于什么时候使用define,什么时候使用let 我有这个功能: (define my-function (lambda (param1 param2 list1) (/ (count (lambda (x) (define a (param1 (remove x list1))) (define b (drop-right x 1)) (define c (param2 a x
define
,什么时候使用let
我有这个功能:
(define my-function
(lambda (param1 param2 list1)
(/
(count
(lambda (x)
(define a (param1 (remove x list1)))
(define b (drop-right x 1))
(define c (param2 a x-sin-clase))
(eq? (last x) (last c)))
(cdr list1))
(length (cdr list1)))))
不知道上述函数的作用。在函数体内部使用定义是否正确
我在某个地方读到,define
用于声明全局变量,let
用于声明局部变量。我查看了racket的文档,但没有提到任何区别。一个区别:内部定义在一个相互递归的范围内,但let绑定不是
这意味着比在<代码>中让<代码>:
(let ([x expr-1] [y expr-2])
body)
expr-1
和expr-2
不能引用x
或y
。更具体地说,
(let ([x (stream-cons 1 y)] [y (stream-cons 2 x)])
x)
;error=> y: unbound identifier in: y
(require racket/block)
(block
(define x (stream-cons 1 y))
(define y (stream-cons 2 x))
(stream->list (stream-take x 5)))
;=> (list 1 2 1 2 1)
如果x
或y
是在let
之外定义的,则expr-1和expr-2将引用外部定义,而不是let引入的定义。具体地说:
(define x 'outer)
(let ([x 'inner] [y x]) ; <- this x refers to outer,
y) ; so y is 'outer
;=> 'outer
expr-1
和expr-2
可参考x
或y
。具体地说,
(let ([x (stream-cons 1 y)] [y (stream-cons 2 x)])
x)
;error=> y: unbound identifier in: y
(require racket/block)
(block
(define x (stream-cons 1 y))
(define y (stream-cons 2 x))
(stream->list (stream-take x 5)))
;=> (list 1 2 1 2 1)
定义的范围
x
在f
的主体中随处可见,但不在其外部。这意味着它在B
、C
、D
和E
中可见,但在A或F中不可见
alet
在这里,x
在let
的主体中随处可见,但不在其外部。这意味着它在E
中可见,但在A、B、C、D或F中不可见
let*
在这里,x
在let*
的主体中以及之后的let*
绑定中随处可见,但不在其外部。这意味着它在D
和E
中可见,但在A、B、C或F中不可见
letrec的范围
x
在letrec
的主体和letrec
的绑定中随处可见,但不在其外部。这意味着它在B
、C
、D
和E
中可见,但在A或F中不可见
letrec
中变量的范围和本地define
变量的范围非常相似,因为letrec
和define
都使用相互递归的范围。我终于明白了我读到的define
的变量是“全局变量”
在《Scheme编程语言第四版》一书中,R.Kent Dybvig一节说:
由let和lambda表达式绑定的变量不可见
在这些表达的主体之外
一个区别是:内部define
s在一个相互递归的范围内(包括mut rec函数),let
绑定不是,但也有其他样式reasons@AlexKnauth对不起,关于你的评论我什么都不懂。谢谢。在(let([x expr-1][y expr-2])body)
中,expr-1和expr-2不能引用x
或y
。但是,在(block(define x expr-1)(define y expr-2)body)
中,expr-1和expr-2都可以引用x
和y
。从技术上讲define
仅在顶层“允许”。在本地定义上下文中使用时,它们只是语法糖,将被扩展为适当的let
形式。那么,在体函数中使用let是否更好?谢谢。当我需要“更改”函数输入,使其成为更好的“更一致”形式时,我发现let
最有用。例如,如果一个函数使用符号
或[Listof Symbol]
,但我想将函数体编写为一致的[Listof Symbol]
,我可以使用let
来隐藏参数并使其成为一个列表<代码>(定义(fx)(let([x(if(list?x)x(list x))))…body…)
我有点被这些不同的作用域所淹没。是否有关于其使用量百分比的统计数据?到目前为止,我们主要使用define和一些let,这似乎已经足够了。我们需要这么多选项吗?我不知道任何具体的统计数据,但在我读过或研究过的代码中,内部定义比let更常见。我通常只在特殊情况下使用let,比如定义不允许或我故意使用“规范化”版本进行跟踪,对于其他所有情况,我使用定义使用“规范化”版本?如果定义在局部范围内,则定义的变量不是全局变量。(define(f)(define x 5)…body…)
中的x
仅在f
的主体内部可见,而不是外部可见。@AlexKnauth可能我还没有理解我的教授。他说:“Define应该只用于定义全局变量。要从函数中定义局部变量,必须使用let或let*。否则,全局变量可能会干扰函数的局部功能。”你的教授说的到底是哪种语言?这听起来像是一个奇怪的语言功能,我想尝试一下。我只是尝试在Racket中使用一个内部定义,而x
在外部看不到,它不是“全局的”。那么你的教授是什么意思呢?@AlexKnauth他说这是关于结束的,
....A....
(define (f)
(let ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....
....A....
(define (f)
(let* ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....
....A....
(define (f)
(letrec ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....