Posts tagged rant
Clojure is an ugly, sloppy hack on top of Java that should shame anyone who has ever written a lisp interpreter in any language. The core code is sloppy and unprofessional, the leaky abstraction of the stacktrace would get you failed in any compiler course. I mean it. There are weekend hacks of scheme compilers inside Java that do not expose the implementation so blatantly. It’s one thing to do so to push out something as fast as possible, but to almost a decade later still not see that sloppiness as a problem is inexcusable. Here’s Peter Norvig’s implementation of Scheme in Java. Notice how he took pride in his work.
Clojure is lisp for people who literally do not know what a lisp is supposed to be like. It’s as much a failure as Arc, except that arc would have passed a freshman CS course. Arc still shows better attention to implementation detail than Clojure.
Clojure: what a Java person’s idea of a lisp is.
Clojure is an abomination, and that is probably why it’ll surpass all common lisps combined. It’s the php of lisps. If you’re a teen, you should probably learn Clojure for the same reason your parents learned php. And when you get older, you’ll be able to laugh and cringe at how much needlessly sloppy, krufty bullshit you had thought was perfectly normal. Clojure: php for people who think they’re better than php programmers.
Now consider all the amazing lispy stuff being done in Clojure by future Elixir devs. Because it’s a lisp, even a shitty one, they are able to do incredible things which absolutely terrify their counterparts who arrived in Clojure from Java. That is a testament to lisp, that even in such a bad lisp people can do incredibly productive, cool things. All of these people will eventually leave Clojure and find a better lisp, and leave behind warehouses of interesting, mindbending lispy code that half of clojurians will regard with religious terror, like powerful magical artifacts. Those on the other end of the spectrum will leave for a more boss-friendly language and dev environment like Go. What will be left, the eternal core of Clojure, will be people who are content with using a bad lisp. The goldilocks programmer, stuck in the middle, who simply puts up with the glaring warts and unfinished, sharp edges. Who shrugs while pounding a nail using a garden gnome instead of a hammer, but accepts that it’s better than whatever they’d be doing in Go or such.
The goldilocks Clojure programmer is one for whom Clojure is their first functional language, first serious use of lisp outside of a hobby since college, and who has suffered through a boss-friendly language for a bit before arriving in Clojure. This person doesn’t know what normal functional languages or lisps or like, but does know what the lack of Java is like. Unfortunately, they’ve normalized Java enough that they don’t notice how much squirts out of their code. This person will stay, outlasting the lisp weenies who arrive in a shower of happy parentheses and leave just as suddenly. This person will stay, outlasting their colleagues who spent more time in cubicle hell than they did, and who retreat to a more corporate language. This person will not have any sufficient motivation to fix either the errors the lisp weenies see, or the errors the Java people see.
Clojure is, almost by design, guaranteed to experience evaporative cooling from both ends of the political spectrum of coding. It’s an alt-center language, it’s that weird guy who claims to be both an anarchist and a Moldbugian. It’s a gloriously failed lisp that will almost certainly expose more people to lisp than any other dialect has. Just like php exposed an entire generation to their first, terrible, programming language.
I use Crouton on a chromebook. Clojure is a pain in the ass on low-end devices. Just annoying as hell, easily hogs all cycles. Lein spins up its own jvm, which adds to the startup time. On a low-end device, you’re gonna spin it down in order to such as watch a youtube video, so you really will not have long enough lein sessions to justify such a slow startup. On a heftier box, you don’t have to juggle things like that.
The stacktraces, holy shit. I hate Java. Every time I see 100+ lines of java vomitspit I see clojure telling me that it is not a real lisp, that it fundamentally will never understand concurrency, and that it does not intend to follow the Lisp Main Sequence.
The Lisp Main Sequence: All lisps inevitably try to consume their own stack. The normal evolution of a lisp is to ruthlessly divorce itself from its implementation, and become pure lisp. Lisps are like facehuggers. Every normal lisp wants to be lisp all the way down. This isn’t a technical thing, it’s social. Lisp hackers want to be able to hack lisp all the way down to the silicon. It’s engrained into the mindset. Lisp is meant to take over all that it sees, drive its enemies before them, etc. Deep down, even the smallest lisp wants to grow up to be a Genera lisp machine.
The mindset of clojure devs, meanwhile, is not the normal lisp mindset. After almost a decade, they have not taken over the stack. In any normal lisp, a year is sufficient. Clojure devs do not think like normal lispers; something is missing in their personalities. It’s downright unsettling to think that for almost a decade clojure hackers have dealt with java regurgitating at them in every stacktrace and put up with it instead of fixing it by replacing it with more clojure. It’s disturbing to think of the sheer volume of java vomitspit they have dealt with over the years as something that is perfectly normal in a lisp. It points to a fundamental defect, an inability to really grok lisp. It’s lisp for pointy-haired bosses. It’s lisp for people who wear ties. Horrifying.
Clojure seems to be at odds with its users. Half are from java, and don’t see anything wrong with java being spat at them. Half are from lisps, and inevitably try to hack their own mutually incompatible solution. The result is that there will never be a single, united front behind which the pre-gamed lispers can rally persuasively enough to get its benevolent dictator for life to adopt. The result is an incredible inertia compared to most other lisps. The userbase may grow, the number of libraries written in clojure may grow, but fundamentally it will not embrace the main sequence of lisp evolution.
Parodoxically, the inherent expressiveness of clojure (it is still a lisp after all), guarantees that a fuckload of effort will go toward scratching personal itches. New libraries and build tools will appear overnight, because in lisps they can appear overnight. But each must beat not only the java, but the other lisp itch-scratching. This will result in dissatisfied lispers bleeding out of the community in search of a lispier lisp. Before they leave, however, they’ll have produced so much sheer output in attempting to scratch their itches that the vast space of options will terrify the java faction. The java faction will similarly bleed off, in search of a more ordered and boss-friendly language.
Who remains? Those who are comfortable with java spewing shit at them, and who are not sufficiently lispy to attempt to hack up a solution in a weekend. Those who for whatever reason are at the borderline between the two mutually-exclusive poles of clojure’s community. In Yegge’s political spectrum of programming languages, clojure is that weird dude who appeals to both anarchists and the alt-right.
I see clojure increasing in popularity, but I don’t see it changing its fundamentally divided nature. It’ll have upswings in popularity, but it’ll be continually bleeding from both ends. This hemorrhaging may not kill it, but it guarantees inertia. The java people will bleed off into Go or something, the lisp freaks will bleed off into Elixir or something, and the core clojure community will remain just as eventually dissatisfying to both.
Note: I am still interested in clojure, despite these annoyances.
Git Koans don’t really exist. I can’t be arsed to make it, though. There are some anecdotes called Git Koans, but as far as I can tell there is nothing similar to Clojure/Ruby Koans where you get hands-on experience fixing things incrementally, from tiny mistakes all the way up the ladder.
Basically: “Here’s broken shit. Fix it.” “Yay, you fixed it. Here’s more broken shit. Fix it.” Turn on continuous integration and use post-commit hooks as the koan runner. Eventually, you fix all the problems in the broken repo.
It actually wouldn’t be very hard. You can pretty much use any kind of make system to build a repo then fuck it up per order. The result would be hands-on experience fixing fuckups in git, from small to huge. Hell: a joker shell script that takes all the commands used to evolve a repo, and randomly inserts typos and wrong commands to fuck it up (Maybe just swap the entered command with one which is often accidentally typed instead). “Here’s a fork of Foo that’s been utterly fucked. Walk through its history and unfuck it.”
You could also do local/remote fuckups pretty easily too. Have a shell script that purposely messes up upstream/downstream relations, purposely screws up a merge, etc. Nightmare mode: multiple remotes are created, each randomly screwed up to simulate others trying, unsuccessfully, to fix their own messed up repos.
As far as I can tell, this doesn’t exist. The only time you’re ever fixing a fuckup is in actual goddamn repos during your job. The only time you will ever unfuck an arbitrarily broken repo is when your ass depends on it.
This means that for most people, git is a cargo cult. You don’t know how to unfuck things, you’re doing shit like cp -R repo repo.old. Imagine if you wrote code this way: the only time you ever fix bugs is in production code. The only time you ever fix a bug is when your ass is on the line. You’d also do cargo cult bullshit. You’d be that happy asshole sloppily commenting out lines of code to see what’s wrong. In $Lang the Hard Way style tutorials, it’s heavily emphasized that you should break stuff in order to learn what happens, and how to fix it when you do inevitably do it by accident. Yet, I would put money on the bet that the vast majority of git users have never purposely broken a repo in order to learn how to fix it. How many purposely messed up a commit or 3 in order to get hands-on experience with git reflog? How many intentionally committed to the wrong branch so they could learn how to stash pop. How many purposely introduced a painful merge conflict in order to learn the right (painless) way to resolve it? Purposely broke the build in order to learn how to use bisect?
In code, it’s unthinkable that you would have no experience of fixing bugs outside of “we need this fixed yesterday” situations. Yet with git, that’s the case. No experience, at all, of unfucking repos that you don’t depend on for rent or whatever. The average git user has no idea how to fix mistakes they make, and every mistake they do have to fix is only ever on a real repo.
Look at Oh Shit Git. It lists very common mistakes, in plain English, and explains how to fix them. I guarantee that the vast majority of git users have never purposely made those mistakes in order to see how to fix them. For many, the first time they have to fix a mistake, that mistake is new to them and they end up on ohshitgit or stackoverflow typing commands that may as well be mystic incantations.