Reputation: 5510
let
-forms are allowed to contain several expressions inside:
(let ((x 4))
x
(+ x 1))
returns 5
.
How is this expression evaluated?
Upvotes: 3
Views: 949
Reputation: 3217
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.
Upvotes: 1
Reputation: 236004
The situation you're describing occurs in several parts in Scheme, not only in a let
expression. In the following ...
let
expressionlambda
expression (and consequently, after the list of parameters in a procedure definition)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.
Upvotes: 2
Reputation: 30227
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:
Upvotes: 4
Reputation: 74655
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)))
Upvotes: 8