-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Two new examples for the lurk-lib repository #32
base: lib
Are you sure you want to change the base?
Conversation
if (= a 0) 0 ( | ||
if (= b 0) 0 ( | ||
let ((q (quot a b 0)) (r (rmdr a b))) (gcd b r))))))))) | ||
(current-env)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't dug into the content yet, but I notice the formatting. Have a look at this to see how lisp is supposed to be formatted:
https://ashok-khanna.medium.com/formatting-lisp-5e28020b8bac
TLDR: should look more like this:
(letrec ((quot (lambda (a b q)
(if (< a b) (quot b a 0)
(if (> (* b (+ q 1)) a)
q
(quot a b (+ q 1))))))
(rmdr (lambda (a b)
(if (< a b)
(rmdr b a)
(- a (* (quot a b 0) b)))))
(gcd (lambda (a b)
(if (< a 0)
(gcd (- 0 a) b)
(if (< b 0)
(gcd a (- 0 b))
(if (= a 0)
b
(if (= b 0)
a
(let ((q (quot a b 0))
(r (rmdr a b)))
(gcd b r)))))))))
(current-env))
- parens always up against contents or other inner parens
- format
if
with line break after condition - format
lambda
with line break after arglist, unless the whole form fits on one line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoops, yes sorry about that, I pushed old code without properly reviewing it. thank you for spotting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanted to mention the reason for all this - you don't generally look at lisp parens. The parens are for the editor and compiler, not the human reader. The editor auto-indents based on the paren structure, and your eyes easily pick up the shape of a let
or if
and their component parts.
Of course within a single line you do need to use the parens, which is why we tend to avoid deeply nested structure on a single line. Usually 3 or 4 levels or so is where it starts to get ugly and you make it more vertical and get more nice indentation.
The deeply nested if
above is not very typical. What you'd normally see in other lisps is cond
, which does the same thing without the nesting:
(cond
(< a 0) (gcd (- 0 a) b)
(< b 0) (gcd a (- 0 b))
(= a 0) b
(= b 0) a
T (let ((q (quot a b 0))
(r (rmdr a b)))
(gcd b r)))
I would expect eventually we'll have cond
in lurk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great insight, thank you for sharing. cond
would be very useful to keep programs legible for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be implemented as a macro. But it's a good observation and it occurs to me that it might be cheap enough, due to how the circuit works, to implement it directly. If we can do so in a way that makes the if
case no more expensive than if
itself, we could potentially share most/all logic with if.
For example, if instead of a terminal T
case, we instead specify that a final, unmatched value is the default failure case, then (if condition true-case false-case)
is actually equivalent to
(cond
condition true-case
false-case)
I think.
If we were okay with simply generalizing IF in that way, then I think the cost might be minimal (depending on some details I can't think through at the moment).
I'll think about it. But regardless, we can definitely implement COND as a macro in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One note, though: the example code @weissjeffm wrote above is not actually structured the way Lisp (Common Lisp and Scheme's) COND is. That's handy for the idea of a 'non-binary IF', but not so much for idiomatic Lisp. The added structure of 'real' COND is actually pretty valuable.
That said, I guess @weissjeffm's COND is the same as Clojure's…
I'd argue that if we implement COND as a macro, we should follow CL/Scheme. But I could possibly convince myself that a franken-IF would not be horrible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha yep I wrote clojure cond
syntax (more or less, I think it allows an implicit default, I can't remember off the top of my head but I didn't use it just for clarity).
I'm curious what added value you meant from the added structure? I thought of the reduction in paren count as basically free, and so much easier on the eyeballs.
This PR contains two new examples for the lurk-lib repository.