Live data from Hacker News

It's not a hack to satisfy known requirements

charemza.name

41–50 of 60 posts

Re: It's not a hack to satisfy known requirements

#41
post #6

I have an engineer on my team that's always asking "what if this or that happens in the future?" to which I've started to reply "what if it does NOT?" I know, I know... wow. Not much insightful. But for some reason with this particular engineer this is the starting point to talk about actual requirements. This question in particular triggers the conversation of going back to product to figure out what they truly know…

I find that these discussions happen in teams that lack experience.

It's common for junior engineers to want to over-engineer stuff: they want to pull this cool library, they want to try this nice pattern, and over all they want to make a good job and a complex architecture sounds like they put more effort into it than a two-liners. That's why junior engineers are not the team lead.

As the lead, many times it's difficult to prove why it's over-engineering. You can often only say "hmm what you suggest is pretty complicated, requires a lot of effort, and in this case I don't think it's worth it".

What makes your take more valuable than the junior engineer's take? Experience.

Now don't get me wrong: it does not mean AT ALL that juniors don't bring anything valuable. They often bring great ideas. But their lack of experience means that sometimes it's harder for them to understand why it's "too much". The lead should listen to them, understand what they say (and by that I mean that they should prove to the junior that they understand), and then refuse the idea.

If a junior feels like the lead is incompetent (i.e. does not understand their ideas and selects inferior solutions instead), then the team is in trouble. And in a way, it is the lead's responsibility.

Re: It's not a hack to satisfy known requirements

#42
post #10

I find that strong typing often obviates the need for unit tests. Software breaks when data transforms in a way that typing can't solve. When data goes across a wire, or into a database, it leaves your space. Anything you do to your code risks breaking it. Integration tests solve that, but at a very high cost. I don't have a great solution for that. It just comes down to experience: how do things change over time? Yo…

Strong typing does not obviate the need for unit tests. It just obviates the need for the simplest ones about passing incorrect types. These are now being obviated anyway due to typecheck static analyses being added to most commonly used untyped languages (python and typescript over javascript, for example).

Re: It's not a hack to satisfy known requirements

#43
I wish more engineers I worked with had a stronger personal belief that design and planning is a favour they do for themselves. Defining clear requirements and resolving unknowns (or at least identifying them) is the foundation that if you don’t build, you’ll be building your project many times.

Re: It's not a hack to satisfy known requirements

#44

It's all pretty solid except for the part about OO. Inheritance almost never works in "the real world" but I find being able to tie functions to the data they're expected to work on to be pretty helpful. It's sort of like typing, really, functionX can only take FooBar variables vs making methodX on class FooBar. Like everything else you can "do it wrong" and you shouldn't be a slave to any particular software ideolog…

I feel like people who say "OO is never right" don't understand how to use it properly. Applies to other concepts as well, of course.

There are tools, and we as professional are expected to use them when they make sense. That's all. If you use a tool badly, don't blame the tool.

Re: It's not a hack to satisfy known requirements

#45

> One of the worst pieces of advice that I ever received was that every function should be unit tested. Obviously not every function should be -- many are so obvious and straightforward that there's nothing to test -- but every function that does anything vaguely "algorithmic" should be. Unit testing is really important for catching logic errors. > Instead, write higher level tests close to the client/user facing beh…

> Yes, these are good. But they're a different kind of test. There are tests for correctness, and tests that the program runs. You need both.

Why do you need both?

Some software is so small and simple that it's possible to write a high level running/integration test that covers all the practical correctness tests that application might need too.

You can say "yeah, but they'd be better if they had unit test" but that's the point being made: eventually you reach a place where more tests, even those recommended as best practice, don't actually deliver any more _real world_ value, and even make the code harder and slower to maintain.

Re: It's not a hack to satisfy known requirements

#46
post #37

It's all pretty solid except for the part about OO. Inheritance almost never works in "the real world" but I find being able to tie functions to the data they're expected to work on to be pretty helpful. It's sort of like typing, really, functionX can only take FooBar variables vs making methodX on class FooBar. Like everything else you can "do it wrong" and you shouldn't be a slave to any particular software ideolog…

I came to the comments to try find a similar sentiment. I agree wholeheartedly with the author on everything apart from the bit about OO, where I feel the same as you. What's the deal with this? I'm not an OO evangelist at all, but I often find myself using objects like you describe: as a mechanism to group related functions and data. I feel there are people who see OO like a philosophy on how to architect stuff, and…

I think the specific trap the author is arguing against is where you try to make your classes model 1-1 some external domain model without tailoring them only to the functionally that your specific application needs. If you’re writing a FooClass, it’s easy to get caught up in giving it everything a Foo would have, even if you won’t actually use it.

Re: It's not a hack to satisfy known requirements

#47
post #4
post #3

I think I needed this right now, thank you.

You’re very welcome! Have to admit I am curious: what’s the context / how has it helped you more specifically?

It's going to take me some time to come to terms with what you have to say; I'm probably not going to be able to internalize it today, and my gut reaction to it is, "I hate it; I'm over-engineering for a reason! I'm going to be better for it and my output is going to be better for it!" but this kind of thing has had me hung up on simple things at every turn. A present example is, I'm going through Chapter 1 of ANSI K&R as a refresher (I'm not a programmer) and I've been stuck on exercise 1-21, "entab", which is presented as follows:

/* 1-21. Write a program entab that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference? */

When confronted with a problem like this, I begin to think, "Well what's the most robust way of going about this task? What's a simple, good, and useful rule that will accomplish the stated goal?" And I'm not quite sure what happens next - figuring that out might require some deeper introspection, but I end up with the proposed solution:

"Any time we encounter consecutive whitespace characters, including spaces, tabs and newlines, ignore the literal characters and instead simply add up exactly how many columns of whitespace they are going to take up, and then, find the smallest number of newlines, tabs and spaces we can print to the screen to match that amount of whitespace. This way we accomplish the stated goal and also end up with a nice text sanitizer."

I'm still mulling all of this over but I'm pretty confident this goes so far beyond the stated problem that it could be considered self sabotage. There's a lot of moving parts to my solution and I don't have the cognitive tools to break up a problem like that yet. (I'd like to eventually of course, but I have to stay focus on what I'm doing!)

Tangentially related maybe? Witches' Loaves https://www.littlefox.com/hk/supplement/org/C0002439

Re: It's not a hack to satisfy known requirements

#48
post #34

I am amazed by the number of articles like this, that essentially say "you should not write bad code, you should write good code", while somehow implying "listen to me, I know better " (otherwise I wouldn't write the article...). The truth is that writing good code takes experience. Those who live by the rule "thou shalt not over-engineer" risk writing bad code. Those who live by the rule "thou shalt know all the pat…

Yes. One either develops systems that work well and scale reasonably, or brittle ones without basic foresight, that keep failing and keep bad engineers employed. Especially if one is putting out open source software, one should take the time to engineer them well, not under-engineer them.

Re: It's not a hack to satisfy known requirements

#49

Earlier quoted context omitted.

> I find that strong typing often obviates the need for unit tests. Can you expand? Because my experience is they are totally orthogonal. For me, unit testing is to ensure the function's algorithm is correct. You verify add(2, 3) == 5 and add(1, 2, 3) == 6 and add(2, Null) == Null. But you don't generally write unit tests that tests how a function behaves when you pass an unexpected type. Nobody in my experience is t…

For certain classes of dynamically typed languages the unit test serves the function that a compiler or linter would perform just by running the code on any input to ensure it can run at all. Basically since these checks are runtime instead of compile time, you have to run the code to get even basic syntactical checking. I think ruby, python and JavaScript all used to use unit tests in this way. These days static ana…

That is because typing in this case is converting a semantic (run time) property into a trivial property (T/F).

It is just making a trade off that is often a reasonable pragmatic default, but if taken as an absolute truth, can lead to brittle systems stuck in concrete.

Not all problems can be reduced to decision problems, which is what a trivial property is.

For me looking at how algebraic data types depend on a sum operation that uses either tagged unions or disjoint unions is a useful lens into the limits.

Note that you can use patterns like ports and adapters which may help avoid some of that brittleness, especially with anti-corruption layers in more complex systems/orgs or where you don’t have leverage to enforce contracts.

But yes if you can reduce your problems to decision problems where you have access to both T and F via syntactic or trivial semantics you should.

But when you convert pragmatic defaults to hard requirements you might run into the edges.

Re: It's not a hack to satisfy known requirements

#50
post #34

I am amazed by the number of articles like this, that essentially say "you should not write bad code, you should write good code", while somehow implying "listen to me, I know better " (otherwise I wouldn't write the article...). The truth is that writing good code takes experience. Those who live by the rule "thou shalt not over-engineer" risk writing bad code. Those who live by the rule "thou shalt know all the pat…

> . If you need to justify your lack of "something" ("It's not a hack because..." or "I don't use OOP because..." or "I duplicated this code because..."), then it feels like it says something about your opinion of your own code, IMHO.

I feel this sort of opinion is simplistic. "Explaining" is a need that is sparked by both sides. Just because someone is having doubts or questioning your work that doesn't mean they are automatically right and you are automatically bounded to introduce changes. Sometimes you do get questions from people who don't even have context on the problem domain and why you are taking path A instead of path B.

Also, sometimes your choices can be questioned by opinionated peers who feel compelled to bikeshed over vague and subjective styles instead of objective technical issues. Is this something that should cause churn in your PRs? To give an example, once I had the displeasure of working with an opinionated junior developer who felt compelled to flag literally white spaces as critical problems in a PR because said junior developer instead of onboarding a source code formatter decided to write a personal markdown file with their opinions on style, and was trying to somehow force that as a reference. Is this sort of demand for justifications something you think should be accommodated?

Post reply on HN