3 ms·
“a pattern-matching construct is a "special form"” What sort of pattern-matching are we talking about? You mean the sort of syntactic pattern matching we see i
by hhas02 5y ago
“a pattern-matching construct is a "special form"”
What sort of pattern-matching are we talking about? You mean the sort of syntactic pattern matching we see in e.g. Ocaml’s `match…with…`
“It can work if functions receive raw, unevaluated syntax.”
In homoiconic languages such as Lisp, all operands are by their nature either “raw syntax” (ASTs) or a superset of it (AST + bindings to call site environment). The only variable [sic] is whether or not they’ve undergone any transformations since the time they were parsed. So passing “raw syntax” is a trivial ask in Lisps, where you already get it for free.
“Lisp had that; it was called fexprs.”
It still does: explicit thunks. But those just move the question of when to evaluate out of the function (which knows what it needs and can do it automatically) to the call site (user has to do it manually, and remember to do it each time). And then it has macros too.
Fexprs went out of fashion early on in Lisp. Multiple reasons for that, few if any of which mean that it has now is the better choice. Language design is all about picking a particular set of compromises that integrate well with each other. Fexprs, for instance, did not fit well with early Lisp’s dynamic scoping, which was a motivation for dropping them. Then Lisp dropped dynamic scoping as well, for other reasons. So are fexprs still a bad fit for Lisp now that it has lexical scoping? John Shutt didn’t think so. And, coming at the same question from an end-user usability POV, I am to date inclined to agree.
You can tie your self in knots over here, or you can tie yourself in knots over there. The fallacical thinking is assuming you aren’t living with a pile of pain and limitations today. The only difference is: as status quo, you’re so familiar with it you don’t even notice it any more.
…
Sure there are disadvantages to handler-side evaluation.
For instance, optimizing compiler engineers will hate John’s $vau, because it stops them blindly rewriting individual operands not knowing/caring about context. Instead, they have to read the entire program first, to find out what operand types each function takes. No peepholes for u? Big deal.
One word: Intellisense. Every modern code editor worth its salt already does this work; because knowing argument types in advance greatly increases users’ productivity: autosuggest, autocorrect, autocomplete, generated documentation, partial compilation strategies, and so on. And, much like network effects, the bigger our programs grow, the more benefit these tools provide.
Thus early Lisp’s choice to resolve its func-vs-fexpr inconsistency (and inconsistencies are bad) by throwing out the fexprs could have equally been resolved by throwing out the funcs and just making everything an fexpr. Had Lisp gone down that road to see where it leads, we might’ve gained these authoring tools 20 years sooner.
I’d also argue that handler-side evaluation of arguments helps to bring program size back down, consolidating not only evaluation time but also type checking, bounds checking, coercion, debugging hooks, rich generated documentation, and whatever else you might want to batch-perform on operands (within sensible limits, e.g. side-effect free).
…
My experimental iris language provides much of this in its Coercion objects, plus they act a native↔implementation type bridge/ffi that is miles ahead of Python/Ruby/JavaScript’s C/C++ extension APIs in terms of ease of use and speed of extension development (a big deal if you want to bootstrap a new scripting language quickly). And in completely decoupling bridging from behavior in a way those predecessors do not, its promises future optimizing compiliation opportunities those others can only dream of.
Iris is a “toy language” by any definition. Including that you can play around and try things you would never imagine doing in a Real Language Design; and not be embarrassed when an idea doesn’t work, and sometimes discover novel ideas that do.
Oh, and learnability. I have another [artwork automation] language, kiwi, which employs this and other “non-standard” strategies, and it is uncanny to see [at least some] non-programmers instantly “get it”, and start being productive in it in hours and days, not days and weeks as AppleScript/JavaScript take.
You call it a can of worms. But honestly, what kid doesn’t love to play with one of those?
- lispm 5y agoFEXPR mostly went of fashion because they could not be compiled and their effects were hard to understand. Every FEXPR can do arbitrary computation with the forms they get passed. Thus each could do non-standard control flow and non-standard evaluation. A macro has the advantage that the generated code usually can be inspected and (for a compiled Lisp) the transformation is only done once. THE syntax of a macro form can already be checked at compile time. A FEXPR only showed usage errors at runtime.