Robert-van-Engelen/tinylisp

Expression for multiple let does not work

oz123 opened this issue · 7 comments

oz123 commented

I had difficulty understanding:

> (let ((x 3) (y 9)) (/ (- y x)))
2

First, this expression (is this an expression? Excuse me if I use the wrong lingua) does not compile.

$ gcc --std=c99 tinylisp.c -o tinylisp
$ ./tinylisp 
tinylisp
930>(let ((x 3) (y 9)) (/ (- y x)))
ERR

Second, I was trying some basic algebra without let, and I was surprised by the result:

929>(/ ( - 9 3))
6

In clojure this is the result:

$ clojure-1.11 
Clojure 1.11.1
user=> (/ (- 9 3))
1/6
user=> 

Also in chicken scheme:

$ csi
CHICKEN
(c) 2008-2021, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.3.0 (rev e31bbee5)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]

Type ,? for help.
#;1> (/ (- 9 3))
1/6

I believe there is a problem with the arithmetic here, and also in the expression found in the PDF .

The let has no list to demarcate the variable binding pairs. Iit's just:

(let* (x 3) (y 9) (/ (- y x)))

The arithmetic operators require two arguments or more. One argument is just the value returned, so you will need:

(let* (x 3) (y 9) (/ 1 (- y x)))

Please read the PDF, because both "issues" are mentioned in it. The PDF has a lot of comments explaining why this Lisp works and what it does. The PDF includes suggestions on how to change the code. You can change the behavior you want to have. Also, Lisp's can differ and that is fine. There is no standard.

oz123 commented

Thank you for your explanation. Both the code in the book, and the experssion you posted aren't working for me.
If this is intentional, I would appreciate if there was a comment on that.

Your first expression:

930>(let (x 3) (y 9) (/ 1 (- y x)))
ERR

Your second expression:

929>(let (x 3) (y 9) (/ (- y x)))
ERR

The example from the PDF which I expected to give 2:

929>(let ((x 3) (y 9)) (/ (- y x)))
ERR

These expressions work:

929>(if (eq? 'a 'a) 'ok 'fail)
ok
927>((lambda (x y) (/ (- y x) x)) 3 9)
2

Can you explain which is the correct syntax which actually yields 2?
Alternatively, if the expression in the book isn't supposed to give 2, can you please add a comment in PDF?

I forget to use let* instead of let in the example in my reply. Both are available when the article's primitive let is implemented.

To avoid confusion, I've added a list of "99-liner Lisp language features" to the README.

oz123 commented

Thank you very much!
Indeed with let* your examples work:

930>(let* (x 3) (y 9) (- y x))
6
929>(let* (x 3) (y 9) (/ (- y x)))
6

The example in the PDF which returns 2 is still not working with let*. You might want to fix this, since this isn't making the enthusiastic reader comfortable reading further when simple examples aren't working.

I agree. That let example was from "regular" Lisp. I will add a comment to that part in the article.

It also has a typo with x missing, since I had meant to use the same example as the subdiv example earlier in the article that computes (/ (- y x) x)) as 2.

Thanks for letting me know!

oz123 commented

Unfortunately, the example still doesn't work:
image

Also, the code embedded in the paragraph is slightly different from above (both don't work).