我正在学习球拍,并且对何时使用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
是否正确?
我在某处读到define
用于声明全局变量,而let
用于声明局部变量。我看过球拍的文档,但没有谈论任何区别。
答案 0 :(得分:2)
一个区别:内部定义在相互递归的范围内,但让绑定不在。
这意味着比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
如果在x
之外定义了y
或let
,则expr-1和expr-2将引用 outer 定义,而不是由let介绍的。具体来说:
(define x 'outer)
(let ([x 'inner] [y x]) ; <- this x refers to outer,
y) ; so y is 'outer
;=> 'outer
但是,内部定义具有相互递归的范围,这意味着在
(block
(define x expr-1)
(define y expr-2)
body)
expr-1
和expr-2
可以引用x
或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)
define
....A....
(define (f)
(define t1 ..B..)
(define x ..C..)
(define t2 ..D..)
....E....)
....F....
x
的内容在f
正文中的任何位置都可见,但在其外部看不到。这意味着它在B
,C
,D
和E
中可见,但在A或F中不可见。
let
....A....
(define (f)
(let ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....
此处x
在let
正文中的任何位置都是可见的,但在该位置之外不可见。这意味着它在E
中可见,但在A,B,C,D或F中不可见。
let*
....A....
(define (f)
(let* ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....
此处x
在let*
主体中的任何地方以及在之后的let*
绑定中都是可见的,但不在该范围之外。这意味着它在D
和E
中可见,但在A,B,C或F中不可见。
letrec
....A....
(define (f)
(letrec ([t1 ..B..]
[x ..C..]
[t2 ..D..])
....E....))
....F....
x
在letrec
的主体和letrec
的绑定中的任何位置都是可见的,但在此之外不可见。这意味着它在B
,C
,D
和E
中可见,但在A或F中不可见。
letrec
中的变量范围和局部define
中的变量范围非常相似,因为letrec
和define
都使用相互递归的范围。
答案 1 :(得分:0)
我终于了解了我读到的define
的变量是“全局变量”。
R。肯特·迪布维格(R. Kent Dybvig)在《方案编程语言第四版》一书的2.6. Top Level Definitions中说:
由let和lambda表达式绑定的变量不可见 这些表达式的主体之外。