I've been chewing through a bit of The Little Schemer and the Peano examples got me thinking about operation size and time.
I got some help on making Peano Multiplication linear -- however (time ...)
didn't show much difference between a lexically scoped version and the let-loop
version.
I do however find a massive difference between the lexically scoped and let-loop
versions when minting a Peano Exponent function.
The obvious question is why it makes such a difference (or perhaps it does not and my attempt at a lexically scoped Peano Exponent has some fatal error)?
-- i had thought i understood what the let-loop
was doing in terms of storing the value in the parent enclosure (making the two roughly equivalent); in which way is this wrong?
;; lexically scoped version of Peano Exp
(define (exxp-lex b ex)
(define (exxp-aux ex prod)
(cond
((zero? ex) 1)
((= ex 1) (mX-let b prod))
(else
(exxp-aux (- ex 1) (mX-lex b prod)))))
(exxp-aux ex 1))
;; let version of Peano Exp
(define (exxp-let b ex)
(let loop ((ex ex)
(prod 1))
(cond
((zero? ex) 1)
((= ex 1) (mX-let prod b))
(else
(loop (- ex 1) (mX-let prod b))))
))
If it's relevant, I am using petite-chez scheme.
For reference, here are the Peano Multiplication functions.
;; a lexically scoped version Peano Multiplication
(define (mX-lex n m)
(define (mX-aux m product)
(if (zero? m)
product
(mX-aux (- m 1) (+ product n))))
(mX-aux m 0))
;; using let for Peano Mult
(define (mX-let n m)
(let loop ((m m)
(product 0))
(if (zero? m)
product
(loop (- m 1) (+ product n)))))
let
". As I said, this is neither here nor there regarding the question; I only mention it since you seem interested in learning more about Scheme. \$\endgroup\$letrec
. (In fact, many implementations translate namedlet
toletrec
, and may do something similar with internal definitions). However, locally scoped mutually recursive procedures can be expressed with internal definitions andletrec
but not with namedlet
. I see it as coming down to what best fits the logic and flow of your function(s), there shouldn't be a big performance difference between otherwise equivalent binding forms. \$\endgroup\$