Hacker News new | past | comments | ask | show | jobs | submit login
Habits of Expert Software Designers (mit.edu)
711 points by headalgorithm 10 days ago | hide | past | web | favorite | 142 comments





Most of these points (like the crucial importance of context/looking around, of users, of figuring out what you're not doing, etc) are important parts of software development.

But the problem is, unless you already have the requisite experience to show you what these bullet points really refer to in practice, you're not going to really make sense of this list, not in a way that will actually help you do anything differently.

"Always learn about the users" for example is much too vague: which users? how do you talk to them? when do you trust them and when do you not take their feedback at face value? I don't think you can learn this sort of thing outside of a real life context.


It is always hard to learn from people several levels ahead of you. What they do is amazing and impenetrable. What they say seems to make little sense. You lack too much of the common background.

This is why, when I find myself in a situation like that, I try hard to understand the point. Why do these people do these strange things? What do they mean by saying these sentences that seem detached from the practice? Empirically, they are smart, so they mean something.

This is how you start to detect where the common context is lacking, and look for explanations. Eventually, with enough effort, you bridge the gap and understand what they meant, and why. This is how you grow.


Don't spend too much time trying to decipher people who claim to be "levels ahead of you." If they actually understood the topic, they could easily explain it in a way that a novice can understand.

Some of the things that I know about would take months or years to explain to a novice in such a way that they would understand what I was talking about. Not by way of metaphor or by analogy, but to truly see things the way I'm seeing them when I give an explanation. We can try to meet halfway but the requisite knowledge may be lacking.

In effect this is what I'm doing when I coach interns and juniors -- giving them the requisite knowledge so that they can see things the way I'm trying to explain them.


"Feynman was a truly great teacher. He prided himself on being able to devise ways to explain even the most profound ideas to beginning students. Once, I said to him, 'Dick, explain to me, so that I can understand it, why spin one-half particles obey Fermi-Dirac statistics.' Sizing up his audience perfectly, Feynman said, 'I'll prepare a freshman lecture on it.' But he came back a few days later to say, 'I couldn't do it. I couldn't reduce it to the freshman level. That means we don't really understand it.'"

-- David L. Goodstein, Feynman's Lost Lecture: The Motion of Planets Around the Sun, ISBN:978-0393039184.


> That means we don't really understand it.

I wonder if other physicists shared the sentiment.


I hope so. I've always thought the quintessence of science is pushing back the boundaries of ignorance. To advance we must first understand the true outline of our incomprehension. In that light, I don't think Feynman's remark is a negative sentiment at all.

To know what what you do not know, etc. (c.f. confucious 2:17, rumsfeld 2:02)


I didn't mean it in a negative way either

I always seek clarity, and quite often 'complex' science is just about that, you get to see differently, eurekas. And when there's no eureka, to me then something is wrong, and the science has been accepted at face value which is also wrong.


Out of curiosity, what sort of topics require months of years of explanation? I find that most complex topics can be broken down to a point where an average adult could digest them if they're interested enough in learning them. I wouldn't necessarily say that a 5-10 min explanation means that they could apply it in the field, but enough to understand a specific scenario.

A question from a five-years-old: why is sky blue?

A correct answer: you need to learn how to read, then some mathematics, then quantum physics, then you can calculate how sunlight scatters on molecules of air. Understanding the physiology of color vision won't hurt, too.

This is not very useful. But at least you see some topics to learn more about, and a simplified picture may be built: sunlight contains some blue light, and it gets stuck in the air, while reds and greens pass in more easily. Hey, you just understood why sunsets are orange and red! Go on.


White Light is actually a mix of colours, the rainbow. You can split it into parts with a glass prism, or in good weather a sprinkler?

Light is a bit like a wave through the air and in the blue light the waves are closer together.

The sky aboves us has a small amount of dust.

Because the blue light waves are closer together they hit more dust.

This means they are more likely to bounce towards us, so we see blue when we look up at the sky.

At sunset the blue waves are more still more likely to hit dust, and so be blocked, so we see red.

Not simple enough, but I gave it a go.


"Daddy, why is the sky blue?"

"Let's start with you reading (and demonstrating to me a core competence of) the basic texts of physics leading up to Rayleigh scattering--in this case, that would be Newton, Liebniz, Maxwell, Einstein, Heisenberg, and Schrödinger. When you have those six down, I'd be happy to explain to you why the sky is blue."

Inspired by: https://news.ycombinator.com/item?id=1492061


Because that's the color of air.

And at the end of all that, it ends up boiling down to "It's the result of a superposition of states collapsing into a single state upon observation, and the mechanism by which that state gets selected is non-deterministic" and now you have a very confused five-year-old.

It is said of a lot of things in mathematics that you simply need to get used to them. This process does take months or years, and once you went through it you probably no longer understand how it feels to not understand those things.

The 5-10 minutes explanation is what you get in a lecture. You may even think that you understand afterwards. Years later, you're going to look back and realize that you really didn't understand much at all.


That is one learning style but not the only learning style. That style is reserved for kids, because often explanations are too abstract, so instead of fully understanding what they're doing, they're given tons of examples, turning the process into muscle memory.

If a topic is muscle memory, it becomes very hard to explain or teach to another. This is why it is important to learn topics beyond muscle memory. I had to go through this because I learned how to program before I was a teen. I found it difficult to explain what I was doing to others.

Today when people get stuck early on learning to program I show them decomposition, as it is the most common hold up people get stuck on. Decomposition is the opposite of abstraction, so it leads into a beneficial second lesson later on. (I don't explain decomposition, I show them.)

At the end of the day it comes down to personality and beliefs more than prerequisite experience when it comes to learning. If someone is afraid to stop and go out of their way to learn a prerequisite, because they're afraid to be seen as ignorant, they're going to struggle. Likewise, if someone is afraid to make a mistake / have a misunderstanding, it can cause too much anxiety to quickly pick up topics.

This is why with interns my primary focus is neutralizing anxiety. I try to show ignorance and misunderstanding are okay and acceptable. I lead by example. Little ducks copy unsaid behaviors well. Once that criteria is met, then and only then do I slowly switch into dumping terminology and lessons on them, only once they're ready for it.


Take Galois proof of the insolvablity of the quintic. To understand it you first need to understand group theory and then field theory and obviously how these relate to the rational numbers and the ring of polynomials over the rationals. Next you need to understand field extensions and then you can start to make sense of galois groups. Then you need to understand the concept of solvability for groups and prove it’s equivalence for galois groups to solutions to polynomials. Then finally you need to demonstrate a polynomial of degree five whose corresponding galois group is unsolvable.

Now you can hand wave this and get a basic idea of it. But this is also undergraduate mathematics. The abstractions keep building on each other as you go and soon the easy way to explain it is still in terms of other abstractions. This is for instance why research papers in mathematics are impenetrable, because the requisite knowledge takes years to acquire.


On the other hand, if you are VI Arnold, you can teach an honest version to motivated high school students in a relatively short timespan, https://amzn.com/1402021860

Intriguing. Are there other books that do a similar job for other topics in Mathematics?

These bullet points are not for specific scenarios. They are broad general activities. Their specifics will change from situation to situation.

The first bullet point — listening to users, but not taking what they say at face value is fantastic advice for all businesses. Executing on it is a high-skill activity.

I can give examples of when this was neglected and things went poorly. I can give examples of it done very correctly. Only after practicing it for years can I get a smell for what a user really needs, or how to steer a corporate customer to the solution they need and not the one they want.


Knowledge is not equivalent to experience. Many things require tacit knowledge just to understand which properties of a thing are important.

Haven’t you ever re-read a book after gaining much practice and realized how much you’d missed on the first time reading? I do that all the time.


Knowing and teaching are very different things. Did you never have a professor who was a brilliant researcher/scientist but a horrible instructor?

+1, and anecdotally I've seen most good developers are bad teachers and that I have always gotten much more from my peers just one or two levels ahead of me (regardless of my peer's ability to teach).

That assumes that they are trying to explain something to you, but sometimes you are trying to sit in on a meetup aimed at people with more knowledge than yourself, or just following along a discussion between other people.

I agree. The best engineers I have worked with have been able to justify decisions to a whole team. They were able to educate those who weren’t up to speed elevating the group.

The worst engineers dismissed others out of hand, saying they lacked the requisite knowledge for a discussion.


some things are irreducibly complex. if I ask a theoretical physicist about their work, they may not be able to explain anything meaningful about it to me.

That tactic makes sense when you want to communicate to people on a much lower level than you are at, and you want them to get the surface level rapidly.

If this were to be levied at me accusingly I'd throw a programming Bible at them, get thee hence and study.


> If they actually understood the topic, they could easily explain it in a way that a novice can understand

This is so patently untrue. Folks like Feynman are the exception, not the rule.


You make a good point, then again many people though they understand something cannot communicate it to noobs on account of curse of knowledge issues. Afaik, Fenyman regularly refreshed himself on the basics, he felt it helped his own understanding I think, but that probably had a lot to do with what made him a great teacher as well.

I especially liked the image of the guy roasting marshmallows on his burning computer.

Error might be opportunity but it's best to triage and fix the immediate impacts of the error, document the root causes, then explore any potential opportunities later.

Similarly, you should put out a burning computer with an extinguisher. It might be neat to know that computers can start fires but I recommend matches or lighters if you want to roast marshmallows.

So, I agree, and I think these articles are actually harmful. The biggest skill is knowing what the most important thing to do is, how much of it to do, and why you're doing it. Doing something because you read it's a best practice done by experts is almost the direct opposite of that because it does nothing to help you prioritize, scale or understand.

Don't be marshmallow guy.


Agreed. Think of them as a list of skills that software engineers have to learn. Junior engineers may not even realize they need to learn them; this post might open their eyes. It may get them talking to users when they might not have otherwise, and through practice, developing those skills.

I think that's where the "look around" point kicks in. You can look at a successful software project and think of ways that "learning about the users" applies to its design.

With some imagination I think that anyone working with software can take something from these points, but it's obviously not a how-to-expert tutorial. Rather, it's what the title says that it is.


> Always learn about the users" for example is much too vague: which users? how do you talk to them? when do you trust them and when do you not take their feedback at face value? I don't think you can learn this sort of thing outside of a real life context.

So how should "these bullet points" explain those things "outside of real life context"?

These points give you abstract points to consider and to then apply to your problem.


When I read this I just assumed it was a checklist for people that know these things - a good reminder. But now that I think about it, it probably was also meant to get people to look out for these things as they learn. I doubt this is enough to really help anyone learn these things.

I think this illustrates why it's relatively rare to find someone who has a high degree of technical aptitude but also a great communicator.

In Feynman's words, "If you can’t explain something in simple terms, you don’t understand it"


The thing is, you can be very good at something without understanding it.

To the OP's point, just because you're good at something doesn't mean you can explain it well to others, especially if you don't understand it. Or at least, if you only intuitively understand it

Define 'something'. As it stands, it's too broad.

I can think of example in other field: Art. Some people just great at using/picking color. They just pick the color they want quickly and paint without thinking about perfect harmony color scheme theory at all, yet their art always result in great color combination.

Just ask them why they pick that certain color and you won't find rational behind it. They just...did, their hand just move to that color, paint it, and it looks good—the results of tons of practices over the years. Not to mention some artist didn't even have proper art education, not to mention art theory. Why and how it happened to be the same combination as in the color harmony theory is surely hard to explain.


It sounds like you are describing intuition. I think there are occasional savants born with this, but for the majority of experts that subconscious decision mechanism is honed after years and years of work.

>you're not going to really make sense of this list, not in a way that will actually help you do anything differently.

My thoughts as well. Or, you will think of course, I do these things, when in fact you are ineffective at them.


In my case, I can see how to apply those things to personal projects that I have complete control over, but I have trouble imagining myself doing those things in my regular job, in which I have some say in how to implement this or that, but I don't really have any high level control over what features the product is going to have.

Besides having the requisite experience to make decisions, you also need to be in a position of authority that can make decisions, and some degree of veto power over decisions made outside your team that affect your work.


Agreed. I think this is an instance of:

> It is only by harsh experience that we learn which principles take priority over which other principles; as mere words they all sound equally persuasive.


I agree with you. From my perspective (I'm a BA, non-developer), for sure I agree that every abstraction should be elegant. But how to define "elegant"? I probably need years and years of GOOD experience and code reading to get that point.

Elegant is one of the more complicated terms in software engineering. Depending on who is using the word, it can mean some combination of: efficiently designed, easily understood (regardless of complexity), surprisingly brilliant, fault tolerant in a clean manner, very insightful on a problem area, etc. Sometimes code is elegant relative to what has been in place, so going from highly complex to slightly complex might be called an elegant solution. Honestly, I've seen elegant used in just about every way imaginable.

While there may be a TON of things alluded to when calling something elegant, generally people mean that it's easy to understand, thoroughly solves the problem, and isn't likely to break. I would imagine that many elegant solutions become legacy code eventually because they don't easily die and don't necessitate placement all on their own.

I'd be interested to hear how other people view/use this word. I haven't given it much thought, but now that I am, it seems to be very important.


> efficiently designed, easily understood (regardless of complexity), surprisingly brilliant, fault tolerant in a clean manner, very insightful on a problem area, etc.

I think your description of elegant is good. One more aspect of elegant is: doing all those things you list here in a manner idiomatic to the language and paradigm you're working in. So for example, regardless of how efficient or easily understood your solution is, if you're using loops and mutation in a functional language, it would rarely be considered "elegant" by experienced people working in that paradigm (that's not to say that loops and mutation aren't very occasionally a good idea in functional languages, but they'd still not be considered elegant).


It does say they have a book coming out. I think this is a teaser, with the book having more detail on each technique.

> with the book having more detail on each technique

Based on the excerpts you can see on Amazon, not really.


> you're not going to really make sense of this list

I think the premise is that if you did not looked at users before and now you know that you should be, it's a huge difference and you will start thinking about questions like you asked and will figure out the answers over time.

I think sometimes the hard part is not knowing what you don't know, because those might be very hard to discover.


These lists tend to be trite, and this one is no exception. For example,

"Experts are not satisfied with just any abstraction, they deliberately seek elegant abstractions through which complex structures can be introduced, understood, and referred to efficiently."

Every developer I've ever talked to believed down to their core that this was what they were doing. Yet 99% of software is utter bilge.

This includes mine. I look at everything I've written 5 or more years ago, and it's all garbage. Most of the work I do is rewriting it.

There's no way around it, it takes a lot of experience to be even able to recognize a good design, let alone write one. No list of 10 rules is going to help much.

It's like painting. No "10 Habits of Famous Artists" is going to help you become a great artist.


> > they deliberately seek elegant abstractions through which complex structures can be introduced, understood, and referred to efficiently."

> Every developer I've ever talked to believed down to their core that this was what they were doing.

Really? I’ve worked with a lot of people who are just trying to make the thing do the thing.

Even most of the people who are interested in good abstractions often are under such pressure to perform “I’m just shipping here don’t mind me” that they largely stop thinking about the right abstraction.

Maybe I’ve worked at too many troubled startups though lol.


Not all developers are doing this, no. But pretty much all the ones I’d like to strangle are.

It’s elegant! No, your dumpster fire of a Second System Syndrome is not elegant. Fractal designs are not elegant. Also you are in your late 30’s. Why are you just having your second system syndrome now? </oddly specific>


>>I look at everything I've written 5 or more years ago, and it's all garbage.

From Walter Bright? Sorry I don't buy this. I can accept that you might feel it could be better, but garbage? No.


Here's a piece I was proud of 20 years ago. Can you count all the ways it's a steaming pile?

https://github.com/dlang/dmd/blob/master/src/dmd/root/outbuf...

I've recently fixed a number of its problems, but it's got a ways to go. Am working on it this evening.

It needs to be better because earlier today I found a bug enabled by its poor design:

https://github.com/dlang/dmd/pull/10462


Programming is finding abstractions, and those change as a program, and the understanding of the problem grows. Abstractions then have to change again as the program interacts with other systems, and to accomodate typical patterns of changes in the requirements which can't be predicted beforehand. Abstractions then have to change again to facilitate understanding the entire thing, and to accomodate technical changes, or allow easier bug finding.

I'd say, a real-world program that's beautiful 5 years later is ...something special :)


No, I know exactly what he means. I sometimes get irritated with code I wrote a year or so ago, and that feeling is compounded the farther back you go. And that’s not counting the spots where I catch myself doing things I’ve told others to avoid doing.

> I catch myself doing things I’ve told others to avoid doing.

Now and then I'll publish some guidelines for writing better code, and someone always points out that I violate them myself and contradict earlier dicta :-)


> "deliberately seek elegant abstractions"

This advice is too abstract, to be practically useful in real life. ? Is it a bit like saying: To be a good runner, do this: Run fast. — Needs to be broken down into smaller more actionable steps.

Still the other advice about talking with users, and looking around at other things out there, and spending time "thinking into the future" about how one's ideas will work out, and what to not include in the software — I like that advice :- )


Experts design elegant abstractions and leave us to understand their brilliance after they've left.

I'd say elegant abstractions are discovered. Those that are designed tend to have leaky corners. Some manage to rediscover something, implement it poorly, and give it a new name to confuse programmers for the next couple of decades that follow.

Experts simulate continually and fool themselves into believing they've thought of everything. Humans are able to predict the outcomes of complicated systems through heuristics. However we're especially bad at specifying invariants of complicated behaviors when it involves live-ness and safety.

Experts know when to model a system and use automation to check their designs. If that is overkill they write property tests. At the very least we write a tonne of unit and integration tests.

There's nothing like writing out the math and having the solution pop out at you.

Experts think about what they are not designing and they write it down as an invariant of their model.

This seems like a blog-vert for a book and while I love learning about how other engineers practice their craft this looks like it's going to be a mixed bag. It might help listing some of the experts involved in this project. Similar to how Coders at Work did.


Yea the expert abstraction thing is bad advice, too many juniors (who probably already over abstract everything) will read this and think they need more abstraction.

The difference I think the author was trying to hit is that an expert uses abstraction to achieve separation of concerns, an important and difficult thing to do.

A junior doesn't know what separation of concerns is but they see the experts abstracting stuff and think they should abstract things then they will be like the experts.


There is an easy test for wrong abstractions.

A right abstraction makes everything smaller. Most wrong abstractions make everything bigger (in the name if "flexibility", etc).


Are you listening, Java people?!

I've come to realize the problem with Java is not the programmers. Most of the strategies they want to use are legitimate improvements in flexibility, and in other languages they do make the source code smaller. Java is simply a poor vehicle.

Java forces programmers to choose a point on the spectrum of "more flexibility" <-> "smaller program size". In languages like Lisp, by contrast, the more generic a function is, the smaller it is. When I choose to make a function less flexible (i.e., making it more specific to improve performance), it gets longer. The spectrum in Lisp is "more flexibility + smaller program size" <-> "more performance + larger program size", and that's almost always an easy choice to make. Every function and macro in core.clj, for example, is impressively concise.

When I write Java, I tend to go for simple first, and then have to rewrite everything 20 times as I discover what axes of flexibility I need. In Lisp, I tend to write a function once in the simplest possible way, and then re-use it in its original form forever. It's already at max-simplicity and max-conciseness by default. Except in the rare case where it ends up being a bottleneck, it's done.

What I want above all is "more maintainable". In Java, the two factors that drive this are on opposite ends of the spectrum. There's no ideal design, and whatever point I pick today will turn out to be the wrong choice later.


One problem is that Java lacked functions until Java 8. It still sort of lacks them internally, but tat least you can write free-standing functions here and there, and especially as lambdas inline.

Another problem is that Java lacks type aliases. If your data have a complicated type like List<Set<Pair<Foo, ? extends Bar>>>, you have to copy-paste this type everywhere, without a way to name it succinctly.

On top of that, Java lacks type inference, even the weakest syntactic form. This is why you often need to write a long declarations, so long that they exceed the space you may have saved by factoring out a small function. Lombok and the diamond operator somehow alleviate that, but not completely.

The lack of pattern matching, or named arguments, or null vs Optional vs Result, goes without saying.

This makes Java a very verbose language, even if the logic of your code is streamlined and economical. In many standard library APIs, it is not.

(Hence Kotlin, obviously, or Scala if you can tolerate the build times.)


> If your data have a complicated type like List<Set<Pair<Foo, ? extends Bar>>>, you have to copy-paste this type everywhere, without a way to name it succinctly.

Java has had generic type inference since at least 7 [0], so all you need is <>

It's not perfect, but I believe it's been improved with each version.

[0] https://docs.oracle.com/javase/7/docs/technotes/guides/langu...


Yes, this is what I called "diamond operator".

I'm talking about a different use case where inference via assignment does not work, e.g. a method declaration:

    public List<Set<Pair<Foo, ? extends Bar>>> combine(
      List<Set<Pair<Foo, ? extends Bar>>> a,
      List<Set<Pair<Foo, ? extends Bar>>> b
    ) {...}
It would be great to have something like

    type Quux = List<Set<Pair<Foo, ? extends Bar>>>;

    public Quux combine(Quux a, Quux b) {...}
Unfortunately, I'm not aware of any plans to introduce that.

Huh, I always thought I was doing Java wrong when I would try to write the equivalent of four Python list comprehensions in a row and end up declaring a ton of List<Set<Pair>>> things. Didn't think to blame the language.

Java 10 added the var keyword so it has some type inference finally.

I would argue that no matter what language you pick, adding abstraction always behaves like this:

Suppose I have a thing I need to do, called X. I write a program to do X. Then later I need to do Y, and I realize that if I think of X as (A + B) and Y as (A + C), then if I re-organize to have one segment of code to do A, then wrap it so that B or C happen afterwards based on context (whether that be polymorphism or different scripts or procedural flow control, whatever the branching mechanism), then I've achieved abstracting A out into its own standalone piece, hopefully because A describes some independent process that makes sense to stand alone. Therefore, I've made it so that B and C's concerns can be separated from A's concerns, and X and Y are now just compositions of these nice linkable, re-usable pieces.

No matter what language you pick, if you want program X to do the same thing, the X-iness needs to still live somewhere. In Java that might look like going from two classes (X and Y) to three classes (A, X and Y). In lisp it might be three functions. I feel like in your example just now, you're comparing A from lisp to X in Java.

Please correct me if I'm wrong. I just feel like when you consider a program holistically, more genericness, and therefore more nuanced program description, always results in more text.

I agree that Java is more verbose than say, lisp or python. But I think that syntactic verbosity is really limited to a per-statement or per-block scope. I disagree that the language itself is responsible for verbosity in the higher-order composition of these pieces, weighted for, of course, how dynamic each language is. I hope you won't fault Java for not having the terseness of Ruby when Ruby doesn't have the performance or rigidity of Java.

I think you only really make order-of-magnitude leaps in reducing verbosity/excess abstraction by sliding up or down the dynamicness vs performance/safety spectrum. Tit-for-tat, I think an equivalent Ruby and Python program will be about the same size, and an equivalent Java and C# program will be about the same size.

The huge asterisk to all this is, of course, the humans actually writing the programs. Obviously a sufficiently motivated developer will be able to make an abstract mess out of any language.


I'll give a concrete example where adding abstraction will make code shorter. This comes from my recent experience, with some details changed for the sake of discretion and simplicity.

Suppose you wanted to simplify the generation of contextual metadata for structured logging in an API service. The service handles requests that manipulate stored records, run logic, etc. Basic CRUD plus business logic.

The starting point is a bunch of raw calls to MDC.put() if a Java service, or an equivalent in another language[0].

An abstraction-free approach might give you a logUser method, a logUserAndAccount method, a logAccount method, a logTransaction method, a logTransactionAndAccount method, etc. This does at least simplify the actual request processing code from the starting point and make the logging consistent, but makes the program longer.

Alternatively, one could have a generic Loggable interface, with a function that returns metadata for the object to be logged, and a logWith method that takes a Loggable as a parameter. You can get fancy and provide a default implementation if all of your entities have common methods like id(). There are probably still ways to improve from here, but now instead of a dozen functions, you have one.

[0] Years ago I wrote a rubygem for this, but was not able to open source the bulk of it.


Most wrong abstractions are created when people anticipate further growth that never comes. I wouldn’t say they are wrong by themselves, but it could be argued you should just refactor your code when you need them.

     > ...too many juniors will read this and think they need more abstraction.
Yes. And that's a good thing.

The way you become "an expert" is by making ALL the mistakes yourself, seeing the results, and doing it over and over again in different contexts until you understand and can do it right (most of the time).


A good thing is making those mistakes but never landing most of them into production. It will boost your progress immensely if you have somebody available to critique and guide you in the right direction. Making mistakes but learning only a month later when significant amount of time has been wasted in wrong things won't make you any smarter than figuring them out before-hand. Also you'll be a lot less confident afterwards doing anything by yourself after such a disaster.

So no, don't make "ALL the mistakes". Learn by observing others around you, emulating it and then finally at some point understanding it clearly enough to make something completely novel.


    > ...making those mistakes but never landing most of them into production. It will boost your progress immensely if you have somebody available to critique and guide...
I mostly agree.

But the consequences of what "landing a mistake in production" actually means depends on a lot on the environment and the project. Does it mean the deliverable has a hiccup and skids past the deadline a few days? Does it mean there's <gasp> a bug? Does it mean a hard-to-maintain big ball of mud that makes people miserable for years? Or does it mean a rocket blows up? All those things happen, of course, but to assign blame on any significant number of these to uppity juniors reading articles that are too advanced for them is a bit of a stretch. There are so many ways projects can fail.

I think we all can agree that juniors need the agency to try things out (hopefully with a few guard-rails installed). Sadly having benevolent mentor watch-over juniors is, in many places, a luxury and they're forced to read "articles on the internet" for guidance. It's not optimal but it's OK.


Sure, it's a vague line. And it's hard already for juniors to have the confidence to make their own decisions or code in general. To have them also fear failure is even worse with everybody fixated on not making any mistakes. But as a constant failurer myself, I don't view falling on your ass all the time as that great of a thing that you should be so careless to let it continuously happen. You have to try your best and be focused, otherwise you'll always half-ass things without learning the right mindset so to speak.

> Learn by observing others around you

Or even better, learn by making mistakes and have great coworkers who can catch those in code reviews.


Mistakes are always a part of the process and are one way to learn.

However I don't think we would have had Ramanujan if he were left to rediscover all of mathematics on his own. Having an expert validate your insights or point you in the right direction can speed up the learning process a lot.


Learning abstractions is really hard, mainly because over or under abstracting doesn't break the code, it just wastes work, and if you keep on erring the same way you won't have a reference for how much work something should have taken.

An "illustrated guide" shouldn't mean shallow content without any practical advice decorated with semi relevant stock photos.

There was a good one, where an eager dog was used to represent the user. I'll be sure to refer to my hard headed business users like that and see how far I go. When they use the UI right, I'm going to be there with a treat.

I will definitely try this method next time I do user testing.

Yeah, I didn't find it helpful at all. It was basically saying, "Experts do great work!" Thanks, I already knew that.

Actually I'm kind of taking back the "semi relevant stock photos" part. On second look I think the illustrations are fine and relevant. The problem is not with the illustrations and not even with the text which is fine too but the mismatch between the title and the content. A bit clickbait-y.

Certainly a book on this topic should be far more interesting than this article makes it look, so rather than dismiss the book out of hand I took a look around.

After looking briefly at the companion site for the book [0] (not much there), then the publisher's page on the book [1] (ditto) I took a look at the table of contents on Amazon [2]. Definitely there are some very interesting items there that I wish they'd used for this article, like:

* Experts sketch: [They] externalize their thoughts

* Experts work with uncertainty: [They] keep options open

* Experts test: [They] are alert to evidence that challenges their theory

Unfortunately, there are no samples of those chapters. Looks like it could be an interesting read, though.

[0] https://mitpress.mit.edu/books/software-design-decoded

[1] https://softwaredesigndecoded.wordpress.com/

[2] Click "Look Inside" https://www.amazon.com/Software-Design-Decoded-Experts-Think...


What happened to avoid listical titles?

> If the title begins with a number or number + gratuitous adjective, we'd appreciate it if you'd crop it. E.g. translate "10 Ways To Do X" to "How To Do X," and "14 Amazing Ys" to "Ys." Exception: when the number is meaningful, e.g. "The 5 Platonic Solids."


Agree

This is basically just marketing for a book

This is basically CS lifestyle marketing.

There's zero useful, actionable content. There's no evidence the authors have any big-project experience of their own, and the bibliography doesn't help make a case for their expertise.

https://softwaredesigndecoded.wordpress.com/annotated-biblio...

In fact it seems to be academic back-seat driving by a pair of authors who don't understand the difference between reading about a domain and living in it, and are now communicating in platitudes. With cutesy pictures.

"You know you could try to make your abstractions more elegant? How about focussing on the essence? Or seeing how someone else did it?"

Thanks. When our next intern slot turns up, we'll be sure to keep you in mind.


> There's zero useful, actionable content.

I agree. With no motivating examples these are just platitudes. Or rather, I suppose if I want the motivating examples and cases, I need to buy the book.


Sounds like you didn’t focus on essence. You could restructure the problem space and just read it.

That's the point of the entire site, though.

"Illuminating the bold ideas and voices that make up the MIT Press's expansive catalog. We publish thought-provoking excerpts, interviews, and original essays written for a general reader but backed by academic rigor."


It's pretty obvious too.

I've always suspected The MIT Press Reader had a secret agenda. The first hint was at the footer of the page:

Illuminating the bold ideas and voices that make up the MIT Press's expansive catalog.


the point is why does it get posted and upvoted if it's so obvious

It’s only obvious when the article gets read, and in my experience many people who vote don’t bother to read

No it's obvious even before that because as the person I responded to points out it's right there in the footer:

>The first hint was at the footer of the page: Illuminating the bold ideas and voices that make up the MIT Press's expansive catalog.


The footer in the article.... if the voter doesn’t read the article I think it’s plainly obvious that they didn’t bother to open the article with the intent of reading it...

Expert Software Designers read. And do it continuously. Not only HN and medium, but big "essence" ideas that you do not get usually on day to day tasks, and mold the perception of problems and solutions.

People familiar with Wirth, Kay, McCarthy, Iverson, Moore's (and pals) works have a fundamentally broader vision of problems and their solutions.

It's obvious, but all those points are not learnt in a discrete manner but they work as a whole and grow on you during the journey.


> Expert Software Designers read

“Read? Books? With pages? And chapters? I don’t pay you to read, I pay you to program! And I’ve seen programming, programming is done with a keyboard, so I’d better hear typing! And I expect you to tell me exactly what you’re going to be doing, hour by hour, for the next two weeks, or ‘sprint’ or whatever you nerds call these things these days, and I’d better see lots of commits to the repository because I’m checking who’s committing the most because I don’t pay you to read and learn, I pay you to know and if you don’t already know there are a thousand foreigners lined up to do your job for ten cents a day so you’d better get in line, programmer!”


oh, hey boss!

I just bought this cherry extraloud MX-blue so you can hear me clickyclacky from your office. And created a deeplearning model to count clicks for our new pay-by-press payroll model. something something democratization :)


What readings would you recommend for an advanced reader?

I don't consider myself that much advanced, but I think Iverson's "Notation as a Tool of Thought"[1], and Wirth's "A Plea for Lean Software"[2] make one rethink many concepts of our daily programming tasks (the 2 articles work at 2 different levels)

But really, anything you grab from any of them is awesome by default.

1. http://www.eecg.toronto.edu/~jzhu/csc326/readings/iverson.pd...

2. https://cr.yp.to/bib/1995/wirth.pdf


The picture for "8) Experts think about what they are not designing:" looks like an optical illusion, but I can only see the two people with their arms on either side. What is the other picture? My guess would be some kind of Lovecraftian monster e.g. Cthulhu [0].

[0] https://en.wikipedia.org/wiki/Cthulhu


They are probably using negative space (e.g., what they did not fill in) to show the picture. Sure, this is often used to show two pictures at once, but I don't think that's the case here.

I think it's mirrored vertically to further reinforce the trope from preschool of cutting out shapes from folded construction paper.


This article has sold me on not buying that book.

I mean, what is this. Not even a point on how Expert Software Designers get bored and browse hacker news for 5 hours?

Terrible.


> Experts focus on the essence

I think this is one of the strongest points of a good developer, and what makes them such good problem solvers in many situations. Often you get confronted with problems, from say a client or through user feedback, which don't amount to much more than "wishes" - with no clear and/or conflicting solutions. A good developer is able to distill the problem down to its core, finds out the true nature of the issue, can communicate that back, while also offering solutions.


9) The expert barely tolerates when the title 'expert' is used by everybody else to merely justify their lack of knowledge in a given area.

"I don't know nothing about databases, but X/Y can solve it because he/she is the software expert".

"I heard you are the expert in firmware, can you fix the coffee machine?"

More or less like the fact one cannot play like Mozart just because Mozart was a 'genius' (putting aside all the effort he put into it since childhood), the same applies to the 'expert'.

Edit: "The expert" https://www.youtube.com/watch?v=BKorP55Aqvg


Why should we listen to these authors? Yes, they have a lot of academic credentials, but is there any evidence they have worked on large systems that have benefited from their designs in practice?

To put it another way, I think that I would find a book about writing by Stephen King to be more informative as a budding author than, say, the dean of the English department at Harvard.

As with all things, I'm sure there may be value on many of the things they've written, but you may need to already be an expert software designer to realize what advice is useful and what isn't.


Most comments cover what I thought about this article (obtuse and too abstract to be practical), so I won't repeat them. However, I did find "The Principles of Computer System Design: An Introduction" by Saltzer to be the best book combining theory and practice.

Part 2 is online: https://ocw.mit.edu/resources/res-6-004-principles-of-comput...


I'd buy all of these if it started with #1: Experts deliver.

Delivery over elegance of delivery any day.

Why is it that all these lists that are seemingly aiming to teach me something always a list of ‘common sense’ items.

Good designers use good abstractions, it’s good to talk to your users... of course, there is nobody that disagrees with these things, but even the most junior of designers knows that.

What the dodo is a software designer by the way. Something from academia?


Haha I keep reading 'Eating Habits of Expert Software Designers'

Thinking ohh that sounds weird, and then seeing it correctly. Feel bad saying it but I'm sort of disappointed now :p


How on earth is content this shallow drifting to the top of HN? Is any "non expert" software designer walking away from this enlightened in some way?

This article is adapted from the book “Software Design Decoded: 66 Ways Experts Think“

I imagine the idea is that if you want to go further, you buy the book.


Okay. Not very effective then.

Yes, it's an advertisement.

Beside the obvious marketing spin, how do you define an "expert software designer"? I remember a long time ago in the pre internet era someone defined an expert as "anyone 40 miles from home". How am I supposed to evaluate someone's opinion as to whether or not I should even pay attention to their habits?

“Eight good recommendations that modern software management practices like Kanban and Scrum work effortlessly to destroy”

Non-experts also do all of these, just badly.

Seriously, aren't we over this "winners do this" bullshit yet?


I am trying to learn more about distributed systems architecture. Currently almost finished reading "Designing Data Intensive Application". Is there any recommendation from HN what book should I read next? I am thinking - Building Microservices - Desining Distributed systems

Any thoughts?


Hey, I'm currently writing a book for PragProg that's going to announced soon. It's tentaively titled "Building Distributed Services with Go", and the Go part is secondary if it's not your language of choice. It guides you through building a distributed service from beginning to end. I don't have anything to point you to at the moment other than my mailing list and I'll let you know when the book is in beta: https://travisjeffery.us4.list-manage.com/subscribe?u=1e3ff7.... Thanks.

Awesome! I will subscribe!

None of these are habits.

they might be considered skills.

The only two skills on there that are useful are involving users, and looking around.

Elegant abstractions? Meh, so long as its simple and works.

What they are not designing? Pfft. if you can't create a clear spec, then you shouldn't really be designing

"as you are such an expert, what is missing?"

1) Communication. If you can't communicate, then you aren't helping

2) Documentation. If its not documented, then its not designed

3) consistency. Just because there are new and shiny thing, doesn't mean you should slam them in.

4) pragmatism. All choices have tradeoffs. Limit the innovation to get things done in time.

There are more, but this is all I can think of right now.


1) Experts involve the user

That right there is the most important one in the list. Also, as a developer, you can be the user. Try to use your design and start punching data using your designed interface. After entering 100 times you'll catch any bad crap you put there and wish for a faster or smarter way to enter it, trust me. Also, monkey your interface to your wife/kid(s)/non-technical friend(s) and they will point fast whatever they find is boring. No need to deploy in the wild to catch the bad design


I started a new company recently and we are a major user of the same back end in our platform that our customers use.

I can say that hopefully never again will I work on a system where the users are remote and isolated from Dev. The benefits of dog fooding are enormous. So many small and large UI discoveries that you would never know about if the input trickled in through jira tickets.

If you want to build an elegant, user-friendly system, then use it yourself. Constantly. Repetitively. Then scratch your own itch.


I don't think there is anything practical to be learned from this writing...

Anecdotally, I've been working in the software industry for only one year (used to be in academia), but I really feel like the main challenge is collaboration and team organization. That, and tackling huge code bases.

Designing abstractions, algorithms, and all that technical stuff really is the easy part.


Point 6 could be rephrased to be more clear. Experts are great at providing original solutions, but they may not always see problems worthy of solutions. By looking around at existing attempted solutions they can estimate the gap between stated and actual problems from their proposed solutions and instead minimize that gap with a better solution.

This reminds me of a great little gem of another MIT Press book: "Software Design Decoded - 66 Ways Experts Think". Clever illustrations and useful, concise insights FTW.

Edit: haha, next time I should RTFA (which clearly mentions it's taken directly from the book I remembered and pulled off the shelf). But my recommendation remains unchanged! :)


While I agree on the content, I think the word "Expert" in the title is misleading. All of these habits are better attributed to Generalists. "Experts" I know are often too focused on certain fields. More power and wisdom comes by connection of experience from different, even orthogonal, domains.

> 2) Experts design elegant abstractions:

I really appreciate the thing called "abstraction" not only in Software Designer but also in general, it often takes large amount of time to be an expert in the field before one can create/design an abstraction out of the problems.


I opened the link and I searched for the word "Simplicity" Found 0 of 0. I decided not to read it in order not to hurt my ego. I might not be an expert software designer as my number one item would have been "seek simplicity"

okay, personally I thought that piece was a little fluffy and made me think of this quote from the Billy Madison movie: <<At no point in your rambling, incoherent response were you even close to anything that could be considered a rational thought. Everyone in this room is now dumber for having listened to it. I award you no points, and may God have mercy on your soul. Billy Madison : Okay, a simple "wrong" would've done just fine.>>

> Experts design elegant abstractions

And a lot of times the most elegant abstraction is no abstraction cough oop cough. Unnecessary abstraction is as wrong as a wrong abstraction.


Yeah, I’m gonna disagree with the “paste, paste, paste “ / “generate mass spam” school of development here.

Many feel like you, though. I just don’t want to maintain their effluent.


I'm not going to claim "expert", but I have designed more software than I can even remember.

Some of my approach:

-- I strive primarily to form a clear and simple mental model of the system that the software will represent.

-- Simplicity is everything in software design and should be priority one. Conversely, you must actively avoid complexity, and when part of a system is starting to feel complex, take a step back and rethink the approach. Sometimes systems must include complexity, try to contain this all into a tightly constrained area of the system.

-- Loose coupling of system components is next most important - priority two - when designing large interconnected systems - you'll succeed in designing something big if you can instead make a number of smaller systems that know as little as possible(ideally nothing) about the other parts of the system.

-- Software is like painting - you can't plan every brush stroke in advance - instead you get the broad brush strokes in place and then paint ever finer levels of detail.

-- I strive for consistency, but not slavishly. Try to use the same approaches/technologies everywhere if possible. When not possible, choose the most suitable technology/approach and use that.

-- I'm extremely hesitant to allow special cases or exceptions, but I will happily do so when it is clearly necessary.

-- I grant myself time to think about possible solutions even when there is pressure (typically from myself) to be actually implementing/coding a solution.

-- I do my best to "design out" or get rid of software - the fastest, easiest to write and most reliable code is no code.

-- I try to lean heavily on the capabilities of existing systems like database and web servers. If you really understand what existing systems are capable of at a deep level then often you can avoid reinventing the wheel and hook in to what those existing systems do.

-- I'm not a fan of complex systems such as containers and kubernetes. I have been able to build all my software architectures without them.

-- The project build should primarily aim to put together a working ended to end system that does the absolute minimum to enable the integrated whole to work - i.e. you need to build just enough of each thing to put a pig in one end and get sausages out of the other..... without much attention to anything like user interface or error handling or really much of anything else at all. This is because it is much easier to complete a system that is working, even if only minimally.

-- I'm happy to throw away previous decisions and system components if they have proven to be wrong.

About 1,000 other things I don't have time to think out right now.


The subtext here is that experts are never "experts", you are constantly iterating and learning.

.... sort +2n | more

less > more


Experts read Hacker News.

Judging by the comments on this article, that is not the case.

What's an expert?

Epstein.



Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: