axisofeval is a programming language enthusiast's blog on Lisp, Kernel, fexprs, condition systems, and generators.
Commenters cite it in discussions of dynamic scoping, fexprs, and delimited control, pointing to Kernel and the Wat language as related work.
From what you write about macros, it hints at something like F-expressions and first class environments, though I am not sure if it actually does have it.
I find the Kernel programming language to be inspiring. It is based on first class environments and tries to go further in the direction of the philosophy of Scheme : "Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary."
Your post is also in this spirit.
A language like this would allow a much greater dynamism and a reflective capability, but compiling it is a research project. (There was also a minor scuffle here on HN, a decade ago, regarding the non-inclusion of eval in ClojureScript in order to enable better optimization.)
https://web.cs.wpi.edu/~jshutt/kernel.html
https://axisofeval.blogspot.com/2011/09/kernel-underground.html
---
Edit: Brief explanation of F-expressions (vau expressions in Kernel)
For a function call, the argument expressions are evaluated and the function only receives the values.
For a macro, the argument expressions are accessible to the macro, but the macro cant access the environment, so it cant evaluate these expression, but rewrites code into some other code.
For a vau expression as in Kernel(analog of lambda), the expression receives not just the argument expressions but also the lexical environment. This means it can genuinely return a result and not just…
I'm not OP, but there are a few I could see some mentioned in the OP's post in passing.
* The common lisp condition system [3, 0] is a way better way to do errors.
* Tune-able compilers [1] allow you to make better trade offs than even gcc allows for c, let alone Clojure's very opaque compiler.
* CLOS [2] is a very powerful object system which clojure does not replicate (they have multi methods, and java classes, but not a meta class system; think python's meta class features but better (because of macros and compiler access) and with multi methods designed in).
* Nice native interoperability (Clojure generally being on the JVM, and common lisp capable of direct calls and memory manipulation).
That being said. Clojure's unparalleled concurrency features are amazing. I would compare them as: if Clojure is the Java of lisps, then Common Lisp is the C++ of lisps.
[0] http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
[1] http://franz.com/support/documentation/current/doc/compiling.htm#decl-opts-1
[2] http://www.laputan.org/pub/papers/MOP.pdf
[3] http://axisofeval.blogspot.com/2011/04/whats-condition-system-and-why-do-you.html
> Still, the basic eval command looks remarkably similar in lisp vs TCL.
The primary difference is whether arguments are evaluated before (Scheme/Lisp) or after (Tcl) being sent to the function/command.
The deferred evaluation is what allows you to do things that you need macros for in other languages. (ie. you need deferred evaluation or macros to implement short-circuit operators, for example)
However, early Lisps had FEXPRs which also deferred evaluation. The late John Shutt built and entire Lisp called "Kernel" around the idea:
http://web.cs.wpi.edu/~jshutt/kernel.html
I strongly recommend a read through his PhD thesis:
https://www.wpi.edu/Pubs/ETD/Available/etd-090110-124904/
Unfortunately, his implementation isn't anywhere near as good as his conception. Other people have implemented it better.
http://axisofeval.blogspot.com/search/label/kernel
http://axisofeval.blogspot.com/2011/09/kernel-underground.html
The Oh Unix shell grabs some of the core Kernel concepts and runs with them in a useful package:
https://github.com/michaelmacinnis/oh
> I'm not entirely convinced of which way to add dynamic scoping to scheme is best
I believe the way Kernel[1,2,3] handle this is really great. A `vau` expression is like a `lambda` expression (it's a lexically scoped fexpr actually) except that its operands (~ arguments) are passed in call-by-text and there is an extra argument which is the dynamic environment of the call site. This way you can `eval` the operands in the dynamic environment if you want to, but you can also `eval` quoted symbols or expressions in this same environment, thus achieving dynamic scoping.
This is very powerful, `vau` expressions can replace functions and macros altogether (and you have first class macros "for free" for instance). The counterpart is that I don't know if this kind of code can be compiled down to efficient code.
[1] http://web.cs.wpi.edu/~jshutt/kernel.html - John N. Shutt's Kernel page.
[2] http://klisp.org/ - An implementation of Kernel.
[3] http://axisofeval.blogspot.fr/ - a blog which talks a lot about Kernel.
Agreed wholeheartedly.
Take this blog post, replace “Lisp” with “C++”, “Haskell” with “Rust”, and “type system” with “lifetime system”: http://axisofeval.blogspot.com/2011/01/why-lisp-is-big-hack-and-haskell-is.html.
“C++, as it stands, can't do any of that, and won't be able to do any of that. That's simply a fact. Why? Because it's coming at the problem from the wrong direction. Trying to graft an interesting lifetime system or verification onto C++ is simply too heroic and ill-specified a task. C++ starts with ultimate freedom/unsafety, and you can't constrain it. Rust starts with ultimate bondage/safety, and then, piece by piece, adds that freedom back. On a theoretically well-founded basis.”
This summarizes C++'s safety woes.
I'm sure they keep using it and that's ok, of course. But deepdown you want your projects to be widely adopted. That provides motivation and renewable workforce given that at some point the "elders move to greener pastures".
Take Go for example. Its creators helped a lot of people to write easier network software. Maybe they even would have preferred another syntax, but got over that and just used a syntax that most programmers would perceive as familiar and easy to learn. To me there is a lesson in this too.
Also this is an interesting text about the subject
http://axisofeval.blogspot.com.br/2010/06/letter-to-young-pl-enthusiast.html
(And I love Clojure, Ocaml, Factor, Lisp, Erlang... so really the lesson is for me)