Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>What <code>let*</code> expands to</h2> <p>This:</p> <pre><code>(let* ([a 1] [b (* 2 a)]) (cons a b)) </code></pre> <p>expands to this:</p> <pre><code>((lambda (a) ((lambda (b) (cons a b)) (* 2 a))) 1) </code></pre> <p>Here's a nice way to think of what <code>lambda</code> means in Scheme (nice because it's both simple and accurate): it's both a label for a place in the program <em>and</em> a scope for bound variables. In Scheme, a label for a place in the program (like what you can <code>goto</code> to in other languages or branch to in machine language) always goes with a scope for bound variables. You can only "goto" a place in the program by supplying values to bind to the variables bound within its scope. </p> <p>Scheme's <code>let</code> is a way of saying, "I want to make a scope where these variables are bound, but I don't want to wait until later to tell their values. I want to specify their values right here." So, <code>let</code> is just a macro that makes the lambda and then supplies the values right there.</p> <p>If you want the values of one of the variables to be an expression that uses another of the variables, like the way <code>b</code> is expressed in terms of <code>a</code> above, then <code>b</code> has to be defined within the scope of <code>a</code>. Hence the <code>let*</code> macro, which defines each successive variable in a scope that includes the previous variable. Since we have a bunch of nested scopes, they are implemented by a bunch of nested lambdas.</p> <h2>The macro</h2> <p>Here's how to tell Scheme how to rewrite a <code>let*</code> as a bunch of nested lambdas and function applications:</p> <pre><code>(define-syntax let* (syntax-rules () [(__ () body ...) (begin body ...)] [(__ ([v e] [v* e*] ...) body ...) ((lambda (v) (let* ([v* e*] ...) body ...)) e)])) (let* ([a 1] [b (* 2 a)]) (cons a b)) =&gt; (1 . 2) </code></pre> <p>In <a href="http://www.scheme.com/petitechezscheme.html" rel="nofollow">Chez Scheme</a>, you can play around with this in the REPL by typing <code>(expand '(let* ([a 1] [b (* 2 a)]) (cons a b))</code> and seeing what comes out. Here's what comes out when I try it:</p> <pre><code>(let ([#:a 1]) (let ([#:b (#2%* 2 #:a)]) (#2%cons #:a #:b))) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload