5 ms·
Last post: All of my own “amateur” end-userlanguage design work of the last 15 years is the result of coming up through AppleScript, simultaneously delighted a
by hhas02 5y ago
Last post:
All of my own “amateur” end-userlanguage design work of the last 15 years is the result of coming up through AppleScript, simultaneously delighted at the power it gifted me while increasingly appalled at how much hard unforgiving graft I put in to master this supposedly “easy language for ordinary end users”. (Cook and Harris made me the the monster I am today!) Which got me thinking: I appreciate all that C&H tried to do in their own end-user-language work. But surely it could, should, and must be done much better.
And the answer is: YES! End-user programming can be made vastly quicker, simpler, easier, and accessible; and plain old written words—humanity’s greatest and most successful technology of the last 10,000 years are.
Aaaand, I’m still figuring out all the details [where the devil is]. But I’m further on.
So for those that are bravely curious: there are 3 experimental language proof-of-concepts on my GitHub that you are free to explore and do with as you will: entoli, the second one, and iris.
(The first two are somewhat interesting experiments. The third, could be viable. All technically “toy languages”. But so’s JavaScript—and it prolly has 10Bn seats and counting. “Toys” that solve problems = Cool Beans!)
Iris & friends are all “stealth Logos”; much as Logo itself is a “stealth Lisp”. Personally I’d argue Logo’s more Forth than Lisp; and in any case Lisp isn’t a good Lisp either, because Lisp, like AppleScript, BS-es its users by hiding complexity instead of eliminating it; in Lisp’s case pretending it is simple and perfectly uniform while being absolutely riddled with invisible special forms[1].
Lisp’s mistake: eager evaluation. Once you move decision-making as to how and when arguments are evaluated, from the command’s context to the handlers’, the number of special forms your language requires to do its job drops to zero. John Shutt’s Kernel language solved this, although couched in typically cryptic academic terms I don’t think many noticed or realized its significance.
I solved the same problem independently, though coming from the hacker’a “git it done” perspective. You can see how I did it in iris &co. Interpreted performance is inevitably slowed by the extra layer of abstraction. However, by completely separating handler implementation (just an ordinary Swift function) from handler interface (the novel iris↔Swift type bridging that converts arguments and results from one to other), it should be trivial to create an optimizing Iris compiler that traverses an Iris script (which, like Lisp, is composed of simple native data structures) and outputs a Swift program that links up those Swift functions directly.
And that’s relevant here too, because? Because I lifted that whole idea straight from AppleScript’s “application dictionaries”; and a helluva terrific idea those were too. (Even if they botched some of the implementation details, and then quit in anger before the developer documentation was done.)
High-level RESTful interfaces? Cook and Harris largely did it first, and arguably did it better too. And theirs was just as ubiquitously misinterpreted and rottenly implemented by 99% the rest of the world as HTTP is today. (But that’s a rant for elsewhere.)
…
Now if anyone is really really crazy and looking for something to amuse, #3, iris (its name is obvious wordplay) has one outstanding TODO: finish its library that allows it to speak Siri Shortcuts. Because Shortcuts’ awful XML workflow files, stripped right down to their essentials, are simple sequences of commands; exactly what Forth and Lisp and Logo and my own languages all speak. I am currently pursuing a different market, though if anyone else wishes to pick up and run with iris: be my guest.
Right now, Jellycuts is leading the field, having cracked the translation bit and put a nice, if unimaginatively conventional “UI” around it. (Although its increasingly solid Swift-like syntax is a good practical choice from a marketing perspective; and I’m honestly surprised @AriX’s team hasn’t swooped in and bought it and its developer yet.)
Because whoever can unify text-based scripting [2], GUI-block-based scripting, and voice-driven scripting, into a single language that just speaks words, with a choice of presentations for every market and task, can basically own end-user automation for the next 30 years. For with billions of “supercomputers in pockets” today, and a billion kids grown up using them and hungry for more, there is an opportunity there to redefine “Personal Computing” for this new generation.
(And I’ll bet you no-one at Apple, Alphabet, et al has even noticed it yet. Just remember: building it is the easy part; the trick is in clinching the sale.)
--
[1] Hilariously unaware example of developers expertly explaining why special forms are required in programming languages: https://stackoverflow.com/questions/33465692/why-is-cond-a-special-form-in-scheme-rather-than-a-function https://stackoverflow.com/questions/33465692/why-is-cond-a-s...
[3] And here think: not Bash, not C, not Python, but “TXT-speak”. Because the pidgin-English we all use when texting on our phones is remarkably similar to the pidgin-English that Logo language used (and which my own language designs use too). A natural, evolved, successful text interface in which a billion users are already trained and know how to use.
[3] Perfectly begging the question, which John answered: “They’re not!” https://news.ycombinator.com/item?id=3831012 https://news.ycombinator.com/item?id=3831012
- kazinator 5y ago> Once you move decision-making as to how and when arguments are evaluated, from the command’s context to the handlers’, the number of special forms your language requires to do its job drops to zero That's a gaping fallacy based on the idea that special forms do nothing but control argument evaluation. For instance, oh, a pattern-matching construct is a "special form", and if you already don't have it, it won't materialize out of thin air just from the fact that function arguments are lazily evaluated. It can work if functions receive raw, unevaluated syntax. But then you don't have zero special forms: you have de facto as many special forms as there are functions in your image. That whole can of worms is just literally a can of worms. Lisp had that; it was called fexprs.
- 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?