At RacketCon in July 2019, Racket architect Matthew Flatt proposed some ideas for what he first called “Racket2”, but is now called “Rhombus”—the ostensible successor to today’s #lang racket. These ideas have caused ripples—and a little consternation—within the Racket community.
Most notably, Matthew floated the idea of moving away from Racket’s parenthesized S-expressions to notation more similar to other languages—what is sometimes called “infix notation” to contrast it with Racket’s “prefix notation”. Matthew’s rationale is that “parentheses are certainly an obstacle for some potential users of Racket … we should try to remove or reduce the obstacle”.
I’ve come to appreciate parenthesized S-expressions. But to be fair, what initially persuaded me to try Racket was the Scribble @-expression notation. This style of notation didn’t exist anywhere else, and allows you to write things like @func{text body} that combine invocations of code with ordinary text. (This notation system is also the foundation of my publishing language Pollen.)
So I agree with Matthew Flatt that notation matters. Indeed, I believe that the ability to design notation is a key benefit of language-oriented programming. + PL researchers are less excited by notation, but that’s fine—they need to care about proving results, whereas practitioners need to care about ergonomics. That’s why I spend a lot of time in Beautiful Racket on lexers and parsers, because these are the tools we use to implement that notation.
In the case of Lisp languages like Racket, Matthew Flatt is right: among a certain audience of potential users, parentheses are a deterrent. Who knows why? But in the last 60 years, simply grabbing these dissenters by the lapels and fumigating them with the stinky garlic breath of parenthesized S-expressions has not been a winning strategy. If Lisp partisans want different results in the next 60 years, we need to try something new.
Within the Racket community, some of the professed alarm about new notation has centered around the possibility of losing parenthesized S-expressions altogether. So far, I find these concerns overstated:
Racket is an interesting language precisely because it takes contrarian, even daring, positions—not because it follows the crowd. For example, the reason Racket exists at all is that it outgrew the boundaries of Scheme. For another example, the multiyear effort to reimplement the entire language on Chez Scheme, which is now bearing fruit. On that view, investigating alternate notation is consistent with Racket’s culture of curiosity. Certainly, if you want an intellectually stagnant programming language, you have plenty of other choices.
In any case, it’s not obvious to me that infix notation must necessarily displace parenthesized S-expressions. Again, consider Scribble: in addition to notation like @func{text body}, Scribble supports more standard-looking S-expressions like @(func "text body"). With Scribble, the Racket team already figured out how to let both styles coexist. There’s no reason to think they couldn’t do the same for Rhombus.
But even if they don’t, the Racket team has already given assurances that vanilla #lang racket—parentheses and all—will continue to be supported for a long time. As I understand it, they’re not even promising that the new notation will “eventually take over”. Instead, it might remain part of a separate #lang indefinitely, and find whatever audience it finds. A wholesale displacement of parenthesized notation would only occur if and when a critical mass of users supports it.
Unfounded opposition to theoretical future notation is even less defensible than unfounded opposition to parentheses. If any engineering team can pull this off and blow everyone’s minds with how good it can be, it’s the Racket team. I’m content to reserve judgment until there’s a prototype that’s good enough to criticize. Certainly, I don’t want to get caught looking stupid by betting against Matthew Flatt and the other core Racket engineers.
I feel confident, based on their track record, that the Racket team will remain conscious of the costs and benefits of new notation. Certainly, it would be counterproductive to adopt new notation that alienates everyone who already likes Racket.
All that said, I do have a few concerns. If you think I’m wrong, I invite you to send me evidence & argument against them. But I’ll set them out here so I needn’t repeat myself in the years to come:
I expect that most of the parenthesis-hating programmers whom Racket hopes to attract with new notation will simply move on to some other pretext for dismissing Racket. That is, I believe that the objection to Racket (and other Lisp languages) often goes deeper than parentheses, but it’s shorthanded as “ugh, parentheses” because that’s easy and obvious.
It would be sad to divert a lot of time & effort to persuade people who are basically unpersuadable. That’s not an argument against trying anything new. Rather, it’s an argument in favor of proceeding on a prototype basis, and finding ways of validating that prototype with the intended audience.
The declining popularity of Lisp languages in CS teaching—and the related failure of these languages to ever crack industry in a big way—is a longstanding trend that goes beyond Racket.
For example: Scheme was originally created in 1975 for use in MIT’s introductory CS course, but in 2009, it was replaced by Python. Another example: programmer and startup investor Paul Graham has vigorously promoted Lisp for decades, citing it as the reason for his own startup success. Despite the weight of his endorsement (and his cash), there’s little evidence Lisp languages have made much of a dent in the tech industry. And another example: longtime Lisp advocate Peter Norvig switched from Lisp to Python because “it was better pseudocode” and because Python “has the edge … when the main goal is communication”.
“What about Clojure?” That is certainly the biggest Lisp success story in recent years. Still, though Clojure is a well-designed Lisp, its overwhelming advantage comes from the fact that it’s hosted on the JVM. That is, Clojure can be Trojan-horsed into workplaces that use Java (= about a zillion).
Against that backdrop, I think it’s fruitless to expect that Racket is ever going to be the choice of kajillions, or even mere jillions, of programmers. So what? Among programming languages, I think of it more like a McLaren supercar than a Honda Civic: it’s not for everyone, but if you need what it can do, you will love it!
If it weren’t obvious already, I believe that Racket’s great, unique strength—do people still use the phrase “killer app”?—is language-oriented programming, where it has no peer. That is why Beautiful Racket exists.
The interaction between the Racket community and Racket core engineering team has happened—at least in my six years of Racket experience—at something of a remove, like polite neighbors separated by a shoulder-high hedgerow. The core team is very responsive when it comes to, say, bug reports. But with larger issues, the core team makes the decisions, and there’s not huge visibility into how or why these decisions are made.
There is not, for instance, an official RFC process or other means of collecting and responding to community feedback in a sane and coherent manner (= roughly, a system that rewards reasoned thought over shoutiness and squabbling). + Typed Racket has been experimenting with an RFC system of its own, though activity has been light so far. Since RacketCon there’s been an effort to get an RFC system started. Fair enough. But this kind of change takes more than just committing some source files to a new repo. It requires a deeper cultural switch: the whole Racket core team has to commit to the new system, and then lead by example. + On this issue, unity matters. There are five members of Racket’s core team. Often, they speak as a group. Sometimes, they do not, which can be confusing to those trying to discern Official Racket Policy.
Can they? Will they? I have no idea. Of course, it’s the core team’s prerogative to run the project as they wish. The rest of us are, after all, freeloaders. But procedural transparency isn’t just a mechanism for gathering community feedback, nor is it bureaucratic foofaraw. It’s also a tool for convincing users, especially industry adopters, that Racket has procedures and values that are worthy of time & money commitments—that there is a “rule of law” that guides outcomes.
I may be a visible user and fan of Racket—and even a teacher at Racket School—but I don’t have any influence on the direction of Racket. I think the Racket community is now big enough, however, that pulling off this kind of major change in Racket requires a stronger procedural foundation. The absence of this foundation is, in this fan’s opinion, a greater risk to the success of Rhombus than any technical hurdle.
BTW, none of this is meant to imply any pessimism about Racket. Beautiful Racket has already introduced thousands of people to LOP and Racket. I plan to keep using Racket in my own work, and keep spreading the word.
Growth of an open-source language doesn’t just mean more commits to the code. It also means more commitments to the community. Racket has already evolved tremendously in the time I’ve been using it. I look forward to seeing where it goes next.
As I mentioned above, I think Racket’s facility for language-oriented programming (LOP) is its killer feature. The #lang abstraction, for instance, is a) amazing and b) available in no other language. Under the hood, these LOP tools are made possible by Racket’s extraordinary hygienic macro system—another feature unique to Racket.
Still, what we think of as Racket’s modern LOP tools weren’t there from the beginning. Racket, after all, started as a Scheme implementation. These extra pieces accrued over time.
Thus, to me—not that I have any say—the major opportunity of Rhombus would be to rebuild the language with these unique LOP ideas at the core, rather than tacked on from the outside.
Recently I was researching a question about certain differences between Rust and C. Someone quipped that “in Rust, they fill gaps in the language by making the language more complex; in C, they fill those gaps by writing more C”.
A cute idea, which applies nicely to Racket too: once you have the ability to make languages, why would you make the core language more complex? Why not just make more languages? Count me among those who think even racket/base has gotten too big.
My ideal Rhombus would take the idea of LOP abstraction to its natural extreme. I could foresee a system where the core language is smaller, and pieces are mixed in as needed. Racket core engineer Jay McCarthy has already explored this idea in his #lang remix project.
Maybe there isn’t even one “main” language—you pick the one that suits you. This also neatly solves the question of whether prefix or infix notation ought to prevail. Answer: neither. They coexist. Deal with it!
“But industry adopters want a language to have a canonical notation blah blah …” To a degree, I’m sure that’s true, but—
If the animating idea of Rhombus is to disguise the language’s best features to better attract people who don’t care about them, then it’s a waste. Let Racket be Racket.
In practice, network effects would cause one or two notational dialects to dominate for Racket at large (say, one with parentheses and one without). Other notations would persist for domain-specific purposes (like Pollen).
FWIW, there’s already a huge language community that embraces multiple notational dialects for the same underlying language: JavaScript. So perhaps LOP as a concept is not as foreign as it once was.
All that said, pulling this off would require substantial upgrades to deliver on the promise of a top-to-bottom LOP platform. For instance, the Scribble documentation system, though fantastic for languages that use parenthesized S-expressions, is mostly useless for those that don’t. Supporting arbitrary notation in Scribble documentation should be within reach, just as one can write custom indenters and syntax colorers for DrRacket.
Would this be a lot of work? Well, yeah. Am I the one who’s going to do that work? Well, no. + Though I contribute where I can, for instance improving the brag parser language. So feel free to ignore me. But as a consequence of writing Beautiful Racket, I’ve gotten a deeper look at Racket’s LOP tooling than many. I know the strengths; I know the weaknesses.
And from piles of fan mail, I also know that people really dig this material. Primarily because it uncorks a whole new way of thinking about programming. The reason I expect more from Racket is not because I’m dissatisfied with what’s there. On the contrary—it’s because Racket has already shown itself capable of so much, thus it’s the only language where those expectations seem achievable, rather than merely quixotic.
Originally, this project was called “Racket2”. On Oct 2, it was renamed Rhombus. (The language emerging from the Rhombus project may ultimately have a different name.)
In an earlier version of this piece, I had recommended against “Racket2”. Why? I could believe that “Racket2” was the name of something that existing Racketeers can distinguish, with small effort, from what is today known as “Racket”.
I was less persuaded, however, that people new to this community—who are a key market for this new language—would discern the difference as easily. To them, “Racket2” would naturally sound like the successor to Racket. If you had already decided (for whatever rational or irrational reason) that you didn’t like Racket, why would you be interested in Racket2? It would be like broccoli farmers trying to appeal to children by calling it Broccoli2. Press release: “Broccoli2 now tastes like french fries!” Sorry—you lost them at broccoli.
If this were some private project, the working title wouldn’t matter. But the development of this new language will be happening in public view, assumedly in part to attract some of those people who had given Racket the brush-off in the past. Thus, a name other than “Racket2” makes more sense. To those newly curious, the genetic connection to Racket isn’t especially interesting. They’ll be evaluating this new language on its own merits.
To use a practical analogy: this new language will be at least as different from current Racket as Scribble is, and Scribble warranted its own name. It’s just “Scribble”—not “Racket Scribble” or “Scribble by Racket”, etc.
And now it is called Rhombus. Wish granted.
After a burst of activity in the initial months, the Rhombus brainstorming repo has been in zombie mode since October 2019. By which I mean: commits have all but stopped, and though discussions are still happening among community members, all five members of the Racket core team have essentially withdrawn from these conversations. See for yourself—one, two, three, four, five.
This tends to prove my earlier prediction that Racket lacked a sufficiently strong “procedural foundation” for navigating a project of this nature. Despite originally insisting “we do not want to do things the same way this time”, and announcing new & improved procedures, the Racket core team immediately fell back into old habits, retreating behind the shoulder-high hedgerow while expecting different results.
Though I was optimistic at the start, these days I view the Rhombus project a little differently, as one must in the face of accumulating evidence:
Personally, I have no interest in a non-parenthesized notation for Racket. (Excepting dialects like Scribble, which are intended for a different domain of use.) To me, the parentheses are more than just traditional: they visually explain important things about how the language works, and thus are as fundamental as lambda. The idea of “Scheme without parentheses” sounds like “math without numbers”—doable but obtuse.
So far the Rhombus project has defined itself largely in opposition to traditional parenthesized notation. + Maybe that wasn’t the intention. There are also deeper technical changes being considered. But that has been the outcome. But that’s not enough. It also has to distinguish itself from non-parenthesized languages with a lot of Lispy features, like JavaScript ES6 and Swift. What, exactly, is someone going to learn in Rhombus that they wouldn’t learn using one of those languages? And if the answer is “syntactic abstraction via macros”—that hasn’t been a big source of uptake for Racket to date. + JavaScript doesn’t have any macro-like capabilities. But Swift does, in the form of generics (which are completely different from Racket generics).
Most of all, I don’t understand whose interests the Racket core team hopes to serve with Rhombus. If it’s largely an intellectual itch that wants to be scratched, then they should just say so, and go off and do whatever they want. If it’s meant to attract a certain set of parenthesis-hating programmers, then some of these people should be brought forward, to prove that the set is not empty, and that the benefits will outweigh the costs.
For now, however, it’s being held out as a collaboration with the current user community (for whatever definition of that word). Meanwhile, the Racket core team is less interested than ever in supervising that community, and already seems bored by the effort of interacting with them on this project. If that remains so, the Rhombus project is destined to create frustration and disappointment on all sides.
By the way—since the Racket core team has never been hugely interested in engaging with its user community, one might ask: why is this team so eager to embark on an expensive technical project to enlarge that community? No idea.
One might also ask: if the Racket core team wants to enlarge its user community, why resort to an expensive technical project and not, say, scaling up cheaper techniques already known to work? No idea on that one either.
Since 2013, I have been successful—arguably more successful than anyone—bringing new people into Racket. That’s not to brag, but rather to point out that there is evidence available for those who wish to study it. And also to admit that even though I’m no longer a Racket contributor, I have my own myopia about these things. In any case, I wish the Racket core team and Racket community the best of luck with this project.
09 Aug 2019: First release.
12 Aug 2019: Added “if it were up to me” section.
19 Sept 2019: Added “about that working title” section.
03 Oct 2019: Rhombus update.
11–14 July 2021: Update.
Longtime Racket contributor Greg Hendershott has good points too.
Honu: A Syntactically Extensible Language: paper by Jon Rafkind and Matthew Flatt that describes how Racket macros would work in a notational environment without parentheses. This research would likely become the basis for infix notation in Racket.
Matthew Flatt’s Rhombus project plan from October 2019.