47 comments

[ 1.1 ms ] story [ 53.5 ms ] thread
I get more done by writing the stupid code, and fixing it, than junking the old code... but every now and then I can see clearly a structure for a rewrite, and then I rewrite, but its rare.
I feel like people should be writing stupid code, and in the case where its a compiled language, we should ask compiler or the language for better optimization. The other day, I was writing a check of a struct that have certain structures (protobuf probably have something like this)

struct S { int a; int b; int c; int d; int e; /* about 15 more members */ }

so I wrote

const auto match_a = s.a == 10; const auto match_b = s.c == 20; const auto match_c = s.e == 30; /* about 15 more of these */ if (match_a && match_b && match_c) { return -1; }

Turns out compilers (I think because of the language) totally shit the bed at this. It generates a chain of 20 if-else instead of a mask using SIMD or whatever. I KNOW this is possible, so I asked an LLM, it was able to produce said code that uses SIMD.

Why is this a struct and not an array of ints ?
I'm working on in-kernel ext3/4fs journalling support for NetBSD. The code is hot garbage but I love it because of the learning journey it's taken me on: about working in a kernel, about filesystems, etc. I'm gonna clean it up massively once I've figured out how to make the support complete, and even then I expect to be raked over the coals by the NetBSD devs for my code quality. On top of that there's the fact that real ones use ZFS or btrfs these days, and ext4 is a toy; like FAT, by comparison, so this may not even be that useful. But it's fun and lets me say hey Ma, I'm a kernel hacker now!
I appreciate the sentiment, but "There is no stupid code" is the dumbest sentence I've ever read.
Today its vibe stupid code.
This is a particularly bad mobile layout. Fix your margins.
> Fast forward to today. I’ve been doing a dive on JavaScript/TypeScript and different runtimes like NodeJS and Deno,

That's why. If all codes in a project are stupid, there's no stupid code indeed relatively.

Go read Linux kernel mailing list.

The Kernighan law says debugging code is twice as hard as creating it.

Therefore, if you push yourself to the limit of your abilities to create the most clever code you can, you won't be able to debug it.

Where did you study games? Seems like we have similar trajectories.
>>> When I finished school in 2010 (yep, along time ago now), I wanted to go try and make it as a musician. I figured if punk bands could just learn on the job, I could too. But my mum insisted that I needed to do something, just in case.

Amusing coincidence. I also wanted to be a rock star, or at least a successful working musician. My mom also talked me out of it. Her argument was: If there's no way to learn it in school, then go to school anyway and learn something fun, like math. Then you can still be a rock star. Or a programmer, since I had already learned programming.

So I went to college as a math major, and eventually ended up with a physics degree.

I still play music, but not full time, and with the comfort of supporting myself with a day job.

I like this philosophy. It's interesting to me that the author writes about trying deno, specifically out of curiosity for compiling binaries with it, because that is something that's been specifically tickling the back of my mind for awhile now, but I've had no real reason to try it. I think this gave me the motivation to write some "stupid" code just to play with it.
Buns faster and the binaries are a bit smaller last I checked.
I would say that much of my code starts out stupid and, hopefully, becomes better with refinement.
For sure. I'd argue to write the "stupid" code to get started, get that momentum going. The sooner you are writing code, the sooner you are making your concept real, and finding the flaws in your mental model for what you're solving.

I used to try to think ahead, plan ahead and "architect", then I realized simply "getting something on paper" corrects many of the assumptions I had in my head. A colleague pushed me to "get something working" and iterate from there, and it completely changed how I build software. Even if that initial version is "stupid" and hack-ish!

> I'd argue to write the "stupid" code to get started, get that momentum going.

Yes and no, depending on how dependent you become on that first iteration, you might drown an entire project or startup in technical debt.

You should only ever just jump in if:

A) it's a one off for some quick results or a demo or whatever

B) it's easy enough to throw away and nobody will try to ship it and make you maintain it

That said, having so much friction and analysis paralysis that you never ship is also no good.

I frequently do both. It takes longer but leads to great overall architecture. I write a functional thing from scratch to understand the requirements and constraints. It grows organically and the architecture is bad. Once I understand better the product, I think deeply on a better architecture first before basically rewriting from scratch. I sometimes need several iterations on the most complex products.
This is also why I'm not a fan of the "software architect" that doesn't write code, or at least not the code that they've architected.
You should always have an architecture in mind. But it should be appropriate for the scale and complexity of your application _right now_, as opposed to what you imagine it will be in five years. Let it evolve, but always have it.
Theres a phrase that's become a bit of a mantra in adjacent circles

"Just make it exist first. You can make it good later."

With a working prototype you get to test the specification and the users, not just the code itself.
This is why I hate software engineering as a profession.

You're going to write the "stupid code" to get things out the door, get promoted and move on to another job, and then some future engineer has to come along and fix the mess you made.

But management and the rest of the org won't understand why those future engineers are having such a hard time, why there's so much tech debt, and why any substantial improvements require major rework and refactoring.

So the people writing the stupid code get promoted and look good, but the people who have to deal with the mess end up looking bad.

> I used to try to think ahead, plan ahead and "architect"

Depends on what you do. If you build a network protocol, you'd better architect it carefully before you start building upon it (and maybe others do, too).

The question is: "if I get this wrong, how much impact does it have?". Getting the API of a core service wrong will have a lot of impact, while writing a small mobile app won't affect anything other than itself.

But the thing is, if you think about that before you start iterating on your small app, then you've already taken an architectural decision :-).

This is where experience matters. The more experience you have, more often than not, the less stupid the code is. Not because you aren't testing your concepts as fast, but that your tooling is improved.

Basicaly, do you have a good foundation to build from. With more experience, you can build a better foundation.

Also read "stupid" code :)

I didn't know about Deno and streams, but this looks fine

  const file = await Deno.open("huge-quotes.txt");
  const quotes: string[] = [];

  await file.readable
    .pipeThrough(new TextDecoderStream())
    .pipeThrough(new TextLineStream())
    .pipeTo(new WritableStream({
      write(line) {
        quotes.push(line);
      }
    }));
Looks like straight out of Dart.
I both agree and disagree with this post, but I might be misunderstanding it. Near the end, it states:

“Enjoy writing it, it doesn’t have to be nice or pretty if it’s for you. Have fun, try out that new runtime or language.”

It doesn’t have to be nice or pretty EVEN if it’s NOT for you. The value in prototyping has always been there and it’s been very concrete: to refine mental models, validate assumptions, uncover gaps in your own thinking (or your team’s), you name it.

Unfortunately it feels that the pendulum has swung in the completely opposite direction. There’s a lot of “theatre” in planning, writing endless tickets and refining them for WEEKS before actually starting to write code, in a way that’s actively harmful for building software. When you get stuck in planning mode you let wrong assumptions grow and get baked in into the design so the sunken cost keeps rising.

Simply have a BASIC and SHARED mental model of the end goal with your team and start prototyping. LLMs have made this RIDICULOUSLY CHEAP. But, the industry is still stuck in all the wrong ways.

For my money, certain types of software shouldn't have tests, too much planning, or any maintenance whatsoever

Prototypes (start ups) rarely have the luxury of "getting it right", their actual goal is "getting it out there FAST to capture the market (and have it working enough to keep the market)"

(Some - apologies but I'm not a game dev enough to be able to say what types this applies to) Game devs - they're more or less build it, ship it, and be done with it, players tend to be forgiving of most bugs, and they move on to the next shiny thing long before it's time to fix all the things.

Once the product has traction in the market, and you have paying customers, then it's time to deal with the load (scale up) and bugs, I recall reading somewhere that it's probably best to drop the start up team, they did their job (and are now free to move on to the next brilliant idea), and replace them with a scale up team, who will do the planning, architecting, and preparation for the long term life of the software.

I think that that approach would have worked for Facebook (for example) they had their PHP prototype that captured the market very quickly, and (IMO) they should have moved through to a scale up team (who could have used the original code as a facade, strangling it to replace it with something funky (Java/C++ would have been what was available at the time, but Go would be what I would suggest now)

> It doesn’t have to be nice or pretty EVEN if it’s NOT for you.

> There’s a lot of “theatre” in planning, writing endless tickets and refining them for WEEKS before actually starting to write code, in a way that’s actively harmful for building software.

I'd love to have a "high paying job" where I am allowed to start prototyping and modelling the problem and then iteratively keep on improving it into fully functional solution.

I won't deny that the snowballing of improvements and functional completeness manifests as acceleration of "delivery speed" and as a code-producing experience is extremely enjoyable. Depth-first traversal into curiosity driven problem solving is a very pleasurable activity.

However, IME in real world, someone up the chain is going to ask "when will you deliver this". I have ever only once been in a privileged enough a position in a job to say "I am on it and I will finish it when I finish it... and it will be really cool"

Planning and task breakdown, as a developer, is pretty much like my insurance policy. Because when someone up the chain (all the way down to my direct manager) comes asking "How much progress you have made ?" I can say (OR "present the data" as it is called in a certain company ?) "as per the agreed plan, out of the N things, I have done k (< N) things so far. However at this (k+1)th thing I am slowing down or blocked because during planning that-other-thing never got uncovered and we have scope-creep/external-dependency/cattle-in-the-middle-of-the-road issue". At which point a certain type of person will also go all the way to push the blame to another colleague to make themselves appear better hence eligible for promotion.

I would highly encourage everyone to participate in the "planning theatre" and play your "role".

OR, if possible start something of your own and do it the way you always wanted to do it.

> ... for WEEKS before actually starting to write code...

I'm curious who is in these kinds of jobs. Because I've never seen this in practice.

I feel like this is the time to mention "How Big Things Get Done", by Bent Flyvbjerg. "Long planning vs. start prototyping" is a false dichotomy. Prototyping IS planning.

Put another way, refining tickets for weeks isn't the problem; the problem is when you do this without prototyping, chances are you aren't actually refining the tickets.

Planning stops when you take steps that cannot be reverted, and there IS value in delaying those steps as much as possible, because your project then becomes vulnerable to outside risk. Long planning is valuable because of this; it's just that many who advocate for long planning would just take a long time and not actually use that time for planning.

Shame that the writer didn’t tie up the initial story about waiting to be a musician without knowing anything about that with the end of the story.

Also, 2010 was just yesterday my young friend :)

Even if the code is for yourself or for a collaborative team for a project or for a company the quality matters. Also the software replicability, reproducibility and reliability are significant indicators for viable code and guaranteed results
> It’s small, it’s dumb, and there were probably plenty of options out there.

Oh, this sort of "dumb" code. That is just exercise. It bothers me that in this field we don't think we should rehearse and exercise and instead use production projects for that.

Actual dumb code is one that disregards edge cases or bets on things being guaranteed when they're not.

@author the blog scales poorly on smaller devices. The header doesn't fit the screen, margin's too big and lines are too crammed (line height needs a bit mor love).

https://i.imgur.com/Ev6Ea1b.png

One thing I have found to be a very valuable habbit is to first think about what your software has to do on paper and draw some shitty flow charts, lists and other things, without too much care about whether you will do it (especially if it isn't software that you strictly need to do for some reason).

Whether an idea is good or not can often only be judged when it becomes more concrete. The actual finished project is as concrete as it gets, but it takes time and work to get there. So the next best thing is to flesh it out as much as possible ahead and decide based on that whether it is worth doing it that way.

Most people have the bad habit of being too attached to their own ideas. Kill your darlings. Ideas are meant to be either done, shelved or thrown into the bin. It doesn't do any good to roll them around in your head forever.

I do not believe that the real struggle is "starting", nowadays, since AI impresses 90% that is able to complete a task. We struggle in architecting the whole thing we want to start.
I agree but there are certain types of unnecessary stupidity, which feel more easy at at first, but hurt more than they help very quickly (measured in amount of code):

The first one that comes to mind relates closely to naming. If we think about a program in terms of its user facing domain, then we might start to name and structure our data, functions, types too specifically for that domain. But it's almost always better to separate computational, generic data manipulation from domain language.

You only need a _little bit_ more time to move much of the domain specific stuff into your data model. Think of domain language as values rather than field names or types. This makes code easier to work with _very quickly_.

Another stupidity is to default to local state. Moving state up requires a little bit of planning and sometimes refactoring and one has to consider the overall data model in order to understand each part. But it goes a long way, because you don't end up with entangled, implicit coordination. This is very much true for anything UI related. I almost never regret doing this, but I have regretted not doing this very often.

A third thing that is unnecessarily stupid is to spread around logic. Harder to explain, but everyone knows the easy feeling of putting an if statement (or any kind of branching, filtering etc.) that adds a bunch of variables somewhere, where it doesn't belong. If you feel pressed to do this, re-consider whether your data is rich enough (can it express the thing that I need here) and consistent enough.

You should write stupid code, but you should write good code too.

Writing stupid code is like walking to the shop. You're not going to improve your marathon time, but that's not the point. It's just using an existing skill to do something you need to do.

But you should also study and get better at things. If you learnt to cycle you could get to the shop in a third of the time. Similarly, if you learn new languages, paradigms, features etc. you will become a more powerful programmer.