5

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.

sds
  • 58,617
  • 29
  • 161
  • 278
user1134991
  • 3,003
  • 2
  • 25
  • 35
  • Which version of Scheme are you referring to? Neither R5RS nor R6RS contain any prog. – bipll Apr 18 '18 at 14:32
  • It is Cadnce SKILL++ – user1134991 Apr 18 '18 at 14:54
  • 1
    Cadence SKILL++ seems to be descended from Franz Lisp (which itself is kind of cool, that something is still using it all these years later). It's possible that Franz Lisp had performance differences between `let` and `prog` although I can't find any mention of them. –  Apr 20 '18 at 13:40

1 Answers1

8

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.

sds
  • 58,617
  • 29
  • 161
  • 278