В чем разница между let и let*, я этого не понимаю (Racket)

(define x 2)

(let ((x 1) (y (+ x 1))) (+ x y))

вы получаете 4;

(let* ((x 1) (y (+ x 1))) (+ x y))

вы получаете 3.

Я не понимаю, как работает let. Может кто-нибудь объяснить, я новичок в информатике, спасибо


person HelpMeplox    schedule 11.12.2014    source источник


Ответы (1)


(let ((x 0) (z x))
  ...)

Эквивалентно:

((lambda (x z) ...) 0 x)

Возможно, в вызове анонимной процедуры вы видите, что при вычислении аргументов переменная внутри тела еще не существует, но внутри тела x есть 0, а предыдущая x скрыта во всем теле, но доступна как z.

(let* ((x 0) (z x))
  ...)

Что эквивалентно:

(let ((x 0))
  (let ((z x))
    ...))

Глядя на это, вы сразу же видите, что x устанавливается на 0 и затеняет любые другие x в момент привязки z.

Представьте, что вы хотите вычислить гипотенус треугольника:

(let ((hypotenuse (sqrt (+ (square a) (square b)))))
  ...)

Вы хотите немного разделить его, поэтому измените его на let* следующим образом:

(let* ((sqa (square a))
       (sqb (square b))
       (hypotenuse (sqrt sqa sqb)))
  ...)

Если бы вы использовали let, то sqa и sqb были бы недоступны! Эмпирическое правило состоит в том, чтобы использовать let и изменить его на let*, когда вам нужно сослаться на что-то связанное в том же let. Будьте осторожны, чтобы не затенить переменные, которые вы используете позже.

person Sylwester    schedule 11.12.2014