何时使用定义,何时使用让球拍

Van*_*nel 4 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-sin-clase))

        (eq? (last x) (last c)))
      (cdr list1))
     (length (cdr list1))))) 
Run Code Online (Sandbox Code Playgroud)

不知道上面的函数是做什么的。define在函数体内使用是否正确?

我在某处读过define用于声明全局变量和let用于声明局部变量的地方。我查看了球拍的文档,但没有提到任何区别。

Ale*_*uth 9

一个区别:内部定义在一个相互递归的范围内,但让绑定不是。

这意味着比在 a 中let

(let ([x expr-1] [y expr-2])
  body)
Run Code Online (Sandbox Code Playgroud)

expr-1expr-2不能引用xy。更具体地说,

(let ([x (stream-cons 1 y)] [y (stream-cons 2 x)])
  x)
;error=> y: unbound identifier in: y
Run Code Online (Sandbox Code Playgroud)

如果xy在 之外定义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
Run Code Online (Sandbox Code Playgroud)

但是,内部定义具有相互递归的作用域,这意味着在

(block
  (define x expr-1)
  (define y expr-2)
  body)
Run Code Online (Sandbox Code Playgroud)

expr-1expr-2 可以参考xy。具体来说,

(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)
Run Code Online (Sandbox Code Playgroud)

范围 define

....A....
(define (f)
  (define t1 ..B..)
  (define x ..C..)
  (define t2 ..D..)
  ....E....)
....F....
Run Code Online (Sandbox Code Playgroud)

x中体随处可见f,但并不之外的。这意味着它是可见的BCD,和E,而不是在一个或F.

范围 let

....A....
(define (f)
  (let ([t1 ..B..]
        [x ..C..]
        [t2 ..D..])
    ....E....))
....F....
Run Code Online (Sandbox Code Playgroud)

这里 thex在 的主体中随处可见let,但在 之外不可见。这意味着它在 中可见E,但在 A、B、C、D 或 F 中不可见。

范围 let*

....A....
(define (f)
  (let* ([t1 ..B..]
         [x ..C..]
         [t2 ..D..])
    ....E....))
....F....
Run Code Online (Sandbox Code Playgroud)

在这里x, the 的主体let*和它之后的let*绑定中的任何地方都可见,但不在此之外。这意味着它在and 中可见,但在 A、B、C 或 F 中不可见。DE

范围 letrec

....A....
(define (f)
  (letrec ([t1 ..B..]
           [x ..C..]
           [t2 ..D..])
    ....E....))
....F....
Run Code Online (Sandbox Code Playgroud)

Thex在 的主体letrec和 的绑定中随处可见letrec,但在 之外不可见。这意味着它是可见的BCD,和E,而不是在一个或F.

在变量的作用域letrec和局部范围define的变量,因为这两个非常相似letrecdefine工作,相互递归的范围。