4 ms·
> the code that is currently executing can be manipulated live Typically when people say this about Lisp, they mean that they can redefine functions and object
by trealira 2y ago
> the code that is currently executing can be manipulated live
Typically when people say this about Lisp, they mean that they can redefine functions and objects live, having all the code adapt to use the new definitions, or when their code hits an error, they can not only redefine functions and objects live, but also examine the state of the call stack and change the values of variables live, and then let the code run again. This[0] is a clear explanation that I found. There's also a video[1] that shows the same thing.
However, I don't know if those apply to Scheme. Also, I am pretty sure it is unrelated to Lisp being homoiconic, and that it's more about it being dynamically typed and interpretable.
[0]: https://malisper.me/debugging-lisp-part-1-recompilation/ https://malisper.me/debugging-lisp-part-1-recompilation/
[1]: https://youtu.be/jBBS4FeY7XM https://youtu.be/jBBS4FeY7XM
- hollerith 2y agoBut that can't be "what makes Scheme and other homoiconic languages special".
- trealira 2y agoI suppose that, if I'm asked "What is something that makes homoiconic languages special?" and the answer can't be that it makes macros easy, then I would say it's that it's easy to write an interpreter for that language in the language itself, because the data structures that form the syntactic structure of the language are themselves first-class objects. That's why the interpreter from the appendix of the LISP 1.5 manual can be so short. That's also why the EVAL function takes as a parameter a list of atoms, and not a string, as in non-Lisp dynamically typed languages; since a Lisp program is also a list of atoms, that's the form it takes in the interpreter. The first Lisp compiler [0] isn't so long, either. The equivalent eval function in non-homoiconic languages requires a lexer, parser, and special definitions of data structures to represent the syntax, as well as functions to manipulate those data structures. [0]: https://texdraft.github.io/lisp-compiler/internals.html https://texdraft.github.io/lisp-compiler/internals.html
- hollerith 2y agoI like that answer, and want to add to it. Scheme was the first language with lexical scoping of variables, and after Scheme was published in 1975, most new languages have had lexical scope and most languages used now (Java, C#, Javascript, Rust) have it. I think the qualities you describe make it easier to experiment with (Lisp-like) languages and language implementations, which is why lexical scope appeared in a Lisp-like first. Also, I think the concept of a "closure" appeared first in discussions about Lisp (maybe as part of the same discussions that led to lexical scope). Ditto I think continuations and continution-passing style. Also the interpreter you refer to in Appendix A of the Lisp 1.5 manual had a subtle problem or area for improvement around functions appearing as arguments to functions, and the Lisp's community's discovery of that and solution to that seems to have been incorporated into other languages, probably first the early functional languages like Miranda, then on to Javascript, etc.
- trealira 2y agoIt's funny, because I had just recently read about there being a bug in that interpreter due to dynamic scoping, but forgot about when writing that.
- deleted 2y ago[deleted]