Niue available for consumption

The Niue language was made available for public consumption on Mar 23rd.  A release is yet to be made but this early announcement has met with favorable response.  Many have tried the language and came back with comments and bug reports.  Thank you all.  In a short time, Niue made its presence felt at many interesting places on the web:

  1. reddit
  2. rosettacode 
  3. Slava Pestov's twitter

Thanks to the guys who joined the Niue users group and made it come alive!

let and letrec

This one is for Scheme newbies.  How is let different from letrec?  As you already know let introduces new bindings and evaluate its body in a new environment enriched by those bindings.

(let ((a 10) (b 20))
   (+ a b))
=> 30

let gets evaluated to the value of the last expression in its body.  We can also bind procedures using let:

(let ((sqr (lambda (x) (* x x))))
   (sqr 10))
=> 100

Is it possible for such a procedure to make recursive calls to itself?  Let us check that out:

 (let ((fact (lambda (n) 
(if (= n 0) 1
   (* n (fact (- n 1)))))))
    (fact 4))
=> reference to undefined identifier: fact

Our attempt to make fact call itself has failed.  Why?  The following steps show how the variable fact is bound by let:
  1. fact is bound to the new, enriched environment.
  2. The lambda expression is evaluated in the current environment, which do not have a binding for fact and the evaluation fails at the recursive call.
Now we know why the recursive call failed. Only the body of let is evaluated in the enriched enivironment.  In contrast letrec evaluates both the binding expressions and the body in the new, enriched environment. Let us rewrite the factorial procedure using a letrec:

(letrec ((fact (lambda (n) 
(if (= n 0) 1
   (* n (fact (- n 1)))))))
   (fact 4))
=> 24

These are the steps followed by letrec for making new bindings:
  1. fact is bound to the new, enriched environment.
  2. The lambda expression is evaluated in this enriched environment. and it has no problem looking up the variable fact.
  3.  The body is evaluated in the enriched environment.
We can even bind mutually recursive procedures in letrec:

(letrec ((even? (lambda (n) (if (= n 0) #t (odd? (- n 1)))))
         (odd? (lambda (n) (if (= n 0) #f (even? (- n 1))))))
 (even? 10) ;; => #t
 (odd? 3) ;; => #t
 (even? 11))
 => #f