Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Well, you've implemented let* :

    (let* ((a 1) (b a)) (+ a b))
is equivalent to:

    ((((lambda (a) (lambda (b) (+ a b))) a) 1)
And anyway, implementing 'letrec' in C/Asm is really not that hard: allocate cells, assign names to them, compute the values. Compare that with the machinery of making closures (flat or linked?) and function invocation.

I personally prefer to have 'letrec' as a primitive and implement non-recursive 'let' on top of it by checking whether any newly bound names are referenced from the bound values.



> Well, you've implemented let* :

    (let* ((a 1) (b a)) (+ a b))
I think this should just be plain let.

If I do:

     (define-syntax let-
      (syntax-rules ()
        [(_ ((x e) ...) b1 b2 ...)
         ((lambda (x ...) b1 b2 ...) e ...)]))
And then try:

       (let- ((a 2) (b a)) (+ a b))
I get:

     ; a: undefined;
     ;  cannot reference an identifier before its definition
     ;   in module: top-level


I don't really understand if you are surprised by that or not. That is the expected behaviour of regular let. Parallel binding. let* is sequential.


I'm not surprised by that. The parent suggested (or I thought that they did) that this was actually the definition for let* . And my point was to show that it does not behave like let* but rather like plain let.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: