that's the one I was expecting to be there. Computer Science may be a science, but software engineering (to say nothing of "programming") is a series of scar tissue in bits, intermixed with so many different expectations
I expect that if a webpage encounters an error, it tells me that it did; most managers expect that error handling is for paranoid people and slows down ship velocity. Thus, all software is terrible, just to different audiences
Beyond that, engineers have different ways of approaching problems and of crafting the code. TDD may actually work great for one engineer, but be terribly disruptive to another. Engineers working in IDEs tend to have a different idea about what constitutes readable code than ones working in basic editors. There is no one way of writing code that is ideal for every coder.
TDD, as the top-most comment correctly points out <https://news.ycombinator.com/item?id=32509268>, relies on having requirements against which to test, and as very best I can tell, requirements aren't "Agile" because (pick one:) (the users don't even know what they want || there's never time to do it right, but there's always time to do it over)
don't even get me started on the "basic editor" versus IDE war; that's a topic that 100% of the time grinds my gears
Agile isn't about requirements in the sense of "all behaviour of this project must be specified up front" but that doesn't mean for small slices of validated or to be validated behaviour we can't say "this is what it should do" (otherwise nothing sensible would ever get written?)
From that point of view, a developer has what they need to move forward with TDD (or any other process of their choosing).
I've been wanting a documentation system that lets me "cite" tests in support of a claim, such that when a test fails the programmer can see what claims that test was meant to support, which is crucial context in deciding how to fix the code, test, and/or docs.
You just need a testing framework that supports specifying context.
I write my JVM tests mostly using Spock[1] as it's absolutely great at letting me specify, and ecouraging me to do so, as much context as I can.
It may look something like this (this example is loosely based on Spock using Geb[2]):
@Narrative('''
Users can choose to authenticate using method A or B.
This test makes sure that users can choose one or the other, go back and
change their decision later, and complete the procedure with either method.
''')
class AuthenticationMethodsSpec extends Specification {
def 'Users can choose method A'() {
given: 'the user goes to the login page'
goTo(LoginPage)
when: 'the user chooses method A'
page.click('methodA')
then: 'the user goes to the method A login page'
at LoginMethodA
}
Error messages are great too... and the tests, at least when written as above, with actual contextual information everywhere necessary, are much better than the usual JUnit abominations you're likely to find in Java shops.
It may look superficially similar to Cucumber, but it's IMO much better because it's just Groovy code (and I happen to really like Groovy, some people have trouble with it because it's "not exactly like Java"), no custom parsing of text-based stuff and other complex gimmicks.
Sure there are other factors that are involved, but my point was, some coders are more deliberative while others are more exploratory. I'm in the latter group. I think by writing code. I do lots of refactoring and sometimes start over. Writing tests in the middle of that process would result in lots of thrown away test code and a much slower exploration of the problem space. Other coders think through problems first and know what they want before they start. They are more likely to benefit from something like TDD.
Above all else, TDD requires that... ... ...you like working that way.
I dunno why the TDD folks specifically get so zealot-y about it being the one-True Way™. I'm happy that they've found something that they like and are passionate about, but, damn... it seems like they missed the episode of Power Rangers where you learn that different people will like different things than you do, and that that's okay. They don't have to be "wrong" for you to still enjoy your TDD.
> Engineers working in IDEs tend to have a different idea about what constitutes readable code than ones working in basic editors.
I do like beautiful punch card layouts, too. But I'd still not hire someone who uses punch cards to write java. If one cannot configure the "basic editor" to provide basic semantic tools IDEs had for 20 years, then I don't care much about opinions on readability...
I can see arguments either way. IDEs allow people to create complex code effortlessly so the resulting code tends to be more complex. Forcing developers to remember names and file locations causes the developer to try and encapsulate the complexity so they don't have to remember as much. Also, I often need to read code outside of an IDE. If the code was written to be understood that way, it tends to be easier. If I'm going to be living in a single codebase for a long time, I love a good IDE. Having good refactoring tools is awesome. But I often jump around across many codebases across multiple languages and I appreciate if I can make sense of them without firing up some specialized tool.
What situations do IDEs add a bunch of difficult to read code? Auto-adding lines of code for importing things, closing blocks, hints while typing are all pretty clean. I do, however, think Typescript adds a lot of LOC where it often seems unneeded for a responsible developer.
It's not the IDE adds difficult to read code. It's that it makes it easy to write difficult to read code. This is particularly visible in the Java world. For example, the practice of dropping interfaces in front of everything never would have seemed reasonable if you didn't have an IDE that could do that with the click of a button, and the ability to quickly click through an interface to an implementation makes it relatively painless to work with. However, a person without access to an IDE is forced to use text searches to find implementations and has to keep in their head how all these interfaces and classes are organized. Similarly, IDEs make using complex method signatures tolerable with parameter hinting, makes finding method overrides trivial, and autocompletes all those long similar-sounding names like FooFactoryBuilderFacadeAdapter.
In contrast, a developer writing code with a plain editor needs to remember everything and when that becomes difficult, the developer will be forced to either simplify things or encapsulate the complexity so they can forget about it. That code base will be easier to read without tooling because it was built to be understood that way. The developer also has to write each bit by hand, which gives time and motivation to wonder whether what they are writing is necessary.
I could make a similar argument in the other direction as well. Code written by hand tends not to get refactored as much, tends to use too short variable names because of typing laziness, or inappropriate names because renaming variables is not trivial as it is in an IDE. I see the advantages of both, and I find myself preferring the sweet spot of intelligent editors that stop short of knowing everything about your code base.
The more I work with The Cloud, the more I feel like software is alive: Things that used to work, don’t, a piece that works well becomes bloated with logs that needs to be saved and inspected regularly, surgery is sometimes needed to hot-replace log4j with 1.18.2, and anything you connect to the internet can be infected by diseases. Can’t wait for AI-specialized psychologists to intervene to understand how its infancy is related to their adulthood problems.
Along these lines, you can't attach a debugger anywhere and dissect it like some lifeless cadaver. You have to rely on having taught the system in advance to report what's going on and draw conclusions from a set of signals.
I think another factor is that real world software development is a never-ending series of compromises. Compromises of performance vs readability, developer desires vs client demands, and best practices vs "we need that bug fixed now".
Whenever compromises are necessary, conflict inevitably arises, based on what different people value. There are rarely objectively correct answers in software development, which means compromise and arguments are inevitable.
And people are bad at taking a step back to examine what it is that they’re valuing differently. Instead, they just argue about the “correct answer” even though they’re coming from different starting points.
"Sometimes"? I'd say 95% of them suck and more often than not, religious-like beliefs get in the way... as usual in all human discourse.
People like me who moved on from several different technologies during their career -- even though they have built profitable sub-careers on their shoulders -- seem to be an exception. I didn't expect that. I was convinced that programmers are rational and ruthlessly effective and that everyone is like me: they will understand and realize the limitations of what they work with and will move to something that serves them and the business better.
Oh, how wrong I was.
So yeah, most such discussions are like various religious fanatics screaming at each other. With time I severely dialed down my participation in such "discussions" and nowadays I only comment on HN and leave the occasional (read: 1-2 times a month) comments on Reddit. And I have trained myself to care less and less if somebody disagrees with me for emotional reasons or due to sunk cost fallacy. It's extremely tiring to explain those to people, from scratch, every time, and them eventually ending up saying stuff like "I don't know man, you might be right but I still believe that..." -- and proceeds to repeat something we disagreed on 20 times already.
No time or energy for that stuff anymore. If you want to believe, then believe. Not my problem anymore, and nowadays I wonder why it was ever my problem in the first place (in the past).
You care because most often it is your problem still. For example, when you know with facts that a given technology is less error prone than another. But the other party still picks the worse one. When a year down the line shit hit the fan, it usually ends up back on you. Because you are the only one with enough knowledge and expertise to even understand the mess they put themselves in.
I'm certainly in the defensively argumentative crowd. Eventually, as someone who likes doing this work, a single/series ends up being a massive albatross on the team until the project dies or someone steps up. That's often me, because I don't want to be miserable. Sometimes the choices are so monumentally bad, there is no way to fix it. It's just a miserable death march.
Yeah, I am very much the same (if I read you correctly): I get it that maintenance is more important than "devs playing with new shiny toys" -- a saying over which I slammed a manager in a high-level meeting and I didn't flinch doing it; I'd do it again! -- BUT sometimes it's painfully obvious, usually months later, that using tech X or Y just makes it that much harder to maintain the software.
There are points at which difficult decisions have to be made. It's a shame most managers / CTOs / VPs of engineering are so cowardly and idolize not being spotted by upper management for having a few hiccups in their projects, over any other concerns.
I have no patience for their political in-fighting in companies so I usually arrive at a contract, beat a bunch of things into shape, reduce test failures, simplify deployment, introduce a few conventions (and document them) that make it easy to change code, make 1-2 high profile and very requested features and then usually end up leaving 6-9 months in -- simply because I start getting included in the political games. At that point I am like "hell no" and just move on.
"For example, when you know with facts that a given technology is less error prone than another."
I am sorry, but this sounds a bit like you are in the fanatics camp.
It always depends on what you want to build and what is the given skillset of the people and the avaiable time.
Bad teams will mess up even with the best technology and good teams can deliver with outdated imperfect languages. And good teams can disintegrate over religious tech wars ..
This is always down to context -- so please don't generalize somebody as a fanatic.
Many times during my work it has become apparent that (some examples follow):
1. We constantly introduce bugs due to the dynamism of the language we use. We had in-house devs that could have rewritten a few very small services (think 20-ish endpoints, we're not talking rewriting a mastodon with 500+ here) in a static strong typed language. Alas, almost everyone mercilessly shot that effort down even though it was right in everyone's faces how that will reduce the upkeep of bugs and maintenance with at least 50%, if not 80%.
2. Somebody figured it's a genius idea not to follow the conventions of a certain web framework. At least 15 people came and left over the course of a year and they all struggled hard to adapt. It's not because they're stupid; it's because you have a well-working schemata in your head that you have to undo many times over just so you can work in a single team / company. Eventually all these people figured it's not worth it and I can relate to them (even though I and several others had no difficulty adapting).
3. At one team somebody decided that the in-VM cache implementation is buggy -- even though it absolutely is not because otherwise even stuff like WhatsApp wouldn't function well, btw! -- and they said "hey, let's not only use Redis for cache" (which is fine) "...but also let's use it for mutexes and semaphores that span several computers" (lol). Only after me and another senior threatened to leave did management finally budge and they left us to rewrite the thing which resulted in smaller Dockerfiles, simplified deployment, inadvertent fixing of 20-30 intermittently failing integration tests, and reduction of coding lines by about 1200 (in a project with 11500-ish coding lines so 10% decrease). Then we still left afterwards btw, both of us together, because management figured we're some kind of a threat and sabotaged us at every turn afterwards. Petty small humans ignoring feedback from users and other dev departments telling them we did the right thing. Those I'd call fanatics.
Point is, people want one thing to "just work" and never touch it again, and then proceed to use fluff language to disguise this like it's anything else BUT that. Some of us see through that BS.
Yes, error-prone tech exists. Yes, projects get improved by the removal of those. And I truly believe all this mindset of "you can do your project in ANY tech and it won't make a difference" seriously has to stop. This has been demonstrably false throughout most of computing's history.
Maybe "absolutist" would have been the better word, but yes - it is always down to context, which was my point: the language the person I was replying to, sounded to me like there is good tech and bad tech independent from context.
"And I truly believe all this mindset of "you can do your project in ANY tech and it won't make a difference" "
But this sounds a bit like strawman, I never heard anyone ever making that claim.
Of course it makes all the difference which tech you choose for the job.
Rust is supposed to be good, but no (sane) person would try to script a website with it.
I mean you can use it and compile it to wasm and for big web applications that might even make sense - but for a really simple website I also would not even use typescript, but plain ugly javascript. No complex toolchain, no compiling, no transpiling - and allmost anyone can understand immmediately, what is going on and how to change something.
But sure, if you put stupid people in charge, they will use "simple javascript" where it is just too simple and make everything harder as a result, but this is hardly the fault of javascript.
(oh btw. today I learned that the James Webb Telescope runs javascript internally as a scripting language .. but without details, I will not judge here)
> But this sounds a bit like strawman, I never heard anyone ever making that claim.
Ah, but I am not saying that you said it. Sorry for not clarifying. I meant that in such similar discussions this point comes up VERY often here on HN which is just giving me the saddest of blues because the people around here really should know [much] better.
RE: Rust and web apps backends, I agree completely, that's why I use Elixir for that and it's honestly a sanity saver (not trying to convert you). For everything else I started making a best effort to use Rust -- although likely I'll retire part of my bash/zsh monstrosity scripts in favor of Golang, or maybe OCaml once its parallel story fully stabilizes.
"Ah, but I am not saying that you said it. Sorry for not clarifying. I meant that in such similar discussions this point comes up VERY often here on HN which is just giving me the saddest of blues because the people around here really should know [much] better."
Yeah, I know it was not directed at me, but I do not recall anyone making such statements ..
A big thing I think is left out is how deeply personally invested people get in the language(s) and tool(s) they use. Technical discussions around those things become perceived as personal attacks and reasonable discussion is impossible.
I could be wrong, but I feel like a lot of the most ardent defenders are people who stick to one/a couple of languages and tools. As someone who loves a lot of languages and has liked a lot more before falling out of love, I also tend to have a bit more critical eye because I've seen the warts by comparing one language to another. No tool is perfect.
It would be interesting to see which tools people are the most defensive about. I've certainly noticed a lot of JS defenders who ignore how insane some of the weirdness of that language (never mind the ecosystem) are, but one person's observations aren't data.
This is exactly right. For every developer who hated so and so framework, there may have been a developer who absolutely loved it. And they’re both “right”.
Most decisions do not have a right or wrong, just trade-offs that some developers would make, others wouldn’t.
"Everyone is always right" [in the limited scope of their argument, which may be different to yours] is an important realisation in life, and makes you approach disagreements very differently (i.e. tease out differences in scope, rather than prove someone "wrong". Which they're not. Because "Everyone is always right").
Or as Patrick Lencioni says in his excellent book "Five Dysfunctions of a Team": don't aim for consensus, aim for buy-in.
34 comments
[ 2.9 ms ] story [ 66.8 ms ] threaddue to https issue and my corporate firewall was blocking it.
that's the one I was expecting to be there. Computer Science may be a science, but software engineering (to say nothing of "programming") is a series of scar tissue in bits, intermixed with so many different expectations
I expect that if a webpage encounters an error, it tells me that it did; most managers expect that error handling is for paranoid people and slows down ship velocity. Thus, all software is terrible, just to different audiences
don't even get me started on the "basic editor" versus IDE war; that's a topic that 100% of the time grinds my gears
From that point of view, a developer has what they need to move forward with TDD (or any other process of their choosing).
I write my JVM tests mostly using Spock[1] as it's absolutely great at letting me specify, and ecouraging me to do so, as much context as I can.
It may look something like this (this example is loosely based on Spock using Geb[2]):
Error messages are great too... and the tests, at least when written as above, with actual contextual information everywhere necessary, are much better than the usual JUnit abominations you're likely to find in Java shops.It may look superficially similar to Cucumber, but it's IMO much better because it's just Groovy code (and I happen to really like Groovy, some people have trouble with it because it's "not exactly like Java"), no custom parsing of text-based stuff and other complex gimmicks.
[1] https://spockframework.org/spock/docs/2.1/index.html
[2] https://www.gebish.org/
I dunno why the TDD folks specifically get so zealot-y about it being the one-True Way™. I'm happy that they've found something that they like and are passionate about, but, damn... it seems like they missed the episode of Power Rangers where you learn that different people will like different things than you do, and that that's okay. They don't have to be "wrong" for you to still enjoy your TDD.
I do like beautiful punch card layouts, too. But I'd still not hire someone who uses punch cards to write java. If one cannot configure the "basic editor" to provide basic semantic tools IDEs had for 20 years, then I don't care much about opinions on readability...
In contrast, a developer writing code with a plain editor needs to remember everything and when that becomes difficult, the developer will be forced to either simplify things or encapsulate the complexity so they can forget about it. That code base will be easier to read without tooling because it was built to be understood that way. The developer also has to write each bit by hand, which gives time and motivation to wonder whether what they are writing is necessary.
I could make a similar argument in the other direction as well. Code written by hand tends not to get refactored as much, tends to use too short variable names because of typing laziness, or inappropriate names because renaming variables is not trivial as it is in an IDE. I see the advantages of both, and I find myself preferring the sweet spot of intelligent editors that stop short of knowing everything about your code base.
Lol. I will use this from now on: A software engineer is a computer scientist with scar tissue.
Whenever compromises are necessary, conflict inevitably arises, based on what different people value. There are rarely objectively correct answers in software development, which means compromise and arguments are inevitable.
People like me who moved on from several different technologies during their career -- even though they have built profitable sub-careers on their shoulders -- seem to be an exception. I didn't expect that. I was convinced that programmers are rational and ruthlessly effective and that everyone is like me: they will understand and realize the limitations of what they work with and will move to something that serves them and the business better.
Oh, how wrong I was.
So yeah, most such discussions are like various religious fanatics screaming at each other. With time I severely dialed down my participation in such "discussions" and nowadays I only comment on HN and leave the occasional (read: 1-2 times a month) comments on Reddit. And I have trained myself to care less and less if somebody disagrees with me for emotional reasons or due to sunk cost fallacy. It's extremely tiring to explain those to people, from scratch, every time, and them eventually ending up saying stuff like "I don't know man, you might be right but I still believe that..." -- and proceeds to repeat something we disagreed on 20 times already.
No time or energy for that stuff anymore. If you want to believe, then believe. Not my problem anymore, and nowadays I wonder why it was ever my problem in the first place (in the past).
There are points at which difficult decisions have to be made. It's a shame most managers / CTOs / VPs of engineering are so cowardly and idolize not being spotted by upper management for having a few hiccups in their projects, over any other concerns.
I have no patience for their political in-fighting in companies so I usually arrive at a contract, beat a bunch of things into shape, reduce test failures, simplify deployment, introduce a few conventions (and document them) that make it easy to change code, make 1-2 high profile and very requested features and then usually end up leaving 6-9 months in -- simply because I start getting included in the political games. At that point I am like "hell no" and just move on.
I am sorry, but this sounds a bit like you are in the fanatics camp.
It always depends on what you want to build and what is the given skillset of the people and the avaiable time.
Bad teams will mess up even with the best technology and good teams can deliver with outdated imperfect languages. And good teams can disintegrate over religious tech wars ..
Many times during my work it has become apparent that (some examples follow):
1. We constantly introduce bugs due to the dynamism of the language we use. We had in-house devs that could have rewritten a few very small services (think 20-ish endpoints, we're not talking rewriting a mastodon with 500+ here) in a static strong typed language. Alas, almost everyone mercilessly shot that effort down even though it was right in everyone's faces how that will reduce the upkeep of bugs and maintenance with at least 50%, if not 80%.
2. Somebody figured it's a genius idea not to follow the conventions of a certain web framework. At least 15 people came and left over the course of a year and they all struggled hard to adapt. It's not because they're stupid; it's because you have a well-working schemata in your head that you have to undo many times over just so you can work in a single team / company. Eventually all these people figured it's not worth it and I can relate to them (even though I and several others had no difficulty adapting).
3. At one team somebody decided that the in-VM cache implementation is buggy -- even though it absolutely is not because otherwise even stuff like WhatsApp wouldn't function well, btw! -- and they said "hey, let's not only use Redis for cache" (which is fine) "...but also let's use it for mutexes and semaphores that span several computers" (lol). Only after me and another senior threatened to leave did management finally budge and they left us to rewrite the thing which resulted in smaller Dockerfiles, simplified deployment, inadvertent fixing of 20-30 intermittently failing integration tests, and reduction of coding lines by about 1200 (in a project with 11500-ish coding lines so 10% decrease). Then we still left afterwards btw, both of us together, because management figured we're some kind of a threat and sabotaged us at every turn afterwards. Petty small humans ignoring feedback from users and other dev departments telling them we did the right thing. Those I'd call fanatics.
Point is, people want one thing to "just work" and never touch it again, and then proceed to use fluff language to disguise this like it's anything else BUT that. Some of us see through that BS.
Yes, error-prone tech exists. Yes, projects get improved by the removal of those. And I truly believe all this mindset of "you can do your project in ANY tech and it won't make a difference" seriously has to stop. This has been demonstrably false throughout most of computing's history.
"And I truly believe all this mindset of "you can do your project in ANY tech and it won't make a difference" "
But this sounds a bit like strawman, I never heard anyone ever making that claim.
Of course it makes all the difference which tech you choose for the job.
Rust is supposed to be good, but no (sane) person would try to script a website with it. I mean you can use it and compile it to wasm and for big web applications that might even make sense - but for a really simple website I also would not even use typescript, but plain ugly javascript. No complex toolchain, no compiling, no transpiling - and allmost anyone can understand immmediately, what is going on and how to change something.
But sure, if you put stupid people in charge, they will use "simple javascript" where it is just too simple and make everything harder as a result, but this is hardly the fault of javascript.
(oh btw. today I learned that the James Webb Telescope runs javascript internally as a scripting language .. but without details, I will not judge here)
Ah, but I am not saying that you said it. Sorry for not clarifying. I meant that in such similar discussions this point comes up VERY often here on HN which is just giving me the saddest of blues because the people around here really should know [much] better.
RE: Rust and web apps backends, I agree completely, that's why I use Elixir for that and it's honestly a sanity saver (not trying to convert you). For everything else I started making a best effort to use Rust -- although likely I'll retire part of my bash/zsh monstrosity scripts in favor of Golang, or maybe OCaml once its parallel story fully stabilizes.
Yeah, I know it was not directed at me, but I do not recall anyone making such statements ..
It would be interesting to see which tools people are the most defensive about. I've certainly noticed a lot of JS defenders who ignore how insane some of the weirdness of that language (never mind the ecosystem) are, but one person's observations aren't data.
Most decisions do not have a right or wrong, just trade-offs that some developers would make, others wouldn’t.
But seriously don’t use crappy ORMs.
Or as Patrick Lencioni says in his excellent book "Five Dysfunctions of a Team": don't aim for consensus, aim for buy-in.