Racket gets in your head like nothing else. Once you learn it, (Scheme does this too) you get x-ray vision to see every other language modulo syntax.
I have been writing Elixir professionally for the bulk of my career. (It’s been pretty awesome!) Despite this, I consider Racket to be my native language because it’s so easy for me to think in Racket. It’s the perfect bridge between my brain and the problem domain.
I have spent a lot of time in the PL space and I just cannot wrap my head around the love of Racket. I absolutely love the innovation that comes out of the community though! The gradual types system work, nanopass, embeddable DSLs are all fabulous so I like to keep tabs on what they are cooking up.
I recently picked up Essentials of Compilation by Jeremy Siek, perhaps his book and lectures will make something click for me.
In the meantime Julia has been my happy medium for a “lisp”.
Racket is used across CS programs that have adopted the How to Design Programs book [1] (some schools do not use the original book, just the textbook for source material).
I was just remembering https://htdp.org fondly yesterday. Working through that book was one of the most wonderful and transformative experiences I've had in programming. I owe so much of my problem solving skills today to that book.
It's an incredible curriculum. I have a lot of fond memories myself. I frequently wonder nowadays if it isn't the right approach to force students to stop and think a bit more about "Computer Science" and not just "Programming" in an introductory context.
I was a few years into amateur self-teaching at that time. It helped me think through problems recursively, which was a lot of fun, but my biggest takeaway was learning to think of problems by representing the data with types, then stubbing out functions that dealt with the different types that I needed to solve the problem. Although it's done with an untyped language, it makes you think through the type signatures of all the functions you write. I discovered that whenever something didn't work, the problem was almost always that I misunderstood the data or the type. I also learned how to deal with problems with recursive algorithms through trees and nested data structures like s-expressions. That opened up a whole world of parsing and evaluating.
HtDP is an introductory textbook. It shouldn’t have new material for someone who has 2 years worth of experience.
That said, while I didn’t learn content from it, the exposition of their process was excellent. It really influenced my “personal software process” a lot. Also, it gave me a lot of tools for informal postmortems that I reach for when mentoring junior colleagues.
The book’s taxonomy of the different kinds of recursion helped me see what others found difficult about it.
Background: I liked SICP but HtDP made it easier to see the content as one unified subject instead of a bunch of tricky/interesting individual exercises.
I’m thankful for Racket - it got me regularly programming in lisp by virtue of LeetCode accepting it as one of its languages.
I did start to feel Racket’s “wordiness” towards the end - it started to feel a bit like COBOL. I’ve since moved onto Clojure and really appreciate the shorter keywords/function names/fewer parenthesis.
I still miss for/fold though - that thing is an absolute machine.
Racket is an amazing language for prototyping ideas that you don't understand yet.
At $dayjob I'm using it to test what novel geometries of deep learning models would look like. Being able to redefine any part of the stack for any reason is a superpower you don't know you need until you do.
A great place to start is the little learner which holds your hand until you get opinionated about what the underlying primitives should look like. E.g. what if we used sparse tensor representation?
That sounds kind of amazing. But you're not actually doing the machine learning in Racket, are you? Is your Racket code generating other code like PyTorch?
This is a complete tangent, but since you mentioned MNIST: I accidentally discovered Tsetlin machines this week when someone on r/Julia asked if anyone with an AMD GPU could run the benchmark in their package called Tsetlin.jl. I've got an AMD GPU so I was happy to oblige. Then I looked at what the benchmark was doing: it was training an MNIST classifier to 98% accuracy in 9 seconds - that seemed like a couple of orders of magnitude too fast. I was flabbergasted and wondered what the heck this thing was and that's when I learned about Tsetlin machines. I went on (with the help of Claude) to implement one in an FPGA and again was flabbergasted when it only took 2k LUTs to implement a Tsetlin machine for MNIST classification in hardware.
Well yes, you have to use one of the newer mnist variants these days if you want to get anything meaningful. A linear classifier gets something like 87% on the original one.
> I don't even know what vector addition should look like.
I think you're trying to imply you're inventing something new and racket enables you to explore... But what I read (as someone with a PhD in deep learning that has worked on sparsity) is you actually don't know the prior art and you're using racket as an excuse to reinvent a whole bunch of stuff that already exists in plenty of mature libraries in more mundane languages (including python/pytorch). Which is of course fine for personal growth but please don't oversell racket as a "superpower" - to wit I can manipulate any part of my stack too because it's all written in cpp.
>Unlike their binary counterparts, posits and takums, tekums simultaneously accommodate both ∞ and NaR, while retaining the simplicity of negation by flipping the underlying trit string. Perhaps most strikingly, tekums enable rounding by truncation, a property that eradicates at a stroke some notorious problems of rounding in binary arithmetic: double rounding errors, cascading carries in hardware, and the attendant inefficiencies.
You do realise that you need to store arbitrary binary blobs which don't nicely align to memory words?
And that once you can store them you need to write custom functions that do bitwise manipulation on those arbitrary blocks of memory?
The stuff that's done in hardware for you on all binary fp?
Meanwhile in racket I got arbitrary balanced ternary manista and exponent precision in less time it took to write this post. Something that not available in C/Cpp even for binary fp?
> You do realise that you need to store arbitrary binary blobs which don't nicely align to memory words?
And that once you can store them you need to write custom functions that do bitwise manipulation on those arbitrary blocks of memory?
Yes what part of my response to you gave you the impression that I did not?
> Meanwhile in racket I got arbitrary balanced ternary manista and exponent precision in less time it took to write this post.
Your claim was that it could not be done in cpp, not that it was faster/simpler/whatever-new-goalpost-you're-now-presenting in racket.
> less time it took to write this post
An interpreted language with a runtime and a GC is easier to use than a systems language? I think this novel discovery is worth a turing award indeed! I'll be sure to refer you for one. Maybe even an honorary doctorate at my alma mater.
I used a predecessor of this almost thirty years ago to learn Scheme and work trough the book SICP. The Racket maintainers still ship updates and new features, that’s remarkable.
Scheme is a wonderful lisp dialect. It taught me basics of functional programming, about closures, about tail call recursion, about functions always returning values (which annoyed me a lot when I started learning Python, where .append or .sort returened `none` instead of the list, and were destructive).
So I have very fond memories of Racket (then DrScheme) and Scheme. Had also written my matrix multiplication library and my CAS system to mimic the functionality of my HP28s calculator.
Racket is cool, has nice features, simpler than Common Lisp and comes with an editor which is nice. I'm always somewhat jealous and want to use it.
But it's really hard to give up the raw power of Common Lisp and ability to write low-level code. Even if the language and tooling is all more complicated.
See https://blog.racket-lang.org/2026/05/racket-v9-2.html for the release announcement and highlights.
If you are using rackup you can upgrade with `rackup upgrade`
Don’t forget to migrate your packages with raco pkg migrate 9.1
I have been writing Elixir professionally for the bulk of my career. (It’s been pretty awesome!) Despite this, I consider Racket to be my native language because it’s so easy for me to think in Racket. It’s the perfect bridge between my brain and the problem domain.
I recently picked up Essentials of Compilation by Jeremy Siek, perhaps his book and lectures will make something click for me.
In the meantime Julia has been my happy medium for a “lisp”.
It was the first mainstream attempt to an ALGOL style Lisp.
https://opendylan.org/documentation/index.html
Pity it didn't went down well at Apple.
[1] https://en.wikipedia.org/wiki/How_to_Design_Programs
That said, while I didn’t learn content from it, the exposition of their process was excellent. It really influenced my “personal software process” a lot. Also, it gave me a lot of tools for informal postmortems that I reach for when mentoring junior colleagues.
The book’s taxonomy of the different kinds of recursion helped me see what others found difficult about it.
Background: I liked SICP but HtDP made it easier to see the content as one unified subject instead of a bunch of tricky/interesting individual exercises.
I did start to feel Racket’s “wordiness” towards the end - it started to feel a bit like COBOL. I’ve since moved onto Clojure and really appreciate the shorter keywords/function names/fewer parenthesis.
I still miss for/fold though - that thing is an absolute machine.
At $dayjob I'm using it to test what novel geometries of deep learning models would look like. Being able to redefine any part of the stack for any reason is a superpower you don't know you need until you do.
A great place to start is the little learner which holds your hand until you get opinionated about what the underlying primitives should look like. E.g. what if we used sparse tensor representation?
https://scottlocklin.wordpress.com/2024/11/19/lush-my-favori...
As such pretty much all numerical optimisations are useless for my work. Racket however chugs along happily, if slowly.
That mnist takes 30 minutes per epoch isn't a worry when I don't even know what vector addition should look like.
I think you're trying to imply you're inventing something new and racket enables you to explore... But what I read (as someone with a PhD in deep learning that has worked on sparsity) is you actually don't know the prior art and you're using racket as an excuse to reinvent a whole bunch of stuff that already exists in plenty of mature libraries in more mundane languages (including python/pytorch). Which is of course fine for personal growth but please don't oversell racket as a "superpower" - to wit I can manipulate any part of my stack too because it's all written in cpp.
It took me 20 minutes.
Tell me how you'd do that in cpp?
https://github.com/ggml-org/llama.cpp/discussions/15095
>Unlike their binary counterparts, posits and takums, tekums simultaneously accommodate both ∞ and NaR, while retaining the simplicity of negation by flipping the underlying trit string. Perhaps most strikingly, tekums enable rounding by truncation, a property that eradicates at a stroke some notorious problems of rounding in binary arithmetic: double rounding errors, cascading carries in hardware, and the attendant inefficiencies.
Yes I can read very well - can you?
> ... by storing them in the corresponding uint
And that once you can store them you need to write custom functions that do bitwise manipulation on those arbitrary blocks of memory?
The stuff that's done in hardware for you on all binary fp?
Meanwhile in racket I got arbitrary balanced ternary manista and exponent precision in less time it took to write this post. Something that not available in C/Cpp even for binary fp?
Yes what part of my response to you gave you the impression that I did not?
> Meanwhile in racket I got arbitrary balanced ternary manista and exponent precision in less time it took to write this post.
Your claim was that it could not be done in cpp, not that it was faster/simpler/whatever-new-goalpost-you're-now-presenting in racket.
> less time it took to write this post
An interpreted language with a runtime and a GC is easier to use than a systems language? I think this novel discovery is worth a turing award indeed! I'll be sure to refer you for one. Maybe even an honorary doctorate at my alma mater.
You need to reread the reply they made. They asked how you would do it in cpp, not that it’s not possible.
> I think this novel discovery is worth a turing award indeed! I'll be sure to refer you for one. Maybe even an honorary doctorate at my alma mater.
You could have made your point sufficiently without being condescending.
Scheme is a wonderful lisp dialect. It taught me basics of functional programming, about closures, about tail call recursion, about functions always returning values (which annoyed me a lot when I started learning Python, where .append or .sort returened `none` instead of the list, and were destructive).
So I have very fond memories of Racket (then DrScheme) and Scheme. Had also written my matrix multiplication library and my CAS system to mimic the functionality of my HP28s calculator.
Have to look into it again.
But it's really hard to give up the raw power of Common Lisp and ability to write low-level code. Even if the language and tooling is all more complicated.