1. 38
  1.  

  2. 31

    It’s odd to see C described as boring. How can it be boring if you’re constantly navigating a minefield and a single misstep could cause the whole thing to explode? Writing C should be exhilarating, like shoplifting or driving a motorcycle fast on a crowded freeway.

    1. 17

      Hush! We don’t need more reasons for impressionable youngsters to start experimenting with C.

      1. 10

        Something can be boring while still be trying to kill you. One example is described in Things I Won’t Work With.

        1. 1

          ‘Boring’ is I suspect the author’s wording for ‘I approve of this language based on my experiences’.

          1. 10

            I suspect “boring” is used to describe established languages whose strengths and weaknesses are well known. These are languages you don’t spend any “weirdness points” for picking.

            1. 5

              Normally I’d lean towards this interpretation, but I’ve read many other posts by this author and he strikes me as being more thoughtful than that. Perhaps a momentary lapse in judgement; happens to everyone I suppose.

              1. 4

                ‘Boring’ is I suspect the author’s wording for ‘I approve of this language based on my experiences’.

                I’m curious if you read the post, and if so, how you got that impression when I said things like “it feels much nicer to use an interesting language (like F#)”, “I still love F#”, etc.

                Thanks for the feedback.

                1. 4

                  I found your article pretty full of non-sequiturs and contradictions, actually.

                  boring languages are widely panned. … One thing I find interesting is that, in personal conversations with people, the vast majority of experienced developers I know think that most mainstream langauges are basically fine,

                  Are they widely panned or are they basically fine?

                  But when I’m doing interesting work, the boilerplate is a rounding error and I don’t mind using a boring language like Java, even if that means a huge fraction of the code I’m writing is boilerplate.

                  Is it a rounding error or is it a huge fraction? Once the code has been written down, it doesn’t matter how much effort it was to mentally wrestle with the problem. That was a one-time effort, you don’t optimize for that. The only thing that matters is clearly communicating the code to readers. And if it’s full of boilerplate, that is not great for communication. I want to optimize for clear, succinct communication.

                  Of course, neither people who are loud on the internet nor people I personally know are representative samples of programmers, but I still find it interesting.

                  I’m fairly sure, based on this, that you are just commenting based on your own experiences, and are not claiming to have an unbiased sample?

                  To me it basically seems that your argument is, ‘the languages which should be used are the ones which are already used’. The same argument was used against C, C++, Java, Python, and every other boring language you can think of.

                  1. 3

                    Are they widely panned or are they basically fine?

                    I think the point is that the people who spend a lot of time panning boring languages (and advocating their favourite “interesting” one) are not representative of “experienced developers”. They’re just very loud and have an axe to grind.

                    1. 1

                      Having a tough time reconciling this notion that a narrow section of loudmouths criticize ‘boring languages’, against ‘widely panned’, which to me means ‘by a wide or significant section’.

                      But it’s really quite interesting how the experienced programmers who like ‘boring languages’ are the ones being highlighted here. It begs the question, what about the experienced programmers who don’t? Are they just not experienced enough? Sounds like an unquestionable dogma to me. If you don’t like the boring languages in the list, you’re just not experienced enough to realize that languages ultimately don’t matter.

                      Another interesting thing, some essential languages of the past few decades are simply not in this list. E.g. SQL, JavaScript, shell. Want to use a relational database, make interactive web pages, or just bash out a quick script? Sorry, can’t, not boring enough 😉

                      Of course that’s a silly argument. The point is to use the right tool for the job. Sometimes that’s a low-level real-time stuff that needs C, sometimes it’s safety-critical high-perf stuff that needs Ada or Rust, sometimes you need a performant language with good domain modelling and safety properties like OCaml or F#. Having approved lists of ‘boring languages’ is a silly situation to get into.

                      1. 2

                        To be honest, I don’t really see why that’s hard to reconcile at all. Take an extreme example:

                        Let’s say programming language X is used for the vast majority of real world software development. Through some strange mechanism (doesn’t matter), programmers who write language X never proselytize programming languages on the Internet. Meanwhile, among the set of people who do, they almost always have nasty things to say about X. So, all the articles you can find on the general topic are at least critical of X, and a lot of them are specifically about how X is the devil.

                        Is saying that X is “widely panned” accurate? Yes.

                        Of course that’s a silly argument.

                        Yes it is.

                        The point is to use the right tool for the job.

                        Indeed.

            2. 20

              But when I’m doing interesting work, the boilerplate is a rounding error and I don’t mind using a boring language like Java, even if that means a huge fraction of the code I’m writing is boilerplate.

              That’s interesting, I would expect it exactly the other way around. History is full of examples where people first prototyped something in some high level language and then, once the design had solidified, rewrote it in C or Java or something like that for performance or interoperability reasons. I’ve prototyped algorithms myself in Scheme before transcribing it into PHP (which was the language we were using for $BIG_PROJECT at work). And at university, in my assembly course I would routinely write something in C and then convert it into assembly “by hand”.

              If you think about it, it’s much easier to experiment and change things if there’s less boilerplate. Experimentation involves a lot of wrong turns and throwing away and rewriting a lot of code. Boilerplate just makes that process slower. But once you know the exact design, you can meticulously write down the type declarations and so on, because you know they’re not likely to change anymore.

              1. 12

                I think a big part of it is how much design you do before writing code. If you already have your algorithm on a piece of paper you can skip the high level implementation and go right to the performant / maintainable one.

                1. 4

                  I think there’s a nice intersection here between what you’re saying and what the article is claiming. What is hard is hard problems, and knowing what to do. In many cases I find that I have to prototype a little to figure out how to solve a problem, and I would never build a prototype in a “high boilerplate” language like Java. Sometimes I figure out what to do on paper or by thinking about the architecture. In either case, once I know what to do, the amount of boilerplate in the language doesn’t matter all that much, but it would be a real strain to try and figure it out in-situ with a lot of boilerplate in the way.

                2. 14

                  I think the association between blub and boringness maybe made sense in 2000, but in 2021 (and even in 2015 when this was written) the languages which count as boring today are actually fairly powerful. Vast swathes of software are written in Ruby, Python, and JavaScript, with liberal uses of first-class functions and various other niceties which seemed weird to blub programmers in 2000. Even if you’re writing for Mac or iOS, most people probably choose Swift nowadays, which has its warts but can hardly be called a blub; or on Android I believe Kotlin is generally preferred these days.

                  It’s true that low-level infrastructure is often stuck in C and C++ and Java (but even Java has lambdas now, I hear — and it’s never had free, to its credit). But even there, things are changing: I sense increasing interest in Erlang, or at least its infrastructure.

                  It’s obviously not that there aren’t still advanced higher-level languages and features out there, but the world has moved on a lot since Paul Graham’s original essay. (He wrote that off the back of being a startup founder at a time when it wasn’t unusual to write web apps in C!)

                  1. 15

                    It’s true that low-level infrastructure is often stuck in C and C++ and Java (but even Java has lambdas now, I hear — and it’s never had free, to its credit). But even there, things are changing: I sense increasing interest in Erlang, or at least its infrastructure.

                    C++ has had lambdas since 2011 and (since lambdas are just objects with an invoke method and some fields that reference surrounding state) has had the ability to represent the same idea with a lot of boilerplate for much longer. This was quite apparent from the fact that a lot of C++ libraries didn’t need any changes to be able to accept lambdas because they could already use an arbitrary class with the call-as-function operator overloaded, and a lambda is just a shorthand way of writing one of those.

                    I quite often use C++ now for things where I’d have reached for a scripting language 10-15 years ago. Just in the standard library, you have arrays, maps, strings, regular expressions, tuples, tagged unions, and automatic memory management with the likes of std::shared_ptr or std::unique_ptr to the extent that I never need a raw new or delete in anything other than the lowest-level code. The compile + run time for a short C++ program (even at -O0) doing some data processing is typically shorter than the run time for the equivalent in Python and if I really need to start micro-optimising then everything that I need is available, whereas if I started in a scripting language then micro optimisation means rewriting some of it in C++.

                    1. 6

                      That’s extremely true of C#, too. It’s sprouted a lot of functional features over the last five or so years. If only they’d get around to adding discriminated union types, I’d be perfectly happy.

                      1. 5

                        the world has moved on a lot since Paul Graham’s original essay. (He wrote that off the back of being a startup founder at a time when it wasn’t unusual to write web apps in C!)

                        Perhaps, but I don’t think Paul Graham has moved on, since he wrote “Weird Languages” in 2021 which is arguing the point that this post is making a case against.

                        YMMV on this last bit, but I pretty regularly run into programmers who claim that you basically can’t get anything done in a language unless it has some fancy feature that currently mainstream languages seem unlikely to add, such as higher kinded types.

                        1. 7

                          There’s no way I’m gonna re-read Graham’s original essay, but the new one is very short, and again, from imperfect memory, it makes way less grandiose claims than the first. That one posited that it was the choice of Lisp that allowed PG’s online shopping site to out-innovate the competition. The later one basically says “go ahead, learn a weird language, it will make you grow as a person”.

                          No-one should look down on the programmer learning a new language for their own sake. A programmer who demands the team adopt a new language for no other reasons than it’s weird should be met with more skepticism.

                          1. 1

                            If you were to update the article today, what languages would make the “boring” list?

                        2. 10

                          I have a sneaking suspicion that this might be because the interesting data structure-y stuff is all shoving values into and out of trees, arrays, queues, stacks and hashes, and that code looks roughly like Pascal regardless of what you write it in.

                          1. 8

                            I’ve always told employers “I’d rather work on an interesting project in a boring language than vice versa”. IMO a far more important skill for “senior programmers” than fluency in a “cool language” is proficiency in systems design, not in the sense of code organization (which is constrained by programming paradigm/language), but in the language-agnostic “architectural” sense exemplified by “Hints for Computer System Design”. Like the author of TFA, when I design a system I don’t think in terms of a programming language at all, but in terms of data structures and dataflow (and for concurrent/distributed systems, global safety/liveness invariants). It so happens that my implementations tend to be in C/C++ because I mostly prefer to use OS interfaces directly, but that’s just an accident of the OS interface being “native to” C. I still trip on a C++ footgun occasionally, but the LLVM static and dynamic analyzers catch almost all my stupid mistakes before they go into production. Most incorrect behavior in my software is due to fundamental design bugs, not to deficiencies in the programming language. (If you’re wondering, I generally like Rust and have written a couple of nontrivial libraries in it, but I would think long and hard before adopting it for a commercial project.)

                            1. 5

                              TOTALLY LOVE THIS ARTICLE! I think he’s spot on here. It’s one of the reasons why I keep obsessing over Python despite the fact that many cool kids and “Real Programmers” sneer at it on the regular.

                              However this bit made me wonder:

                              Another common pitch, similar to the above, is that learning interesting languages will teach you new ways to think that will make you a much more effective programmer1. I can’t speak for anyone else, but I found that line of reasoning compelling when I was early in my career and learned ACL2 (a Lisp), Forth, F#, etc.; enough of it stuck that I still love F#. But, despite taking the advice that “learning a wide variety of languages that support different programming paradigms will change how you think” seriously, my experience has been that the things I’ve learned mostly let me crank through boilerplate more efficiently.

                              I sincerely don’t understand what he’s driving at here. I could see tools like IDEs or editors helping you crank out boilerplate more efficiently, but what does boilerplate have to do with, say, the way a Javascript developer might approach creating large systems in a radically different, more functional way after learning something like Haskell?

                              1. 5

                                Knowing that it’s boilerplate, and that it’s there so that the underlying system can be sound, and understanding how it fits into the picture? That helps me, because A) instead of trying to think of clever ways around it I accept it (because I see what it saves me elsewhere) & B) I get it right because I understand what it’s doing and why it needs to be that way.

                                1. 2

                                  My only quibbles with python are the packaging story and that some of its code structure tends towards feeling a bit clunky as I go from small to medium size of projects. Aesthetically, some people don’t like LISP’s parens, I don’t like def __init__(self):

                                  1. 1

                                    All eminently reasonable. I’m partially blind so the strong insistence on formatting-as-structure helps me out a LOT.

                                    I know 100% of the time that if I see an indented block below a line, it’s the body of a loop or a conditional. I don’t have to try to parse:

                                    foo {

                                    }

                                    foo

                                    {

                                    }

                                    or the 90 zillion other variations C-like language fans seem to revel in.

                                    This is all personal. If you don’t have to strain and fight to get your underpowered eyeballs to feed the right signals to your brain this will likely make zero sense to you :)

                                    1. 2

                                      I can’t say I have direct experience with partial blindness, but it makes sense that enforced formatting-as-structure would be very helpful there.

                                2. 5

                                  I take “boring” to be subjective to the person and the problem. I’ve written C and C++ for years, so it’s “boring” to me, but it’s not to many other people. I haven’t used Java in probably a decade, so I wouldn’t consider that “boring”.

                                  When I’m doing “interesting work” I want to focus on the problem, not on mechanics of how to write it, or get the code to run. I’ll write it in a language and environment I understand well and then port into whatever I need. I try to keep languages in my toolbox which are good at different things and use whatever is the closest line to done given the project.

                                  1. 5

                                    Yeah, Java isn’t boring it’s just… I have no reason to use it? Even if I was forced into the JVM for some reason there are very stable options that don’t give all the pain Java gives.

                                    1. 1

                                      There have been so many changes to Java since I last used it that I’m kind of interested in it now.

                                    2. 5

                                      Probably good that young people routinely ignore advice like this. We’d get nowhere.

                                      1. 13

                                        “The reasonable man adapts himself to the world: the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man.” ― George Bernard Shaw

                                        That said, I’d probably prefer reasonable coworkers at this stage of my career.

                                      2. 2

                                        I think the whole idea of “blub” is based on the assumption that for any given task “blub” is the wrong choice. However, as Dan asserts in the essay, sometimes “blub” is exactly what you want.

                                        For example, if the system you’re building has a lot of intrinsic complexity (such as a distributed database) any productivity gains realized from a “non-blub” language will be small compared to the total cost of the project.

                                        However, if you need to optimize for time to market - as in the dot com boom, in which Paul Graham built Viaweb - you don’t want to be using “blub”. If you’ve only built systems in this context it’s easy to get the impression that “blub” is just objectively worse for any given metric. Also, people are probably less inclined to wax lyrical about how great “blub” is compared to new and more exciting technologies, and so word gets around that “blub” is just plain bad.