Comment by corytheboyd

Comment by corytheboyd a day ago

15 replies

> […] bottom-up programming, where you write programs in multiple layers, the lower ones acting as programming languages for those above

I like to explain this as “hide the bad parts behind a good API”. Anything interesting is going to require “bad parts”, which just means the low-level, difficult work. From there, compose up and up until a high level orchestration is achieved. It works so much better than the bad parts being distributed everywhere! That’s what you’d also call a “leaky abstraction”

nfw2 a day ago

I think that many, perhaps even most, engineers incorrectly believe that the main purpose of abstraction in code is simply DRY, as if the goal is to save keystrokes or something.

In my view, the purpose of abstraction is to compress the concepts of your application into digestible and manueverable chunks, and DRY is just a heuristic for beginners to follow to help point to where appropriate abstraction boundaries may be.

I hope the various theories behind what constitutes good code will make their way out of scattered blog posts and into CSE curriculum.

  • corytheboyd a day ago

    DRY is an okay rule at the absolute beginning of your programming career, but it must become obvious why it is too simple for you to advance much further. DRY is most certainly not abstraction.

    I actually took a general Software Development course when I was in school that sort of touched on things like Linux, source control, debugging, and other things I now forget— it was an elective though. It was neat, the teacher even introduced us to Ruby, which was a cool experience for a bunch of dumb kids who thought the whole world ran on Java or C++ :) I liked it so much I went on to implement Ruby-isms in C++ for my other classes, and use those to orchestrate solutions. Completely dumb in retrospect, but I thought it was so cool at the time. And hey I guess that’s a great example of learning early on how to “hide the bad parts!”

  • 4star3star a day ago

    I think DRY should be supplemented by "Don't make me read it multiple times". Repeat yourself, by all means, if that makes it so that I don't get all twisted up jumping between so many files that I can't keep the main thread straight while I read your code.

    • jpc0 20 hours ago

      Another on this. If you abstract away code that throws or returns an error document that somehow.

      The amount of times I've had to dig through 6 levels of abstraction to find what error gets returned in some edge case so I can catch and handle it gave me PTSD and gave me not invented here syndrome.

    • wduquette a day ago

      Don’t repeat yourself…but don’t obfuscate the code either.

  • lanstin a day ago

    New software demands a new vocabulary, and if those new concepts correspond exactly to implemented code, everything becomes very clear and possible to share with new people.

    As well, the division of a project into layers where each layer has a manageable amount of concepts, 5-7 for normal layers, becomes much easier for people to learn and use correctly. If I have to keep 12 things in mind while using a layer, it's going to be a lot harder to get correct.

  • jimbokun a day ago

    Good API is for encapsulating and communicating ideas between other programmers or teams.

    DRY is for improving communication with your future self.

joe_the_user a day ago

"Hide the bad parts behind a good API... It works so much better than the bad parts being distributed everywhere!"

This doesn't work for the "bad things" I know of. All of the low-level bad parts which are truly bad/mucky, are bad because they can't be entirely hidden. They are leaky abstractions and by that fact, they ... leak. They impact every part of the system so they are "distributed everywhere" in the sense that the maintainer of a large program has to consider them everywhere even if they only directly show up in a few places.

Just as an example, programming languages are abstractions over the complex structure of "raw" memory. Pythons hide this abstraction more than for example c but once you reach a certain scale the use of python, you have to consider the details of its use of memory. And that's memory in general, which people work at to make reasonably regular as well as fast.

That's not saying you can't have an API that makes the low-level problems less.

WillAdams a day ago

This seems to be one of the core lessons behind John Ousterhout's _A Philosophy of Software Design_

https://www.goodreads.com/book/show/39996759-a-philosophy-of...

and I find that the mechanism of "Literate Programming":

https://literateprogramming.com/

is a useful one for doing this since it allows one to write about both how the low level details are implements in a function, _and_ how the written function is used in a way which allows the twain to support each other.

kmoser a day ago

Said another way: push interface up and implementation down.

  • corytheboyd a day ago

    Well said, I’ll be taking that :)

    • kmoser a day ago

      I can't take credit for it; I read it in a C Users Journal article back in the 1990s which I haven't been able to find online.

reddit_clone a day ago

This is what I believe as well. Also throw in some Functional Programming (isolating pure functions and side-effecting functions) for extra benefits.

  • kevindamm a day ago

    Both excellent points, and I would add a recommendation for high level organization: to consider the data then the process. If you can draw a graph where every data structure is only connected to a process, and vice versa, and that processes may take multiple inputs but only produce a single output type, it will make holding the entire system in your head a lot easier, even for very scaled-up systems.

    Bonus points if you can distinguish between essential state and circumstantial state.