In the end the choice wasn't made for philosophical reasons. It was made because the robot library was in Python, or so he thinks. I think this actually shows there was a strong reason to never use Scheme: it's a failed language family. Outside of academic life support and very niche uses (which are usually directly caused by the academic uses, such as Emacs lisp) scheme just doesn't exist out in the world, despite a dozen very competent and complete implementations that are still supported. This is not an invitation for lisp fan boys to stomp their feet, TIOBE doesn't have any (()())()(()) language in the top 20. Debate rankings all you want, but lisp type languages are extremely rarely used because people don't find them productive when given a choice.
I think that’s key to understanding the issue, so I guess the conversation is over.
There is clearly a pedagogical/philosophical difference, and that is usually what is used to justify using Scheme.
https://www.paulgraham.com/rootsoflisp.html
Whether that is a good thing depends on you.
You can maintain performance across multiple nestings of compiled languages.
Where as if we write a metacirular interpreter in a compiled Lisp, we now have something lesser than the host language: an interpreted dialect. And then, if we write another meticircular interpreter in that dialect, we have something even slower: and interpreter interpreting the code of an interpreter which interprets code. With each level of embedding, we lose orders of magnitude of performance.
Metacircular interpreters are good for showing something cool: that you can document a possible model of how a language works using nothing but a small amount of code in that language. Someone who has learned how to use the language can then read that small amount of code understand it and acquire that model easily. Hopefully with the understanding that's not the only model. (Like for instance that lexical variables don't have to be an association list extended by consting.)
And of course academics have studied metacircular interpreters, and their theoretical properties. In that way they're also legitimate objects of interest.
InfiniteHistoryProject MIT (2011)
https://youtu.be/r8k8o7zkA1o?t=2532
Abelson:
But Fano did say the key thing. So I talked about what you're doing is making a language and how you make languages to make languages. The technical term for that is an interpreter. So an interpreter is something that effectively takes the description of a language and lets the computer effectively speak that language. And Fano was very-- I mean he would say this in his lectures. I don't think any of the students got it. I didn't get it until like the third time through, where he sort of said the really, really key thing is that you build up complexity by constructing an interpreter. And again, that's the core idea of 6.001, said in a slightly different way.
Ah, the Pepsi Challenge! How apropos. Programming language popularity is mostly driven by marketing, after all.
It's a shame that a generation of programmers raised on high fructose corn syrup and aspartame will never know the refreshment of a homemade organic craft soda[S].
After all, if Racket[R] is the language for crafting languages[L], surely it's the SodaStream of soft drinks.
[R]: https://en.wikipedia.org/wiki/Racket_(programming_language)
[L]: https://cacm.acm.org/practice/creating-languages-in-racket/
[S]: https://www.moodymixologist.com/blog/the-ultimate-guide-to-c...
I've seen references to Dan Friedman's work on this in the '80s. It looks very powerful, but he's said it made his head hurt. I bet there will be fruitful research layering interpreters like this with AI code generation.
Also, Nada Amin and Tiark Rompf had something to say about this:
https://dl.acm.org/doi/10.1145/3158140
"12 CONCLUSIONS
We have shown how to collapse towers of interpreters using a stage-polymorphic multi-level λ-calculus λ↑↓. We have also shown that we can re-create a similar effect using LMS and polytypic programming via type classes. We have discussed several examples including novel reflective programs in Purple / Black. Looking beyond this paper, we believe that collapsing towers, in particular eterogeneous towers, has practical value. Here are some examples:
(1) It is often desirable to run other languages on closed platforms, e.g., in a web browser. For this purpose, Emscripten [Zakai 2011] translates LLVM code to JavaScript. Similarly, Java VMs [Vilk and Berger 2014] and even entire x86 processor emulators [Hemmer 2017] that are able to boot Linux [Bellard 2017] have been written in JavaScript. It would be great if we could run all such artifacts at full speed, e.g., a Python application executed by an x86 runtime, emulated in a JavaScript VM. Naturally, this requires not only collapsing of static calls, but also adapting to a dynamically changing environment."
(2) It can be desirable to execute code under modified semantics. Key use cases here are: (a) instrumentation/tracing for debugging, potentially with time-travel and replay facilities, (b) sand-boxing for security, (c) virtualization of lower-level resources as in environments like Docker, and (d) transactional execution with atomicity, isolation, and potential rollback.
(3) Non-standard interpretations, e.g., program analysis, verification, synthesis. We would like to reuse those artifacts if they are implemented for the base language. For example, a Racket interpreter in miniKanren [Byrd et al. 2017] has been shown to enable logic programming for a large class of Racket programs without translating them to a relational representation. Other examples are the Abstracting Abstract Machines (AAM) framework [Horn and Might 2011], which has recently been extended to abstract definitional interpreters [Darais et al . 2017]. For these indirect approaches to be effective, it is important to remove intermediate interpretive abstractions which would otherwise confuse the analysis.
For these use cases, our approach hints at a solution where we only need to manually lift the meta interpreter of the user level while the rest of the tower acts in a kind of pass-through mode, handing down staging commands to the lowest level, which needs to support stage polymorphism. Last but not least, it is important to note that the present work is based on interpreters derived from variations of the λ-calculus, and thus leaves a gap towards collapsing heterogeneous towers of truly independent languages. This gap is especially prominent in a setting where a language level does not follow the usual functional or imperative paradigm, e.g., if a logic programming language or a probabilistic programming language is part of the tower. Thus, we hope that our work spurs further activity in implementing stage polymorphic virtual machines and collapsing towers of interpreters in the wild."
https://www.codemesh.io/codemesh2017/nada-amin
Nada Amin - Collapsing Towers of Interpreters - Code Mesh 2017
https://www.youtube.com/watch?v=Ywy_eSzCLi8
Tiark Rompf - [POPL'18] Collapsing Towers of Interpreters