Hacker News new | ask | show | jobs
by parasubvert 1558 days ago
I would agree… except that MOST programming technologies and processes are widely misunderstood, and it feels increasingly so.

Get 10 random senior programmers in a room, and see if they agree on matters of design, code structure, testing, frameworks, system architecture. I’ve been part of summits trying to do this several times over the decades, and the only agreement we wound up with was that “Layered abstractions are sometimes a good idea”.

There is a lot of duplication of effort in languages, frameworks, and tools driven by “I can’t be bothered to learn this new idea, I know better”, and a lot of misunderstanding of even first principles.

Something like TDD (and other XP practices like pairing) reminds me of diet/fitness /nutrition regimens that are notoriously difficult to comply with. This isn’t to say they don’t work: athletes and bodybuilders do exist, as do many successful TDD practitioners. It’s just human nature to avoid things that require mental change, or to be prone to self deception in their application.

5 comments

> Get 10 random senior programmers in a room, and see if they agree on matters of design, code structure, testing, frameworks, system architecture.

I see this often when the problem is abstract. When the problem is concrete, I rarely see this come up in practice.

I routinely have 4-5 senior engineers in a room agree on architecture, design and methodology for a single, specific, project. To me, these abstract disagreements are a symptom of a generalization mismatch.

> Something like TDD (and other XP practices like pairing) reminds me of diet/fitness /nutrition regimens that are notoriously difficult to comply with.

But these regimens do work. It's just that they don't work for the reasons most people believe.

Take fasting. Most benefits of fasting in casual practitioners come from the obvious fact that they aren't consuming as much calories as they did before, so they lose weight. That doesn't mean fasting works in a different way from, say, just eating less.

Same goes for TDD. It may be beneficial because it forces a culture of testing and code coverage, but the root of such benefits may not be writing tests before code, yet that's what most people agree TDD is about.

I thought this was exactly the point of TDD and fasting but maybe I'm going to the wrong church.
Another reason why it's so hard to actually say "tdd does/doesn't work" is that everyone has their own idea what it is.

Its like everything in software engineering: everyone has an opinion, few have actually tested theirs with performant and stable production deployments

I think, additionally, it's domain specific.

There are problems where TDD is actually a decent approach. If you have solid requirements beforehand, and your problem does reduce to small bite sized units with trivial state, then it's amazing for producing code that doesn't surprise you when you run it.

There are problems where it really really really isn't. Things where there is ambiguity in the expected outcome. Language processing for example is fairly difficult to tackle with TDD. There is no simple state, there is no unambiguous expected outcome. Whether "jump" is a verb or a noun non-trivially depends on the context, and it may even ambiguous. The correctness of such code is a percentage value, not a boolean.

For context, when I debug the keyword extraction for my search engine crawler, I'm looking at test output that looks like this: <https://memex.marginalia.nu/pics/frog-text.png> (blue are individual keywords, red are potential n-grams).

Isn't the acronym, test driven development?

All that means to me is that when we start a project we think about what it means for an implementation to be correct and write a test. If we agree on the specification, the test, then a passing implementation means that we have implemented it correctly -- for that particular test.

One of the challenges of using unit tests for this kind of testing is, as you say, difficult with modelling continuous values.

It is also difficult because the "proof" is so small and trivial. You need thousands of examples to gain some confidence... and for even moderately complex software this can not be enough.

Unfortunately, the path to writing good tests and verifying software requires a bit of mathematical vocabulary and reasoning which many developers are too shy to learn or outright hostile towards ("I've never needed no stinking math, this is programming!").

My point is: as long as you're driving the development of your software using testing, I think you're practising TDD.

Unfortunately, it's hard to be put into a position where you can apply one, let alone multiple new approaches to software development on a team developing a large application for a long time (say at least 2 years). You'll have team churn, you'll have requirements churn, you'll have understanding of methodologies and practical realities change, etc.

So by "testing their (opinions)", I usually understand people to mean that they've been on a project where they've enjoyed working on something in a particular way (people always underestimate what someone is simply enjoying doing, I have no idea why). I understand that almost nobody is able to compare and contrast two significantly different approaches, let alone establish things like incident rates or cost of improvement and such resulting from application of those approaches (because there's no reference point).

What we do need is for all developers to contribute to setting up a foundation dedicated to establishing software development methodology quality, and then have that set up a dozen teams of 4-8 engineers working on a dozen longish problems (6-36 months) with different methodologies, and then aggregate and analyze results in 12 years. All the engineers would have market-rate salaries, so we'd all have to be chipping in monthly :D

I mean, just imagine where we'd be if we've done that in 2010? (probably at the same place, but just maybe not!)

Or TMTOWTDI.

Or there's hidden assumptions that differentiate between a Google solution and a coffee shop solution.

Performant... stable... both have ridiculously variable definitions based on who you talk to. That alone is probably enough to get your 10 Sr. developers to provide different solutions.

I don’t think the assumptions are hidden. There is plenty of literature with a reasonable discussion of the range of definitions of performance and scale. It’s that people aren’t even looking for them. It’s about “Team Red vs Team Blue”. Or whatever buzzword needs to be on your resume alongside leetcode for the next interview. NoSQL vs SQL, FP vs OOP. Can’t get my raise if I’m building coffee shop solutions!

The counter to TMTOWTDI is a set of principles and discipline, at least within a team or a project. Not to outright reject the alternatives, but to recognize the power of consistent behaviour and prioritization of tradeoffs, to try to counter the brand allegiances.

> I don’t think the assumptions are hidden.

And yet in the very article we're talking about, there's no explanation of what assumptions the author is operating within.

I'll even go so far to say that most technical articles omit the assumptions - because it's boring content and is less likely to engage the readers.

Most senior engineers I talk to would give you "conditional answers" on those, and I wouldn't be surprised at all.
> Get 10 random senior programmers in a room, and see if they agree on matters of design, code structure, testing, frameworks, system architecture

Programming consist of different schools of thought, similar to philosophy or economics, thus conflicting view points are not necessarily wrong per se, but they collide with your school of thought. Therefore there will always be some disagreement even between the most experienced programmers.

Now there are of course still things that a right or wrong on a factual level within programming, but because different schools also labels things as right or wrong it can be hard to distinguish what is grounded philosophical reasons and what is based on factual reasons.

In my experience, there is little disagreement with how to solve a problem as with the problem being solved.

I've found that within the high performing engineers, they tend to agree quite often with the solution once they agree upon the priorities of features and the problems being prevented.

Development practices are not difficult to comply with because you make them work for you, not the other way around.

The issue that I see in software engineering is the XOR approach. Top-down vs bottom up, abstraction vs implementation. This is the wrong thinking. One of the classic books on software architecture said paraphrased "The architecture drives the implementation and the implementation drives the architecture". A classic book on software development said paraphrased "You design for the implementation you need and implement for the design you want.

It's a yin and yang. But many software engineers completely fail at this. They get stuck at implementation or design. You need both at the same time. They're trying to represent a many dimensional problem one or more dimensions lower than required. They're flat-worlders trying to describe a cube or even a tesseract. Of course there's going to be misunderstandings and mistakes. Everyone has a difference view of the cube. They're technically talking about the same thing, yet fail spectacularly when the parts don't quire align when they come together. The problem is very simple in a higher dimension.