Как оцениваются формы let? - PullRequest
3 голосов
/ 22 февраля 2012

let -формы могут содержать несколько выражений внутри:

(let ((x 4))
   x
  (+ x 1))

возвращает 5.

Как оценивается это выражение?

Ответы [ 4 ]

8 голосов
/ 22 февраля 2012

это называется неявным begin, другими словами, ваш код оценивается так, как если бы он был написан:

(let ((x 4)) (begin x (+ x 1)))
4 голосов
/ 22 февраля 2012

Хорошо, давайте разберемся с терминологией на всякий случай.Форма let состоит из двух частей: привязок и тела :

(let (<zero or more bindings>)
  <one or more body expressions>)

Привязка имеет форму (<variable> <expression>), а тело представляет собой последовательностьвыражений.let оценивается следующим образом:

  • Создает локальную среду, в которой каждая переменная связана с результатом вычисления выражения в соответствующей привязке.
  • Оценка выражений вbody в последовательном порядке.
  • Result: результат последнего выражения в теле.
2 голосов
/ 22 февраля 2012

Ситуация, которую вы описываете, возникает в нескольких частях схемы, а не только в выражении let. В следующем ...

  • После списка привязок переменных в выражении let
  • После списка параметров в выражении lambda (и, следовательно, после списка параметров в определении процедуры)
  • После каждого предложения в cond выражении

... вы можете написать список выражений. Неявно эти выражения заключены в специальную форму begin, порядок вычисления слева направо, все выражения вычисляются по очереди, но возвращается значение, соответствующее последнему выражению.

Например, это выражение:

(cond ((= 1 1) 1 2 3))

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

(cond ((= 1 1) (begin 1 2 3)))

В обоих случаях возвращаемое значение равно 3, поскольку это значение последнего выражения в списке.

1 голос
/ 23 февраля 2012

Во-первых, терминология - выражения после привязки переменных все вместе известны как тело, и каждое выражение в теле является выражением тела. Пример:

(let ((variable-1 value-1)
      (variable-2 value-2))
  body-expression-1
  body-expression-2)

Выражения тела заключены в begin - (let ((x 2)) x (+ x 1)) совпадает с (let ((x 2)) (begin x (+ x 1))).

Каждое выражение тела в begin оценивается, и возвращаемое значение конечного выражения используется как возвращаемое значение для всего тела. Пример: (begin (+ x 1) (+ x 2)) оценит (+ x 1) и (+ x 2), а затем вернет результат оценки (+ x 2).

Если каждое выражение тела в begin не имеет побочных эффектов, то все, кроме последнего выражения тела, могут быть удалены без изменения поведения программы во время выполнения. Единственными исключениями здесь являются случаи, когда одно из предварительных выражений тела выполняется медленно / не возвращает / выводит ошибки - устранение выражения тела устраняет проблему, которая является изменением поведения программы во время выполнения.

Однако при использовании функций с побочными эффектами полезна возможность вызывать одну или несколько функций для их побочных эффектов и затем возвращать значение.

...