DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH
 

(r5rs.info.gz) Binding constructs

Info Catalog (r5rs.info.gz) Conditional (r5rs.info.gz) Derived expression types (r5rs.info.gz) Sequencing
 
 4.2.2 Binding constructs
 ------------------------
 
 The three binding constructs `let', `let*', and `letrec' give Scheme a
 block structure, like Algol 60.  The syntax of the three constructs is
 identical, but they differ in the regions they establish for their
 variable bindings.  In a `let' expression, the initial values are
 computed before any of the variables become bound; in a `let*'
 expression, the bindings and evaluations are performed sequentially;
 while in a `letrec' expression, all the bindings are in effect while
 their initial values are being computed, thus allowing mutually
 recursive definitions.
 
  -- library syntax: let <bindings> <body>
      _Syntax:_ <Bindings> should have the form
 
      ((<variable1> <init1>) ...,),
 
      where each <init> is an expression, and <body> should be a
      sequence of one or more expressions.  It is an error for a
      <variable> to appear more than once in the list of variables being
      bound.
 
      _Semantics:_ The <init>s are evaluated in the current environment
      (in some unspecified order), the <variable>s are bound to fresh
      locations holding the results, the <body> is evaluated in the
      extended environment, and the value(s) of the last expression of
      <body> is(are) returned.  Each binding of a <variable> has <body>
      as its region.  
 
      (let ((x 2) (y 3))
        (* x y))                             ==>  6
 
      (let ((x 2) (y 3))
        (let ((x 7)
              (z (+ x y)))
          (* z x)))                          ==>  35
 
      See also named `let', section  Iteration.
 
 
  -- library syntax: let* <bindings> <body>
      _Syntax:_ <Bindings> should have the form
 
      ((<variable1> <init1>) ...,),
 
      and <body> should be a sequence of one or more expressions.
 
      _Semantics:_ `Let*' is similar to `let', but the bindings are
      performed sequentially from left to right, and the region of a
      binding indicated by `(<variable> <init>)' is that part of the
      `let*' expression to the right of the binding.  Thus the second
      binding is done in an environment in which the first binding is
      visible, and so on.
 
      (let ((x 2) (y 3))
        (let* ((x 7)
               (z (+ x y)))
          (* z x)))                          ==>  70
 
 
  -- library syntax: letrec <bindings> <body>
      _Syntax:_ <Bindings> should have the form
 
      ((<variable1> <init1>) ...,),
 
      and <body> should be a sequence of one or more expressions. It is
      an error for a <variable> to appear more than once in the list of
      variables being bound.
 
      _Semantics:_ The <variable>s are bound to fresh locations holding
      undefined values, the <init>s are evaluated in the resulting
      environment (in some unspecified order), each <variable> is
      assigned to the result of the corresponding <init>, the <body> is
      evaluated in the resulting environment, and the value(s) of the
      last expression in <body> is(are) returned.  Each binding of a
      <variable> has the entire `letrec' expression as its region,
      making it possible to define mutually recursive procedures.
 
      (letrec ((even?
                (lambda (n)
                  (if (zero? n)
                      #t
                      (odd? (- n 1)))))
               (odd?
                (lambda (n)
                  (if (zero? n)
                      #f
                      (even? (- n 1))))))
        (even? 88))
                                             ==>  #t
 
      One restriction on `letrec' is very important: it must be possible
      to evaluate each <init> without assigning or referring to the
      value of any <variable>.  If this restriction is violated, then it
      is an error.  The restriction is necessary because Scheme passes
      arguments by value rather than by name.  In the most common uses
      of `letrec', all the <init>s are lambda expressions and the
      restriction is satisfied automatically.
 
 
Info Catalog (r5rs.info.gz) Conditional (r5rs.info.gz) Derived expression types (r5rs.info.gz) Sequencing
automatically generated byinfo2html