Использование Let in Scheme - PullRequest
       36

Использование Let in Scheme

10 голосов
/ 03 июня 2009

Я хочу написать программу для поиска корней квадратного уравнения на схеме. Я использовал LET для определенных привязок.

(define roots-with-let
  (λ (a b c)
    (let ((4ac (* 4 a c))
          (2a (* 2 a))
          (discriminant (sqrt ( - (* b b) (4ac)))))
      (cons ( / ( + (- b) discriminant) 2a)
            ( / ( - (- b) discriminant) 2a)))))

Я определил дискриминант с 4ac, так как я не хотел (* 4 a c). Несмотря на то, что я определил (4ac (* 4 a c)), он дает мне эту ошибку:

раскрыть: несвязанный идентификатор в модуле в: 4ac.

У меня вопрос, как оценивать пусть (в каком порядке)? И если я хочу 4ac в моем let, я должен написать еще один внутренний let? Есть ли лучший способ сделать это?

Ответы [ 4 ]

31 голосов
/ 03 июня 2009

Используйте let* вместо let.

Разница между let и let* заключается в следующем:

let* связывает переменные слева направо. Более ранние привязки могут быть использованы в новом связывании дальше вправо (или вниз).

let с другой стороны, можно рассматривать как синтаксический сахар (или макрос) для простой лямбда-абстракции:

(let ((a exp1)
      (b exp2))
   exp)

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

((lambda (a b)
    exp)
 exp1 exp2)
8 голосов
/ 03 июня 2009
  • 4ac - это переменная с числовым значением, поэтому (4ac) не имеет значения.

  • LET связывает все переменные, но переменные не могут использоваться в вычислениях для значений.

Это не работает:

(let ((a 1) (b 1) (c (* a b)))
   c)

Использование:

(let ((a 1) (b 1))
  (let ((c (* a b)))
    c))

Выше представлены A и B с первым LET. Во втором LET и A, и B теперь могут использоваться для вычисления C.

Или:

(let* ((a 1) (b 1) (c (* a b)))
   c)
3 голосов
/ 03 июня 2009

Вам понадобится специальная let -конструктура (let*), поскольку переменные внутри определения let относятся друг к другу.

Это скорее проблема определения области видимости, чем оценки выражения (в обычных let -определениях порядок оценки не имеет значения, поскольку значения могут не использовать друг друга)

2 голосов
/ 11 июня 2009

Когда вы используете let, привязки не видны ни в одном из тел. Вместо этого используйте let * и посмотрите подробности в документации по RNRS.

...