9 ms·
I once, a long time ago, had a similar argument (somewhere online) with a bunch of Java coders. I asked them to create a library for solving quadratic equations
by mojuba 4y ago
I once, a long time ago, had a similar argument (somewhere online) with a bunch of Java coders. I asked them to create a library for solving quadratic equations. Asking to create a library itself was a trap of course.
Everybody came up with some solver classes in Java, some stateful, some stateless. One guy presented the most monstrous solution with 100+ lines of code where you could individually assign the coefficients, individually modify them, trigger recalculation, get the number of roots, get the roots. That guy was very proud of what he did.
Oh, I found bugs in his code. But that was considered normal. People make mistakes, right?
I showed them a two-line solution with a single function (where you'd try hard to make a mistake) and nobody liked it. I was ridiculed right there, for not solving the problem "properly".
It struck me how someone can overengineer a solution to the simplest problem and be proud of it. I thought at the time this industry is screwed if this is the norm.
In fact probably some 90% of so called library code on GitHub is overenginnered crap. 90% is arbitrary but from my experience every time I look for some solution let's say for some GUI effect on iOS, find a library or a framework, take the source, analyze it, start simplifying it and I end up with a version that is orders of magnitude shorter and can be just copied into my project it's so trivial.
You realize that it was so trivial that there was no need for a library in the first place.
I liked the post about minimaism the other day here on HN [1]. It still amazes me how minimalism is not the norm, is not taught as the only way you should solve problems in software engineering. There's no "proper" way other than the most minimalist one, period.
However, minimalism requires some extra effort to achieve, and that's the whole point of engineering.
[1] The post was about minimalism in programming languages, but the author had another, more general post: https://pointersgonewild.com/2018/02/18/minimalism-in-programming/ https://pointersgonewild.com/2018/02/18/minimalism-in-progra...
Edit: mandatory favorite essay: http://www.paulgraham.com/power.html http://www.paulgraham.com/power.html
- agumonkey 4y agoLack of constraints.. I'm sure having no memory, no cycles or not even computer access time made people aim at diamonds, not tar pits. One thing I'd add over the 'screwed industry', at least in the java,model era is that the more they added, the more "tools" they needed and it was seen as a quality. Basically quadratic complexity at the cultural level.. ps: as usual, https://duckduckgo.com/?q=stop+writing+classes+pycon&t=ffab&ia=web https://duckduckgo.com/?q=stop+writing+classes+pycon&t=ffab&...
- mojuba 4y agoIs it just lack of constraints though? Minimalism also guarantees improved maintainability and fewer bugs in the code. The less you write, the fewer mistakes you make, it's that simple.
- watwut 4y agoNo, not really. Minimalism where I had seen it lead to spaghetti like hard to maintain and decipher the code. It was impossible to think about larger units, you had to juggle details of everything in head at the same time.
- alphanumeric0 4y ago.. that sounds like the opposite of minimalism.
- eurasiantiger 4y agoExactly the opposite in my experience. The worst maintainable code is usually the minimal ”prototype” or ”MVP” solution. Couple it with time pressured continuous development and you get spaghetti. Maintainable code has sane abstractions, it wraps external dependencies, and it has minimal interfaces between them and other code. Minimal here doesn’t mean quantitatively minimal but qualitatively minimal.
- mojuba 4y agoSpaghetti is not minimalism, it's quite the opposite. You should minimize dependencies, minimize every function, avoid repetitions, etc. What you mean by MVP that evolves into spaghetti is called "incompetence".
- jacquesm 4y agoIt's not the whole story, but budgets tend to get burned, regardless of whether we're talking about money, time, CPU cycles, RAM, disk storage and so on.
- arethuza 4y agoI swear I've worked with people who if they were shown FizzBuzzEnterpriseEdition wouldn't be able to see the joke as that's how they naturally write all code. https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris... Things like this: static final int INT_1 = 1; I've actually seen production code with: static final string HTTPS = "https"; static final string COLON = ":"; static final string SLASH = "/";
- samatman 4y agoSomething like `SECURE_HEADER = "https:// https://"` and `PLAINTEXT_HEADER = "http:// http://"` can spare real headaches down the road.
- motogpjimbo 4y agoHow?
- zoul 4y agoThe s that’s so easy to miss can make a big difference in some cases.
- motogpjimbo 4y agoIt just goes to prove how realistic FizzBuzz Enterprise Edition is that I can't tell when people are joking about stuff like this or when they're deadly serious. In fact, I came across a line of code that was basically `two = 2;` in my own company's codebase just a few days ago.
- brewmarche 4y agoWhen you introduce a typo in a literal you will typically realise at runtime. Referencing a non-existing field won’t make it through compile time. I honestly don’t see the problem with this approach. I would choose better (semantic) names though.
- kgeist 4y ago>You realize that it was so trivial that there was no need for a library in the first place Minimalism can bite you, too. We have around 30 microservices written in Go, each one one of them living in their own repository (separate codebases owned by different teams). Initially we followed Go's idiom "a little copying is better than a little dependency". So every team simply was borrowing code snippets from other microservices' codebases without creating a common shared library, because those snippets were "trivial". Then it hit production and we found that under load/diverse user input many of those trivial functions were quite buggy or inefficient with edge cases. Since those functions/classes were copypasted over multiple codebases, now you had to contact owners of 30 repositories and coordinate bugfixing in all of them, which is slow and painful. Now we're back to having a shared library of common functions, because it's well tested and it's easy to fix bugs by just upgrading. Often what seems trivial is not trivial at all.
- withinboredom 4y agoIt sounds like what you described is not minimalism at all, except from the perception of individual teams. From the perspective of the product, your solution is minimalism.
- mojuba 4y agoI'd argue that's not minimalism. A lot of the times it relies on the engineer's intuition: is this trivial enough that it can be copied? If as you say those trivial functions were buggy and nobody saw the red flags while copying so many times by so many engineers, then you have an organizational problem.
- kgeist 4y ago>If as you say those trivial functions were buggy and nobody saw the red flags while copying so many times by so many engineers, then you have an organizational problem. If all potential problems with code could be noticed on spot, we wouldn't have the concept of "bugs". Yes, I mentioned minimalism in my post, but I was specifically referring to the idea of copying "trivial" code as opposed to using a dependency.
- ljosifov 4y ago"Succinctness is power" is illustrated nicely in the array/matrix languages. Code working on time series - switching away from a matrix language seems to increase code size by a factor of x5 - x7 times. It is mentally taxing. What was a word before, is now a sentence.
- arinlen 4y ago> I asked them to create a library (...) I showed them a two-line solution with a single function (...) and nobody liked it. I was ridiculed right there, for not solving the problem "properly". And did you solved the problem "properly"? Odds are you did not. I mean, it's terribly easy to come up with all sorts of two-liners if you just ignore all requirements and constraints, and don't pay attention to usecases. This is a major problem plaguing software development. Plenty of people act like they have to carry the burden of being the only competent and smart individual in a sea of fools, and proceed to criticize everything that everyone around them does, for the sin of not doing something that exactly matches your personal opinions and tastes.
- flohofwoe 4y agoThis is just another potential problem of "overengingeered" libraries: they often try to offer a general solution to a whole set of somewhat related problem, but each individual user may just need one specific problem solved, and the correct solution for this one problem may indeed just be a very simple "two-liner". Best example are C++ stdlib classes like std::vector. Sometimes you just need a trivial growable array implemented in a few dozen lines of code, but std::vector pulls in roughly 20kloc of code into each compilation unit, and only if you're very lucky the compiler will condense this down to the same few dozen lines of actually needed code (the fabled "zero cost abstraction"). IMHO OOP languages are more prone to this sort of code bloat problem because they require (or at least "expect") to write a lot of "ceremony code" which is entirely unrelated to the actual problem (such as in C++: constructors, destructors, copy-, move-operators, etc etc... and the actually important "two-liner" problem-solving method is completely buried).
- wruza 4y agoPart of this problem is underconstrained requirements. If you do not specify that “a” can’t be zero in “ax2”, it’s reasonable to behave sensibly in that case. One thing is a free designer who states requirements and constraints. Another is an implementer who was given an isolated task and no more details. You have to be either full-defensive or renegotiate edge cases which probably could lead to unnecessary complexity.
- gbh444g 4y ago> how someone can overengineer a solution If his solution doesn't work with arbitrary number-like objects (matrices at the very least), doesn't support voice input, can't send results via email and can't seamlessy resume the calculations after a hardware failure, it's far from overengineered.
- zeroonetwothree 4y agoMatrices don’t form a field so I would say they are not really “number-like” in the full sense.
- bitwize 4y ago> Oh, I found bugs in his code. But that was considered normal. People make mistakes, right? Should have used TDD/BDD, developed some Gherkin test cases, and used those to develop some JUnit automated tests before starting on the implementation. Oh, and each class -- for the solver, coefficients, variables, etc. -- needs to leverage dependency injection so they can be properly mocked in the tests... I'm reminded of a story about Kent Beck or somebody, one of the big TDD gurus, who wanted to get a microcontroller to draw something on the screen or something. So he first wrote the program in Java, being sure to employ proper TDD principles, and then hand-translated the Java code to microcontroller assembly or something. But this was feted as a win for TDD and evidence that TDD can be used for anything and therefore should be used for everything. The details of the story are vague, and I can't source it right now, but I know it exists. Some Hackernews is bound to dig up a link, they usually do when I make an obscure reference.
- wruza 4y agoHow does one solve a quadratic in just two lines? Did you omit degenerate case checks and/or number of roots?
- mojuba 4y agoNo. Depending on the language you can find a way of returning 0 to 2 results. Could be a dynamic array, could be a tuple that allows NaN's of some sort.
- aragilar 4y agoWhat algorithm did you use? The standard formula is pretty inaccurate, whereas following most of https://people.eecs.berkeley.edu/~wkahan/Math128/Cubic.pdf https://people.eecs.berkeley.edu/~wkahan/Math128/Cubic.pdf, I was able to get down to near machine precision. I've seen enough cases where someone blindly copied in a formula (or numerical algorithm) from a textbook, without considering how the numerics behave, and getting bad results, to trust unsourced numerical code.
- watwut 4y agoI can't help but be more impressed by a guy who quite clearly genuinly likes both the programming and math, had fun with assignment. I don't know how your two liner worked nor why it was deemed improper. I don't know whether it solved all special cases. But it in fact failed your political goal.
- kaba0 4y agoHard disagree, especially on the 90% part — essential complexity can’t be reduced. Chances are you just didn’t understand the problem domain, or you only needed a solution for a small subset of the problem which is much easier to solve. But the 80-20 principle still holds true for many things — the rare edge cases may indeed bring a whole lot of complexity with themselves. They can easily be a difference between an O(n) algorithm and an NP one. Minimalism is okay (in that we should strive to decrease the accidental complexity), but I found that some people overdo it to such a naive and frankly, dumb levels that it is actively harmful.
- amluto 4y agoUnless I’ve missed a radical change in recent Java versions, Java doesn’t have free functions per se. So asking Java programmers will give biased answers.
- fendy3002 4y agoAfaik yes, java doesn't. The closest will be static class and functions.
- leetcrew 4y agoyou can't have a static outer class in java; static classes must be defined inside of a non-static class. AFAIK, the closest you can get to free functions is a non-static class that only has static functions. infuriatingly, many coverage tools will count the "constructor" of this class as uncovered code. stuff like this makes me really miss C++.
- watwut 4y agoWhat so you mean by that? By static class people typically mean that every method has static in it, so you never have reason to create an instance. Static inside inner class is something else entirely and has nothing to do with topic of this thread.
- ziml77 4y agoThey may be trying to say that Java doesn’t have static classes that match C# static classes. In C# if a class is marked static it’s enforced as not being able to be instantiated and all of its methods (and fields) must be static.
- QuackyTheDuck 4y ago> I asked them to create a library for solving quadratic equations. To me, this reads like a requirement, can you really blame them for respecting what you asked for?
- mojuba 4y agoSorry, I wasn't clear: they all built classes with more than one entry point.
- QuackyTheDuck 4y agoI’m confused, since you mentioned a two-line-solution. Was it a library then?
- WalterBright 4y ago> You realize that it was so trivial that there was no need for a library in the first place. I struggle with that all the time. Libraries always tend to accumulate such trivia. My litmus test for it is if the documentation has more lines than the code. I hate libraries that are a mile wide and an inch deep.
- Viliam1234 4y ago> My litmus test for it is if the documentation has more lines than the code. Not sure I am understanding this correctly. Would undocumented libraries be the best or the worst according to this metric?
- sagarm 4y agoDocumentation substantially longer than the implementation can mean the abstraction/interface is more complex than simply reimplementing for a specific use case would have been. Sometimes you want a library anyway in these circumstances though, since the expertise required for the short implementation might be significant.
- alphanumeric0 4y ago“Simplicity is the ultimate sophistication.” – Leonardo da Vinci.
- jacquesm 4y agoYou've just described quite a few software problems. They don't exist because things were too simple, they exist because something that was essentially simple got made complex. One of my better tools to deal with projects that have run into trouble is to mercilessly cut stuff away. One such case I was permitted to write about (most of my work is under NDA), I can't believe it's already been 8 years since then: https://jacquesmattheij.com/saving-a-project-and-a-company/ https://jacquesmattheij.com/saving-a-project-and-a-company/