Earlier quoted context omitted.
And?
Aint I clever? Realized rightaway that forwards JMPs to the next address could have been filled with NOPs instead. But this is not a beauty contest.
Compiling a Lisp to x86-64: Let expressions
31–40 of 40 posts
Re: Compiling a Lisp to x86-64: Let expressions
#32Earlier quoted context omitted.
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-recursiv…
> 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
Re: Compiling a Lisp to x86-64: Let expressions
#33Earlier quoted context omitted.
Aint I clever? Realized rightaway that forwards JMPs to the next address could have been filled with NOPs instead. But this is not a beauty contest.
Ah, right, I didn't look at your name. Have you worked on any other lisps?
Re: Compiling a Lisp to x86-64: Let expressions
#34Earlier quoted context omitted.
> 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.
Re: Compiling a Lisp to x86-64: Let expressions
#35Earlier quoted context omitted.
Yes, real compilers do handle `((lambda (x) ...) ...)` as well as a `let`, because as a Lisp programmer you want to be able to define and use new macros freely, without having to worry too much about low-level optimizations. Kent Dybvig gave a talk on this sort of thing called the "macro-writer's Bill of Rights". It's a similar concept to the recent talk about what optimizations need to be guaranteed for "zero-cost a…
By guaranteed optimisations talk, are you referring to this blog post by Robert O'Callahan: https://robert.ocallahan.org/2020/08/what-is-minimal-set-of-... ?
Re: Compiling a Lisp to x86-64: Let expressions
#36(lets a 1 b 2 (+ a b)) is such a nice macro. Everything but the last expression are bindings.
(let ((a 1) (b 2))
(+ a b))
and harder to implement as a syntax rules macro :)Re: Compiling a Lisp to x86-64: Let expressions
#37Earlier quoted context omitted.
That's really not true of Common Lisp implementations. These have many more than 20-30 functions, and they all have to be there because one can obtain them as values and pass those values around (and, in the case of standard generic functions, add new methods for them). There may be specific expansions for calls to particular standard functions when the types of the arguments are known, or when particular keyword and…
Well, of course; many of them will be functions, not macros. What I mean is, there will only be 20~30 builtins ; the rest can be implemented 'in userspace', as it were. Though specifically in the case of cl, clos might complicate that somewhat, but probably not a ton.
It's one of the features of Common Lisp that things that might be buried in the compiler in other languages are surfaced and made available to the user. This means a great deal of the language's standard functionality can be implemented as if it were in "user space". Macros, readtables, method combinations, setf expanders and generalized places, for example.
IMO, if Common Lisp were to be extended (it probably won't be, at least officially, as there's no money for another whack at a standard) I think it would be best even if more "internal" features were surfaced this way, and made available for user extension.
Re: Compiling a Lisp to x86-64: Let expressions
#38(lets a 1 b 2 (+ a b)) is such a nice macro. Everything but the last expression are bindings.
What? The let way of variable bindings is standard just about everywhere. Why replace it with something that doesn't visually distinguish binding pairs? To my lispy eyes it is harder to navigate than (let ((a 1) (b 2)) (+ a b)) and harder to implement as a syntax rules macro :)
Arc uses (let a 1 (+ a 2)), and lets is simply the logical progression of that.
Re: Compiling a Lisp to x86-64: Let expressions
#39Earlier quoted context omitted.
What? The let way of variable bindings is standard just about everywhere. Why replace it with something that doesn't visually distinguish binding pairs? To my lispy eyes it is harder to navigate than (let ((a 1) (b 2)) (+ a b)) and harder to implement as a syntax rules macro :)
Free yourself from the shackles of parens. Throw off your bindings and run into the streets. It's worth it. Arc uses (let a 1 (+ a 2)), and lets is simply the logical progression of that.
The parens of let lets me easily distinguish the binding clauses, and lets me navigate it a lot easier in Emacs. The lets macro seems like the opposite of that. Every odd thing except the last element is an identifier and every even thing is that identifiers value.