Full Disclosure I created the post but it got more traction than I was expecting. I think some of the grievances about syntax definitely lend more credibility to the Rhombus project. I'd be curious to see what those people thing of the proposed syntaxes. Some of the critiques appear to be misunderstandings about the language itself, and some are genuine shortcomings. I don't feel experienced enough to respond to some of the comments so I would be happy if others would chime in. Also nice to see some new people learning about Racket
I don't have a Reddit, but someone should reply to https://www.reddit.com/r/ProgrammingLanguages/comments/sr9k8g/comment/hws72mt/?utm_source=share&utm_medium=web2x&context=3 with urlang, no?
I think the commenter is actually implicitly saying that Racket libs are not mature enough. There were many clearly erroneous takes on the topic. I am quite surprised by all the negativity surrounding the Racket community, that I find very much unjustified.
Clearly I'm but a programming ant compared to some of the guys speaking on the Reddit thread but IMO, Racket is the most dynamic PL community regarding new concepts in CS. But for some reason, people are completely focused on implementation techniques instead of intellectual curiosity. I also find it interesting that the most recognizable names (DonaldPShimoda, and Athas of Futhark fame) are the most nuanced and interesting opinions of the thread.
That whole thread seems to boil down to a handful of responses:
- I wasn't aware of Racket.
- I wanted to do everything myself because (that's part of the fun) or (because I believe Racket does not provide [essential thing X]).
- I don't like Lisp syntax.
- I don't want to learn new things.
[essential thing X] seems to be one or more of:
B. Type checking
C. Easy integration with/compilation to [other language or VM]
Not all of the claims about missing elements are accurate.
EDIT: Argh. Don't use angle brackets.
I personally would add:
While I love racket (maybe not unconditionally) that is one of the issues, I personally have with it currently — if I do everything myself — I can get my personal distribution of lang x to way lower size.
But in a way that is mostly, because it will do way less than racket is able to do and thus it is easier for it to be small.
With special builds or potentially building specialized racket distributions that also may be possible to get a lot smaller, but I think this is currently not necessarily easy to do, if you want super tiny, you probably need to spend quite a bit of time tweaking things.
And currently I understand wanting to start from nothing, because starting from racket and ending up with almost nothing seems very time consuming. (But I could be wrong, maybe demodularization / exe building and some custom optimizations could get you a long way. The source distribution would still be big.)
I think there is also still a big potential for creating
#langs that aren't rooted in
racket/base but lower level than that. I don't remember which talk exactly, but in one of the racket talks there was also mentioned the idea of essentially creating langs that are closer to the hardware.
[That then eventually could also be used to implement racket, maybe even chez-scheme could be
#lang-ified, although I am unsure that would make things easier to understand currently]
If we had lower level langs (and for example also some that can be used without garbage collection) that may make racket more attractive for e.g. game development.
Also one of the comments pointed out roc-lang, which seems pretty early in development, but has an interesting approach. I watched Roc Lang.
A short summary (from what I remember) could be:
- purely functional
- managed memory
- reference counting without ways to construct reference cycles
- arena allocation
- automatic optimization that introduces mutation where it is safe to do so, to improve performance
- platform implementer / user concept
While I think there are a lot of cases where racket could be used and isn't out of ignorance, we have to be careful not to make the opposite mistake, where racket isn't used for valid reasons, but we dismiss those out of ignorance.
Personally I think a language should defend its validity, but not past what it delivers in practical use with reasonable effort and learning.
Concretely I would say, racket has a problem here, it is way more powerful and able, then it can communicate in a reasonable amount of time. To the point where, after years of using it, I still feel like an idiot sometimes, not knowing whether there is something I could use to do something easier.
So I would say that the vastness of possibilities in racket are a strength, but also a weakness,
because when there is more to learn, it is harder to master.
I think that is one of the points about racket, with tiny languages you get a quick feeling of "I know what I am doing and what I can do with it", with racket you find a new section in the documentation and feel like a beginner again. I think this deters some users, while it attracts others.
When you don't want to build languages it may deter you, if you want to, it may invite you.
I think this aspect that for a lot of people "racket seems like just to much trouble and not worth it" should not be "shrugged off" with "they haven't understood racket".
Maybe we haven't understood how to present a subset of what can be done with racket,
in a way that is attractive to that group of users.
I could have guessed some of the complaints, but I was surprised about how many people didn’t understand that the #lang could do more than DSLs and simple surface syntax changes.
But part of the goal was getting more people to talk about and discover Racket, and with the amount of people and comments the post got I’d say it accomplished that goal.
I agree. It is definitely a big ask to say “Hey if you want a great platform to develop languages we have it, but you have to learn an entirely new programming language first before you can use it”
I think we can overcome this barrier by making cool stuff that attracts people too the language. As some of the comments have shown, it doesn’t matter how ergonomic a language is if people have never heard of it.
Can you give some examples of what these other things are?
These are some of the quotes that jumped out to me.
If all you want is alternative syntax for Racket programs, then use the #lang system.
Racket's maybe useful for a first prototype, but not more than that.
Well, Racket's languages aren't that great at implementing full scale programming languages. They're much better for (more or less) simple DSLs that can be directly used from Racket (as in #lang racket) code.
Specifically, the ability to write powerful type systems in Racket is... not great. IIRC, static type systems have to be implemented as Macros, which is not exactly ideal, especially if you could instead just directly write a typechecker in, say, Haskell or OCaml with much less effort.
The real bottom line reason I can pass on besides pure preference is that things like Racket's language tools always feel to me more like tools for implementing DSLs or other similar mini languages you would use alongside Racket. I don't want to be alongside Racket. I want to make my own thing, which can stand alone
I think the responses in that thread made some good points on the topic of lower-level languages. I wish it was easier to implement a
#lang that ran on a different VM from the traditional Racket VM, so it could have a lot more control over low-level details like memory management and calling conventions. Perhaps it would be possible if modules could expand into LLVM IR somehow?
I just want somebody to implement
#lang rust already.
Isn’t targeting low level a use-case for GitHub - rjnw/sham: A DSL for runtime code generation in racket ?
I think the repo mentions LLVM as a possible target?
Sham reminds me a little bit of python's Numba. With Numba you just add little annotations to the original code. I think if you just want something that is easy to use to speed up some numeric computation function, that is an advantage over Sham.
Sham on the other hand seems to give you an actual low-level language that you use to write your function giving you more control, so it may be a bit more work, but I think the additional choice and control over what you get as a result is Sham's upside.
Sham is a more general tool that can be used to implement many different DSLs, so it makes sense that it has to be more explicit. Probably Sham could also be used to implement a racket language that sometimes uses sham where it can automatically deduce that it would be beneficial (or easy to do so) and use racket in other cases, with such an language it could probably become as easy as Numba.
define-ast is very interesting and goes way beyond what Numba offers.
The paper built an automata language, that reminded me of what I read on ripgrep's page:
Summarizing, ripgrep is fast because:
- It is built on top of Rust's regex engine. Rust's regex engine uses finite automata, SIMD and aggressive literal optimizations to make searching very fast. (PCRE2 support can be opted into with the
- Rust's regex library maintains performance with full Unicode support by building UTF-8 decoding directly into its deterministic finite automaton engine.
- It supports searching with either memory maps or by searching incrementally with an intermediate buffer. The former is better for single files and the latter is better for large directories. ripgrep chooses the best searching strategy for you automatically.
So using Sham to implement rackets regexp could be an interesting research project, I wonder what the benchmarks would show. But I also don't know a lot about the current implementation.
Overall I only had a quick look at the paper, so I don't really know how everything works out in practice.
I think with Sham I would be more likely to use llvm (indirectly).
Yeah, that was really disappointing. One commenter mentioned how macro systems aren't great for implementing type systems and didn't seem to realize that Typed Racket doesn't actually do that. Turnstile is great, but it certainly isn't the only way to do types.
One more valid point was that Racket's contract system can't enforce certain properties when calling into dynamic code such as linear types. Racket always allows you to take create another reference to something.
I think a lot of people are overselling those ecosystems and are underselling Racket's ecosystem. It's important to consider when evaluating a library how difficult it is to implement the functionality provided by said library. Most of Apache Commons isn't that hard to implement, it's just a nice to have. On the other hand, good luck implementing Rosette or Redex from scratch.
A post was split to a new topic: Flowchart that shows outsiders all the options in the racket ecosystem