8 ms·
1. no garbage collector 2. No tail recursion 3. There is no cons, cdr or car stuff. Lists are just vector objects and you use push, cat, slice etc to manipula
by DannyB2 7y ago
1. no garbage collector
2. No tail recursion
3. There is no cons, cdr or car stuff. Lists are just vector objects and you use push, cat, slice etc to manipulate elements.
Only this much is radical enough to say that it isn't a Lisp but disguised in Lisp syntax. Lisp is as much about semantics as the syntax. The power of Lisp to do amazing things comes from the language capabilities. If you cannot reasonably translate powerful programs from Lisp textbooks, then is it a Lisp?
Some languages (example: JavaScript, Python) make it easy to create an inefficient Lisp interpreter that could execute common textbook programs. Minimax, A-star search, unification matching, etc.
- lvh 7y agoWelp, you're right, all of those things are true for the lisp files too (not just vp). I just read some sample source and missed https://github.com/vygr/ChrysaLisp/blob/5483e0926b926c2cde634946a3ec1d943bf087cb/docs/LISP.md https://github.com/vygr/ChrysaLisp/blob/5483e0926b926c2cde63... . I agree those are pretty serious deviations that make "only superficially lisp-like" a reasonable statement. Thanks! (IIUC the "garbage collector" is refcounting; I'm not sure what "All objects used by the Lisp are reference counted objects from the class library." means in practice, and specifically I'm not sure if that means "you basically have a GC in lisp as long as you don't make cycles".)
- vygr 7y agoIt means what it says ;) All objects used by the Lisp are instances of classes from the class library, ie that stuff in class/ folder. These instances are ref counted objects, as they are derefed and they drop to 0 refs they get deinited and freed. The Lisp is constructed from these, for example Lists in the Lisp are an instance of the class/vector, numbers are an instance of class/num, the environment is a chain of class/hmap etc. So yes, you do have GC if you don't make cycles, and you do have to care about not doing that just as you would in C++.
- rini17 7y agoIMO closures and macros are absolutely essential, not just conses.
- lvh 7y agoIt ostensibly has both macros and closures, though. The lisp source i linked creates an anonymous function and uses it with map (which I assume means it has real closures though I guess you could fake that too), and here are some macros: https://github.com/vygr/ChrysaLisp/blob/bb4ad4116d6e794eb66ec7434999328aa4412baa/class/lisp/anaphoric.inc https://github.com/vygr/ChrysaLisp/blob/bb4ad4116d6e794eb66e...
- vygr 7y agoThere is currently no GC, by choice, but I recently did some work to assist the Stats app that I added recently that could lead to me implementing a GC at some point in the future.
- pjmlp 7y agoLisp does not require tail recursion, only Scheme does.
- mnemonicsloth 7y agoMost Common Lisps (certainly the compiled ones) do tail call optimization. Clojure doesn't because it's a Lisp in Java, and Java doesn't. Back when Clojure was just starting to get some attention I watched a video [1] of Rich doing a demo for a user group. Tail call optimization was one of their first questions. He gave them an answer that sounded like he had given it multiple times before. [1] can't find it, sorry.
- pjmlp 7y agoYes it is a common optimization, however it is not a requirement for Common Lisp standard compliance, like it happens with Scheme.
- lvh 7y ago> Clojure doesn't because it's a Lisp in Java, and Java doesn't. I keep hearing this and I have no idea where it comes from. x86_64 doesn't either, Clojure has recur, and prefers consistent var semantics to silently specialcasing some tail calls. There's no particularly good reason the compiler couldn't just do it.
- lispm 7y agoFor every function call it should not grow the stack and jump into the function. The JVM does not support that. One would need to compile the code in complex ways - function calls would no longer map directly to JVM instructions.
- lvh 7y agoYou're explaining TCO. I understand how TCO works. I'm going to rephrase my own argument because it doesn't appear you interacted with it: what part of your argument doesn't work for x86_64? "One would need to compile the code in complex ways: function calls would no longer map directly to CALL/RET instructions." Sure! That's arguably what makes it an optimization. Who cares? CPUs can loop, and so can the JVM. I would maybe see your point if Clojure didn't already know how to do tail calls (and so would need to implement the allegedly complicated compilation step), but as I have pointed out several times: it already has `recur`, which lets you call a function without the JVM thinking there is a function call going on.