Когда использовать определить и когда использовать пусть в ракетке - PullRequest
0 голосов
/ 05 декабря 2018

Я изучаю ракетку, и у меня есть вопрос о том, когда использовать 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 - для объявления локальных переменных.Я смотрю в документации по ракетке, но это не говорит о разнице.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Я наконец понял, что прочитал, что переменные define являются «глобальными переменными».

В книге «Язык программирования схем, четвертое издание», Р. Кент Дибвиг, раздел 2.6.Определения верхнего уровня говорит:

Переменные, связанные выражениями let и lambda, не видны вне тел этих выражений.

0 голосов
/ 06 декабря 2018

Одно отличие: внутренние определения находятся во взаимно рекурсивной области, но пусть привязки - нет.

Это означает, что в 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 будут ссылаться на external определения,а не те, которые введены в 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 работают с взаимно рекурсивными областями.

...