문제

let-forms are allowed to contain several expressions inside:

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

returns 5.

How is this expression evaluated?

도움이 되었습니까?

해결책

The situation you're describing occurs in several parts in Scheme, not only in a let expression. In the following ...

  • After the list of variable bindings in a let expression
  • After the list of parameters in a lambda expression (and consequently, after the list of parameters in a procedure definition)
  • After each clause in a cond expression

... you can write a list of expressions. Implicitly those expressions are enclosed inside a begin special form, the order of evaluation is from left to right, all the expressions are evaluated in turn but the value returned is that of the last expression.

For example, this expression:

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

Is equivalent to:

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

In both cases, the returned value is 3, because that's the value of the last expression in the list.

다른 팁

that's called an implicit begin, in other words your code is evaluated as if it was written:

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

Well, let's get the terminology clear just in case. A let form has two parts: bindings and a body:

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

A binding has the form (<variable> <expression>), and the body is a sequence of expressions. A let is evaluated like this:

  • Create a local environment where each variable is bound to the result of evaluating the expression in the corresponding binding.
  • Evaluate the expressions in the body in sequential order.
  • Result: the result of the last expression in the body.

First, terminology -- the expressions after the variable bindings are collectively known as the body, and each expression in the body is a body expression. Ex:

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

The body expressions are wrapped in begin -- (let ((x 2)) x (+ x 1)) is the same as (let ((x 2)) (begin x (+ x 1))).

Each body expression in begin is evaluated and the return value of the final expression is used as the return value for the entire body. Ex: (begin (+ x 1) (+ x 2)) will evaluate (+ x 1) and (+ x 2) and then return the result of evaluating (+ x 2).

If every body expression in begin has no side effects, then all but the last body expression can be removed with no change to the runtime behavior of the program. The only exceptions here are when one of the preliminary body expressions runs slowly/doesn't return/errors out -- eliminating the body expression eliminates the problem, which is a change to the runtime behavior of the program.

However, when using functions with side effects, the ability to call one or more functions for their side effects and then return a value is useful.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top