6

Does Rhombus risk missing the trees for enforestation? · Discussion #199 · racke...

 2 years ago
source link: https://github.com/racket/rhombus-prototype/discussions/199
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Does Rhombus risk missing the trees for enforestation? · Discussion #199 · racket/rhombus-prototype · GitHub

I have a lot of concerns about the direction that Rhombus is heading. In general, it's possible for me to make good sense of something lisp-or-scheme-like, and Racket traditionally may have deviated from Scheme, but it was pretty easy to make sense of. A few years ago at RacketCon I wrote "Racket is an acceptable Python" and I felt pretty good about it, because I was feeling pretty good about Racket: Racket was the lisp you could get things done in. This was its biggest feature. It felt like we were on the verge of something big. That evening @mflatt told me about Rhombus, it was before the big announcement. Apparently aside from Matthias, I was the first one to express hesitation about this direction. Well, I'd like to expand on why.

I think Rhombus could be a great project. I don't consider lisps to be essentially parenthetical; the goal to provide a surface syntax that is non-parenthetical is a good one and probably seems like it should be Rhombus's main goal. (Secondary goals to figure out other useful additions to the language are good; I'd encourage asking how many of them could be libraries though.) I know @AlexKnauth recently presented on Wraith which I had some help with. Wraith seems like a good direction to me: it ultimately expands to something that's still syntactically delimited as trees, and is understandable as trees. The underlying language too is fairly understandable as trees. This is important for reasons I will expand on later.

I have a joke, I've been meaning to make it a blogpost: "LISP Isn't Syntactically Parenthetical". Wisp and Wraith are both good examples of this by using whitespace approaches, but Fructure is maybe the most interesting example of how far this can be taken: no parentheses, but even rethinking how we might edit code. Code shapes!

But Honu-style syntax... well, it's very hard for me to keep up with this project, I've read the Honu paper, and I'm very against that direction. My joking explanation is that I'm afraid we're "missing the trees for enforestation". I think some of my understanding of this congealed when reading an old writeup by Mark Miller: The Power of Irrelevance. Mark explains how in a security review, the E programming language held up well:

In thinking about lessons from the security review you and David put us through ;), I came to realize that much of its success was due to E's support for a similar quick reject property. Given a question and a large body of largely unfamiliar code, the first job of a programming language notation is to help human readers (both with and without IDE help) do a quick reject: to disqualify most of the program as being irrelevant to the current question without needing to look at most of it. (See also Visible Workings.)

Mark points out that Scheme-without-macros is fairly ideal in this regard; scheme-with-macros, well, it can be hard to know where the macros might rearrange or interject things, but still, the tree structure gives some sense of scope and hygiene helps. I have separate thoughts on how to improve this (not important here, but I think Mark's idea of "doubly hygienic macros" are possible), but it's in the polar opposite direction that Rhombus is going, I believe. When I look at Honu's enforestation, I can't make clear sense of how things will expand just by eyeballing it. It's lost the trees for enforestation, and the power of irrelevance too.

I think Rhombus has two big and admirable goals: to expand the frontier of language design, and to increase adoption. Regarding the former, it's a good goal, but the core language should remain simple enough that it can mostly be implemented in a metacircular manner. Otherwise else I think we've departed rapidly from the space that made Racket fairly ideal for this very purpose into something much more tuned to a specific set of language design choices for one specific language representation. Keeping that tree-like is important to this goal: any surface syntax should expand into something. I support things like dot-notation: foo.bar(baz) could be represented as ((%dot foo bar) baz) while not departing too far from the land of core understandability and keeping a tree-like property. I worry about some of the other proposals I see though. Wherever something could be a library, it should be a library. Avoid The Tragedy of the Common Lisp (which ironically, by still allowing a macro foundation, common lisp is less bad at than most languages, but indeed we don't want a core that's as big as common lisp's).

Regarding the latter goal of increasing adoption, the night that @mflatt told me about Rhombus, I expressed concern and skepticism, but also that I didn't want to provide stop energy against useful development. That's still true. But as I said then, it could be that Racket already has one of the core beautiful advantages: the ability to take the world of lisp and actually make it useful for people to get things done. As I said to Matthew then, "I've seen a lot of communities try to make a big energetic push to a new architectural idea, and all its energy gets consumed in that process, and the community ultimately dies." Dare I say, Perl is an example of this. It's amazing that Python wasn't, and it was due to enormous effort, and even then the changes from Python 2 to Python 3 were puny. It's unlikely that Racket is going to win by trying to enter the same space everyone else is already winning. What about running with the strengths of what we have and innovating where everyone isn't? Lisp, as a conceptual idea, is not essentially parenthetical, as Wisp, Wraith, and Fructure indicate. What if we ran with that?

I am not certain where Racket is going to go. I am hedging my bets: I have begun porting some of Spritely's components to Guile, which I wanted to do already, but my assumption was that Racket would remain the primary implementation. I'm not so sure anymore, but it really depends on where Rhombus goes. The Rhombus page gives an expansion pass in terms of "here's all the things we could do!" What's needed, for me, is now a compression pass: "here's the boundaries we will keep ourselves in!"

So let's say, here's the "Christine's wishlist of boundaries/guidelines":

  • Trees, as a foundation, are important. Parentheses aren't.
  • Lexical scoping is what makes scheme awesome, aim for increasing scope clarity, but certainly don't make it worse.
  • Designing cool language features is nice, but them being able to be emergent and composable from a few small primitives is dramatically preferable from increasing the foundational surface.
  • Keep a simple and fundamental core which can be simply expanded.
  • Libraries over #langs, and separate read approaches from eval approaches, keeping trees as the foundation.
  • Functions over macros, but macros over new primitives.
  • Some new primitives, such as "dot notation", can be included after careful deliberation, but we should make sure they retain a sensible tree-oriented design structure. foo.bar(baz) as ((%dot foo bar) baz), for instance.
  • Stay expression-oriented.
  • I'm also okay with infix notation, but we shouldn't have operator precedence: permit infix notation like {3 + {4 * 5} + x}, but not 3 + 4 * 5 - x.
  • Metacircular Racket should remain possible, easy, and beautiful (or at least, most of it should be)

So what will Rhombus be? And, invoking the power of irrelevance: what won't Rhombus be?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK