Live data from Hacker News

Laws of Software Engineering

lawsofsoftwareengineering.com

511–520 of 554 posts

Re: Laws of Software Engineering

#511
post #138

> Premature optimization is the root of all evil. There are few principle of software engineering that I hate more than this one, though SOLID is close. It is important to understand that it is from a 1974 paper, computing was very different back then, and so was the idea of optimization. Back then, optimizing meant writing assembly code and counting cycles. It is still done today in very specific applications, but t…

IMHO "root of all evil" sits there with YAGNI. An useful way to think about the world (overoptimizing early is often as bad as overabstracting, and just as common), but a principle which shouldn't be taken to an extreme.

I think a more useful mental model is of one-way versus two-way decisions (local optimizations can be applied later., the architecture has to be right from the start), as well as expected risks and payoffs.

Re: Laws of Software Engineering

#512

I'd like to propose a corollary to Gall's Law. Actually it's a self-proving tautology already contained with the term "lifecycle." Any system that lasts longer than a single lifecycle oscillates between (reducing to) simplicity and (adding) complexity. My bet is on the long arc of the universe trending toward complexity... but in spite of all this, I don't think all this complexity arises from a simple set of rules,…

I think this site doesn’t capture Gall’s Law correctly, and your observations are closer to the original.

Gall notes that the universe naturally trends toward complexity and unintended consequences and therefore complex designs should be assumed to already be full of these unintended consequence “bugs”. He proposes that systems should be designed:

- with less scope to reduce unintended consequences,

- with less rigidity to allow for workarounds when unintended consequences arise, and

- to take advantage of “momentum” to reduce the required energy to use the system correctly. In other words make the right thing the easy thing, remembering that the easiest thing to do is nothing, thus systems will halt if operators get too busy with other tasks.)

Re: Laws of Software Engineering

#513

Earlier quoted context omitted.

The biggest issue I have with premature optimization is stuff that really doesn't matter . For example, in Java I usually use ConcurrentHashMap, even in contexts that a regular HashMap might be ok. My reasoning for this is simple: I might want to use it in a multithreaded context eventually and the performance differences really aren't that much for most things; uncontested locks in Java are nearly free. I've gotten…

Ironically to your point, I think adding a ConcurrentHashMap because it might be multithreaded eventually IS premature optimisation. The work can be done in future to migrate to using ConcurrentHashMap when the feature to add multithreading support is added. There's no sense to add groundwork for unplanned, unimplemented features - that is premature optimisation in a nutshell.

I would agree if I were adding a dependency to Gradle or something. In this case it’s just something that conforms to the same interface as the other Map and is built into every Java for the last 20+ years. The max amount of effort I am wasting here is the ten extra characters I used to type “Concurrent”.

My point was that even if it is not optimal, there’s really no utility in bickering about it because it doesn’t really change anything. The savings from changing it to regular hashmap will, generously, be on the order of nanoseconds in most cases, and so people getting their panties in a bunch over it seems like a waste of time.

Re: Laws of Software Engineering

#514
post #33

Not a law but a a design principle that I've found to be one of the most useful ones and also unknown: Structure code so that in an ideal case, removing a functionality should be as simple as deleting a directory or file.

What's the smallest unit of functionality to which your principle applies? For example, each comment on HN has a line on top that contains buttons like "parent", "prev", "next", "flag", "favorite", etc. depending on context. Suppose I might one day want to remove the "flag" functionality. Should each button be its own file? What about the "comment header" template file that references each of those button files?

The `comment_header` template would iterate over the files in `comment_header.d/*`, which would, admittedly, need forced sorted naming:

100_parent.template

150_context.template

200_prev_next.template

300_flag.template

350_favorite.template

Looks odd with the numbering, no?

But then you get the added benefit of being able to refer to them by numbers, just "100" or "300" without having to glue humanlang inflection, declension, punctuation onto identifiers that happen to be words...

Some places where you can see this pattern: BASIC's explicit line numbering; non-systemd init systems.

Re: Laws of Software Engineering

#515
post #429

Earlier quoted context omitted.

Even moreso . I like the Rob Pike restatement of this principle, it really makes it crystal clear: "You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is." Moreso, in my personal experience, I've seen a few speed hacks cause incorrect behavior on more than one occasion.

This is true but doesn't help. Parent is talking about building software that is inherently non-performant due to abstractions or architecture with the wrong assumption that it can be optimized later if needed. The analogy is trying to convert a garbage truck into a race car. A race car is built as a race car. You don't start building a garbage truck and then optimize it on the race course. There are obvious principl…

Ha! -- Allow me to introduce you to the US Diesel Truckin Nationals! Here are some dump trucks drag racing https://www.youtube.com/watch?v=aqxpOPeImkw

Re: Laws of Software Engineering

#516
post #438

Earlier quoted context omitted.

Why did they design it like that? It must have seemed like a good idea at the time.

In ancient computing times, which is when C was birthed, the size of integers at the hardware level and their representation was much more diverse than it is today. The register bit-width was almost arbitrary, not the tidy powers of 2 that everyone is accustomed to today. The integer representation wasn't always two's complement in the early days of computing, so you couldn't even assume that. C++ only required integ…

Was it possible to write a program taking into account this diversity, and have it work properly?

Re: Laws of Software Engineering

#518

Earlier quoted context omitted.

> iterative development is in general superior to overly deliberate and overly careful development. I reserve the right to become smarter as I learn stuff. That means that I reserve the right to produce better designs as I learn stuff. Want me to produce better designs? Let me learn stuff . Therefore, let me iterate a few times.

agreed:)

[deleted]

Re: Laws of Software Engineering

#519

I did not see Boyd’s Law of Iteration [0] "In analyzing complexity, fast iteration almost always produces better results than in-depth analysis." Boyd invented the OODA loop. [0] https://blog.codinghorror.com/boyds-law-of-iteration/

[deleted]

Re: Laws of Software Engineering

#520

I did not see Boyd’s Law of Iteration [0] "In analyzing complexity, fast iteration almost always produces better results than in-depth analysis." Boyd invented the OODA loop. [0] https://blog.codinghorror.com/boyds-law-of-iteration/

[deleted]
Post reply on HN