26 Programming Languages in 25 Days
matt.might.net
matt.might.net
By the time I get the kids in bed at night, I'm often out of steam. Sometimes I try to make some progress on a project, but I usually don't have the willpower to push through a stumbling block. After many many nights of staying up late and losing sleep trying to power through but not actually getting anything working, I finally realized it's better to just go to bed.
But I also feel sad if I go to bed early without making progress on something I'm excited about. So I started tricking myself by telling myself, "Well, you can just think about the project as you fall asleep." That's usually enough to get me in bed early.
And, lo and behold, quite often, I figure something out as I'm drifting off. Then when I wake up the next morning, I can get it implemented while I have my morning coffee. It's a really pleasant routine.
The goal was to see how similar code is, and how little it matters which language you pick.
Obviously it's a constrained problem set (we didn't have to learn all the ins and outs of each language) but it really opened our eyes to the "commonness" of programming, and free'd us from the tyranny of "I program in x".
I think this thinking is a mistake. If you learn languages superficially, you will end up writing the same code just with slightly different syntax. It can take a long time to really understand a language and ecosystem and use its capabilities.
But if those languages are C, APL, Erlang, ML and Lisp then I would expect the lesson would be the design space of languages is much larger than the popular imperative languages would have you believe.
On the other hand, differences will start to show them selves after you spend a while noodling with your script, refactoring it a couple of times and deliberately seeking out opportunities to use language-specific features in the process. This expands the exercise to something more like "a language a week" instead of "a language of day", which is obviously a bit more of a time commitment. But if you want to get value out of a "polyglot" programming exercise like this, I think that's what you really need to do. Otherwise I think you learn lessons that are only correct at surface level.
And Java didn't, until relatively recently (oh god Java 8 was almost 10 years ago), have anonymous functions, which means that you'd be more inclined to express solutions in terms of vulgar loops rather than a map, filter, reduce type operation.
Which is to say, they'd definitely look different.
Right, and you can implement a recursive function in Haskell, OCaml, or Scheme that looks more or less identical in all 3 languages, and is only a recursion-transformation away from the for-loop version seen in Python, Ruby, Java, etc. So all the functional recursion-based implementations will look similar, and all the imperative loop-based implementations will look similar, and the two classes of implementations will also have a lot of overarching similarity.
The basic pattern of "obtain system state, do thing, set up next system state, proceed to next thing" is the same. The differences between languages (read: sets of tools that you are given for expressing algorithms) tend not to become apparent until you've spent a little while working with them.
I can't speak specifically to Erlang because I haven't used it, but from what I've seen the story should be the same.
For example: If you're in a language that primarily uses recursion as the primary iteration mechanism, if you have to iterate through every element of a tree you will just about never do a breadth-first search unless it is absolutely necessary. It's just a pain to express recursively compared to a depth-first traversal. In contrast, in an iterative language, a breadth first traversal is the same (somewhat obnoxious) complexity as any other traversal. But that's assuming both languages would be traversing a tree at all: trees are vastly more likely to be used at all in languages where recursion is the norm.
Like, sure, any iterative function of the form:
f(x) = {
state = h(x)
cond = true
while(cond) do
state = j(x,state)
cond = k(x,state)
end
post_work = l(state,x)
return post_work
}
Can be re-written as f(x) = l(m(x,h(x)))
m(x,state) = state if k(x,state) else m(x,j(x,state))
But if your language only supports one or the other, you're going to approach the problem in fundamentally different ways. Whereas the iterative solution is likely to jump directly into the loop with a trivial h(), the functional language is far more likely to do more work in h() to offload work out of j() prior to what would likely end up being a fold operation.Put another way: for(i=0;i<x;i++) loops are common in iterative codebases I've worked on, but it's exceedingly rare to see f(x,i) = blah return f(g(x),i++) in a functional codebase.
I think that’s a pretty bad result of the exercise. The point of software isn’t just to do a thing. Good software should properly encode a domain or idea and communicate that to others.
If one took the analogy of driving a nail into wood, there are many tools that can do the job, but only a couple that properly handle the job. Because the goal isn’t to just drive the nail, it’s to do it efficiently and ergonomically and in a way easily communicable.
* Excluding some deliberately opaque languages like brainfuck and malbolge.
Anyone who's tried hammering a Java-shaped solution into an Haskell-shaped language will eventually see the folly.
I interview a lot of programmers and I often get told that one of my questions is just impossible because it’s slightly awkward to express in Java. (It’s only Java folk incidentally, even though it’s roughly equally awkward to express in most of the long list of languages we let candidates use.) By analogy these are folk that would have to sit around waiting for their hammer delivery rather than just make do with a mallet for a few minutes.
I agree with your point though. I remember being asked a question and I blanked with how to model it in Java. Then I switched mid interview to python and it clicked for me.
obligatory reference to Landin "The next 700 programming languages" (1966)
His story of pivoting from PL research to medical research (and being a star in the field) is quite motivating.
I missed blogging too, so I set a New Year’s resolution in January to write at least two blog posts this year. It had been over seven years since my last!
I still hadn’t written one by November, but now I’ve got three for the year.
I’m optimistic I can keep it up now.
[1] https://www.facebook.com/freethinksuperhuman/videos/15306506...
But it’s still very useful and I’m sure he learned a lot and absorbed of some of the new languages’ programming styles. You don’t master idiomatic functional programming from one week of writing Haskell, but it does introduce you to basic concepts like functors, lambdas and embedding computation (IO) in data.
Which isn't to say that you're wrong, but rather that the author is likely well aware of these particular shortcomings of the exercise. But then the exercise wasn't "write perfectly idiomatic code in a different language every day", but just "learn some languages I didn't know before".
From my personal experience of doing AoC in Julia this year, my Julia code started out smelling a lot like Python, but managed to adopt a bit more of the Julian way of doing things as I went along (not done yet though...)
This was the reference I used for TeX programming: https://pgfplots.sourceforge.net/TeX-programming-notes.pdf
100 languages in 100 days...
I likely wouldn't do this personally out of pure laziness but good on you!
I have a part two planned to comment more about the languages / days themselves.
This post was just getting too long to include it here.
In the end I lost the motivation once I only had the “regular” languages left. I was also solving them as quickly as possible (in Ruby) to get on the leaderboard so it was kinda boring to also solve them again later on.
The initial headline of your front page intrigued me because I had noticed in surveying my own institution (the one where I studied, both as an undergraduate and as a postgraduate, and where I now happen to work) that while most of the undergrad courses of study we offer that require mathematics include at least an opportunity to program, Medicine does not. I reasoned at the time that the Medics have to cram such a large amount of other material into their brief time that maybe there's just no room to teach them to write code if they are to sleep (in my country they certainly won't have time to sleep once they're junior doctors)
This year I used Python as my second language (still plan to finish) but with a strong emphasis on TDD and property-based testing since I'm already familiar, but not fluent, with Python.
0: https://www.reddit.com/r/adventofcode/comments/zwi0t4/2022_w...
Curious about this line if op is here.
But, I did once learn how to do template meta-programming:
https://matt.might.net/articles/c++-template-meta-programmin...
Write up on the whiteboard in various languages to echo "Ho Ho Ho", preferably in shorthand, one-liner if possible.
Like python would be
("Ho "*3).strip()Clojure and Rust were on their list of strong languages that they didn't end up needing:
> F#, Ocaml, Rust, Perl, Swift, Clojure, Smalltalk
Forth and APL were on the list of probably impractical languages:
> APL / J, Prolog, Forth, m4, COBOL, Fortran, Ada
For day 1, I ended up using a pretty different method than the Python code, mostly so I could use what I already knew or could quickly figure out, processing it character by character.
I wasn't planning to do more, but I realize the input for day 2 could be executed as Forth code simply by defining the words for what those input command should do, and then executing the input AS Forth, so it was actually a quick and easy one in Forth.
Forth would be a good one though. Both simple and different.
In which case Rust is a powerful tool to bring to AoC late on because you can afford to take a not-so-algorithmically clever approach and Rust's optimiser will save you.
Take day 16. The professor did it in Python, with which they have some experience. My Part II solution is pretty bad, it's a combinatorial explosion resulting from a search of the solution space with both the elephant and myself trying every option. But, I wrote it in Rust, so this bad solution finishes in five minutes. If I'd written this terrible solution in Python it may have taken hours to finish...
Yes, I'm willing to tutor a student to test my claim.
It took me a week from a cold start to get a working mergesort toy example working. By comparison, elixir took me 1.5 hours. 2 to make it multicore.
P.S. I'm somewhat surprised by this community's adoration of AoC and at the same time aversion to Leetcode and/or competitive programming in general. Arguably, many leetcode problems are more interesting (from an algorithmic point of view), are much shorter (although I guess for some, part of the fun of AoC is the elaborate story), and most importantly, have extensive test cases, that require generalized solutions.
The AoC isn't the blog post; the choice of using a different language every day is the blog post. Does that not seem even remotely interesting to you?
> I'm somewhat surprised by this community's adoration of AoC and at the same time aversion to Leetcode and/or competitive programming in general.
AoC is deliberately a game. It's spirited and fun. Leetcode is a by-product of an interviewing system that worked kind-of well at one company once upon a time, and then everybody decided they needed to do the same thing because that company had a Big Name, and now we have a broken interview process that is — in most practical respects — completely useless.
That's not to say some Leetcode problems aren't good or fun problems to work on, but the website itself was purpose-built to help people game a broken interview process (which has, incidentally, only made the process worse).
> > Hello world is different from solving actual problems in AoC.
> ...
> The AoC isn't the blog post; the choice of using a different language every day is the blog post
This thread started when someone suggested a similar learning project. Would "hello world in 100 languages" be worthy of a blog post?
> Does that not seem even remotely interesting to you?
It is mildly interesting, but in my opinion, not worth a blog post from anyone more experienced than a college student. I think the whole endeavor is silly. I think that learning the syntax of a language well enough to solve one day of AoC is a dubious achievement. You don't learn the language well enough (in my opinion that takes at least several weeks with the language), you don't even get a head start if you were to later start a project in that language, since you saved a few hours at best. The only thing you get, is to brag about it in a blog post. But who are you trying to impress?
> ... Leetcode ..., but the website itself was purpose-built to help people game a broken interview process
I used Leetcode as a generic name, but I don't mean just them. There's lots of platforms that were build around competitive programming, (starting with Topcoder, Codeforces and many others). Everyone is excited about AoC, but very few people spend time on those other platforms for fun.
> AoC is deliberately a game. It's spirited and fun.
Competitive programming problems are just as fun if not more so. Yet not many people here solve these type of problems for fun. Nobody would write the "25 algorithmic problems in 25 days" blog post. In my opinion, most people are excited about AoC because those problems are not too difficult, and anyone can solve a few problems at the start.
Yeah. Because a blog post is just an outlet for somebody to write. There's no minimum benchmark that needs to be met to be "worthy" of writing a blog post. What a stupid way to look at the world.
> It is mildly interesting, but in my opinion, not worth a blog post from anyone more experienced than a college student.
Again with the worthiness. I have a suggestion: if posts like this are uninteresting to you... don't engage with them?
> I think that learning the syntax of a language well enough to solve one day of AoC is a dubious achievement. You don't learn the language well enough (in my opinion that takes at least several weeks with the language), you don't even get a head start if you were to later start a project in that language, since you saved a few hours at best. The only thing you get, is to brag about it in a blog post. But who are you trying to impress?
So what I'm learning here is that you not only have a terrible outlook on the concept of blog posts in general, but you didn't even actually read the blog post at hand.
The post isn't about the syntax of languages, nor is it about the author's efforts to learn the languages whatsoever. It's about his high-level approaches for planning to solve a known set of problems using a variety of languages. The specifics of the individual languages are unimportant for this sort of post.
I also think it's weird that you think this sort of thing requires a target audience to be "impressed". Again, I think you have a wholly terrible outlook on what blogs are for. People read Matt's blog for his perspective on things. He doesn't need to "impress" anybody, nor is he trying to.
> There's lots of platforms that were build around competitive programming, (starting with Topcoder, Codeforces and many others). Everyone is excited about AoC, but very few people spend time on those other platforms for fun.
Again, an advent calendar is a regular event that many people participate in for fun. The scope of the challenge is well-known in advance, it's a long-but-not-too-long commitment (25 days), and it's a cultural thing to take part in with other people. It also doesn't focus on optimization; it's just whether you solve the problem. Advent of Code also has their leaderboard feature such that individual communities can run their own AoC competitions, which maybe encourages some people to participate (but also does not alienate those who don't wish to compete against other people, since they can just choose to do AoC on their own).
Competitive programming tends to focus on optimization, requires a lot more study and effort, does not occur as part of a regular cultural phenomenon, and so on. They're wholly different endeavors. I don't think there's any mystery to it at all.
> Competitive programming problems are just as fun if not more so.
To you. Some people like that AoC is simple. It gives them something to do. It's like having a one-a-day sudoku calendar on your desk.
> Nobody would write the "25 algorithmic problems in 25 days" blog post.
I don't see why they wouldn't. I think that would be an interesting post. If you're so into competitive programming, why not be the person to write such a post? Or do you only complain about other people's creative endeavors without contributing your own?
> In my opinion, most people are excited about AoC because those problems are not too difficult, and anyone can solve a few problems at the start.
What's interesting to me about the way you've phrased this is that you're talking about enjoying not-too-difficult problems like it's an inherently bad thing. I think this says a lot about you.