Search code examples
scopelisplet

prog vs. let in LISP performance difference


I have been told that in lisp, let is faster than prog (but prog has a bit more of flexibility), when making variables scoped. My question is: Why? I mean, there are certain times when using prog is easier, however, except for empirical tests, I don't know how to guess the effect. Is it when allocating memory? Is it execution? Does it come more when looping? I don't know the implementation differences' specifics.


Solution

  • Lisp

    The description of prog says:

    prog can be explained in terms of block, let, and tagbody as follows:

    (prog variable-list declaration . body)
    ==  (block nil (let variable-list declaration (tagbody . body)))
    

    In other words, functionally speaking, prog is a strict superset of let (except for a small vignette: the former returns nil while the latter returns the value(s) of its last form).

    A proverbial "sufficiently smart compiler" - in fact, any modern Lisp compiler - can detect that return and go are not used and compile the prog identically to the equivalent let:

    (disassemble '(lambda () (let ((a 1) (b 2)) (print (+ a b)) nil)))
    

    and

    (disassemble '(lambda () (prog ((a 1) (b 2)) (print (+ a b)))))
    

    produce identical output:

    Disassembly of function :LAMBDA
    (CONST 0) = 1
    (CONST 1) = 2
    0 required arguments
    0 optional arguments
    No rest parameter
    No keyword parameters
    7 byte-code instructions:
    0     (CONST&PUSH 0)                      ; 1
    1     (CONST&PUSH 1)                      ; 2
    2     (CALLSR&PUSH 2 55)                  ; +
    5     (PUSH-UNBOUND 1)
    7     (CALLS1 142)                        ; PRINT
    9     (NIL)
    10    (SKIP&RET 1)
    NIL
    

    Cadence SKILL++

    You might want to ask the implementors.