代码之家  ›  专栏  ›  技术社区  ›  VansFannel

何时使用define和何时使用let-in-racket

  •  0
  • VansFannel  · 技术社区  · 6 年前

    我在学球拍,我有一个关于何时使用的问题 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))))) 
    

    不知道上面的功能是什么。使用正确吗 定义 在功能体内部?

    我在某个地方读过 定义 用于声明全局变量和 用于声明局部变量。我查阅了Racket的文档,但没有提到任何区别。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Alex Knauth    6 年前

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

    这意味着比在 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 是在 ,expr-1和expr-2将引用 外面的 定义,而不是由let引入的定义。Concretely:

    (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)
    

    A的范围 define

    ....A....
    (define (f)
      (define t1 ..B..)
      (define x ..C..)
      (define t2 ..D..)
      ....E....)
    ....F....
    

    这个 X 在身体的任何地方都可见 f 但不在外面。这意味着它在 B , C , D E ,但不在a或f中。

    A的范围

    ....A....
    (define (f)
      (let ([t1 ..B..]
            [x ..C..]
            [t2 ..D..])
        ....E....))
    ....F....
    

    这里 X 在身体的任何地方都可见 但不在外面。这意味着它在 e ,但不在A、B、C、D或F中。

    A的范围 let*

    ....A....
    (define (f)
      (let* ([t1 ..B..]
             [x ..C..]
             [t2 ..D..])
        ....E....))
    ....F....
    

    这里 X 在身体的任何地方都可见 让* 而在 让* 即将到来的绑定 之后 但不是在外面。这意味着它在 D e ,但不在A、B、C或F中。

    A的范围 letrec

    ....A....
    (define (f)
      (letrec ([t1 ..B..]
               [x ..C..]
               [t2 ..D..])
        ....E....))
    ....F....
    

    这个 X 在身体的任何地方都可见 莱特雷克 以及 莱特雷克 但不在外面。这意味着它在 , C , D e ,但不在a或f中。

    变量的范围 莱特雷克 以及当地的范围 定义 变量非常相似,因为两者都 莱特雷克 定义 使用相互递归的作用域。

        2
  •  0
  •   VansFannel    6 年前

    我终于明白我读到了什么 define 的变量是“全局变量”。

    《方案编程语言》第四版,R.Kent Dybvig,第 2.6. Top Level Definitions 说:

    由let和lambda表达式绑定的变量不可见 在这些表达式的主体之外。