Live data from Hacker News

Bad scientific code beats code following "best practices" (2014)

yosefk.com

61–70 of 333 posts

Re: Bad scientific code beats code following "best practices" (2014)

#61

This is so true I don't think I ever read something so true. It's not even scientists vs software developers. It's people who are really into software development and clean code. They say the program needs a total rewrite and proceed to add 20 layers of inheritance and spreading out every function over 8 files. Ever since I make sure to repeat my mantra every week to developers: How maintainable code is is measured i…

That's a slippery mantra. I can see putting everything in one file.

Everything in one file can be good organization for many even relatively large projects.

Re: Bad scientific code beats code following "best practices" (2014)

#62
Oh look, another tiring craftsmanship debate that other disciplines long figured out!

A, say, physicist writing bad code could equally well be building a pergola for his garden. He doesn’t really know woodworking but god be damned if he couldn’t calculate the forces acting on the beams, and then add some screws - how hard can it be! And probably, he’ll even get the thing up, and it doesn’t look too bad even. Now get a carpenter over, and they will be horrified about all the things the scientist did unusually, did not account for, or just plain wrong. ”Wall Screws you still had around?? How could you not know you’d need structural screws for that?“, he will scream. However, the thing does roughly what the scientist supposed it should do. Until the winter, that is, when the wood expands due to humidity and cracks appear, and he finally needs a professional to fix the problems.

It’s the same story, really: It is a software engineer’s job to build quality software. A scientists job is to solve problems. There’s a clear boundary here, where the latter will deliver a concept to the former, who will eventually create a production-grade implementation off of that. Neither does a scientist have to build proper software, nor does a developer have to do cutting-edge research.

And all the words wasted on how one of them might be doing something badly is on he wrong path.

Re: Bad scientific code beats code following "best practices" (2014)

#63

Earlier quoted context omitted.

I like long simple functions because it makes them easy to reason about when debugging. Rarely does having more functions solve “does this do what I expect.”

Maybe it boils down to how well you are able to navigate a code base. With a full-featured language specific IDE, it is very easy to navigate through even complicated spaghetti. It makes debugging call traces simple, with a GUI. However, many other file viewers and editors make this much more complicated, and it can be frustrating to follow code that is making heavy use of modularization. If you are grepping your way…

>> With a full-featured language specific IDE, it is very easy to navigate through even complicated spaghetti.

If you need a fancy IDE to navigate around code in order to understand it, that might be crappy or poorly organized code.

Not a dig at nice IDEs, just code that requires one to navigate and understand.

Re: Bad scientific code beats code following "best practices" (2014)

#64
>Multiple/virtual/high-on-crack inheritance 7 to 14 stack frames composed principally of thin wrappers, some of them function pointers/virtual functions, possibly inside interrupt handlers or what-not Files spread in umpteen directories

Scientific code? You just described 99% of "enterprise" java code above.

Re: Bad scientific code beats code following "best practices" (2014)

#65

This is so true I don't think I ever read something so true. It's not even scientists vs software developers. It's people who are really into software development and clean code. They say the program needs a total rewrite and proceed to add 20 layers of inheritance and spreading out every function over 8 files. Ever since I make sure to repeat my mantra every week to developers: How maintainable code is is measured i…

Working with a 300 line method is not fun, believe me. Everything is in one place and you don't have to change many files, yes, but due to the cognitive load, it's so much more effort to maintain it.

There are some things that should be in one long function (or method).

Consider dealing with the output of a (lexical) tokeniser. It is much easier to maintain a massive switch statement (or a bunch of ifs/elseifs) to handle each token, with calls to other functions to do the actual processing, such that each case is just a token and a function call. Grouping them in some way not required by the code is an illusory "gain": it hides the complexity of the actual function in a bunch of files you don't look at, when this is not a natural abstraction of the problem at all and when those files introduce extra layers of flow control where tricky bugs can hide. Or see the "PLEASE DO NOT ATTEMPT TO SIMPLIFY THIS CODE" comment from the Kubernetes source[0]. A 300 line function that does one thing and which cannot be usefully divided into smaller units is more maintainable than any alternative. Attempting to break it up will make it worse.

That being said, I agree that nearly all 300 line functions in the wild are not like this.

[0] https://github.com/kubernetes/kubernetes/blob/ec2e767e593953...

Re: Bad scientific code beats code following "best practices" (2014)

#66
post #32

Earlier quoted context omitted.

It's a decent measure of complexity: It's not that "opening files" themselves is work-intensive. But having a lot of files smells of overengineered code. One long, yet simple function has less cognitive overhead than spreading the function across multiple classes or functions or call hierarchies (themselves spread over multiple files).

> One long, yet simple function has less cognitive overhead than spreading the function across multiple classes or functions or call hierarchies Not if you are encapsulating and naming effectively... Why read 100 lines when you can read 20 and find concerns in one routine you are concerned with? Function calls can be expensive. However, optimization can come whenever you need it, and if what you need is one call vs 5…

> Not if you are encapsulating and naming effectively...

No, and this is one of the reasons inheritance has lost popularity. Splitting some functionality across many files adds significantly to the cognitive load of figuring out what code is actually even running. After you trace that information out, you need to keep it all straight in your head while debugging whatever you’re working on. That’s even more problematic when you’re debugging, which implies you already don’t really understand what the program is doing.

And that’s in the case where things are named well. When they’re inevitably accidentally named in confusing or incorrect ways that can contribute to the bug itself and cause the code to be even more confusing.

Extreme levels of encapsulation has its own issues when, actually, the original author is wrong and you really do need some public access to some member. No one writing code is clairvoyant, so excessive encapsulation is common.

Re: Bad scientific code beats code following "best practices" (2014)

#67
post #32

Earlier quoted context omitted.

It's a decent measure of complexity: It's not that "opening files" themselves is work-intensive. But having a lot of files smells of overengineered code. One long, yet simple function has less cognitive overhead than spreading the function across multiple classes or functions or call hierarchies (themselves spread over multiple files).

> One long, yet simple function has less cognitive overhead than spreading the function across multiple classes or functions or call hierarchies Not if you are encapsulating and naming effectively... Why read 100 lines when you can read 20 and find concerns in one routine you are concerned with? Function calls can be expensive. However, optimization can come whenever you need it, and if what you need is one call vs 5…

Not if you are encapsulating and naming effectively...

Encapsulation is hard and a lot of what people call encapsulation isn’t. For example, taking a global variable and moving it to a class is not encapsulation. You have to actually do the hard work of removing the dependency on global shared state. Just changing everything to mutate the new global through an accessor to a “god” object that gets passed everywhere is accomplishing nothing at all. Worse than nothing, you’re complexifying without fixing the root problem: global mutable state.

Re: Bad scientific code beats code following "best practices" (2014)

#68
I've seen this:

- Multiple/virtual/high-on-crack inheritance:

  add each function/class has 7 template specialization parameters and 3 macros which expand to templates which expand to macros
  
- Lookup using dynamic structures from hell – dictionaries of names where the names are concatenated from various pieces at runtime, etc.

  think maps of maps of maps loaded from configs of configs
  
- Dynamic loading and other grep-defeating techniques

  obviously everything has to be a "plugin"
  
- A forest of near-identical names along the lines of DriverController, ControllerManager, DriverManager, ManagerController, controlDriver ad infinitum – all calling each other

  a 1000 times yes! yes!!! DriverController inherits from ControllerManager which extends ManagerController which contains a DriverManager which agregates 3 ControllerManager from diferent namespaces. I've seen a DriverController function going through 12 levels of stack passed between 3 threads to eventually call back a function from the same DriverController
  
- Templates calling overloaded functions with declarations hopefully visible where the template is defined, maybe not

  if a template technique exists, it had to be used!
  
- Decorators, metaclasses, code generation, etc. etc.

  Of course they define their own DDL with xmls parsed by a combination of Python and awk which generates C++ macros which are used in templates to dynamically load plugins which hold maps of maps of function pointers to create3 events dispatched on a pool of threads

Re: Bad scientific code beats code following "best practices" (2014)

#69
post #24

Good code is the simplest code you can write to get the job done. Getting too excited about techniques is a form of scope creep

It depends on what it means to be to get the job done.

Write some code and generate immediate results can be considered a done job. If you want to reuse the code a year later and found an unreadable mess though, not so much.

Re: Bad scientific code beats code following "best practices" (2014)

#70

This is so true I don't think I ever read something so true. It's not even scientists vs software developers. It's people who are really into software development and clean code. They say the program needs a total rewrite and proceed to add 20 layers of inheritance and spreading out every function over 8 files. Ever since I make sure to repeat my mantra every week to developers: How maintainable code is is measured i…

>They say the program needs a total rewrite and proceed to add 20 layers of inheritance and spreading out every function over 8 files. Anyone who in 2023 still thinks inheritance is a good idea for anything other than a few very specialised use-cases is not somebody who seriously cares about the craft of software development, not somebody who's put any effort to study programming theory and move beyond destructive 19…

(Ab)use of any paradigm (I'll need a shower for using that word) can result in nightmares. Inheritance has its place and it is definitely useful in more than "few specialised cases". It can get out of hand and it can become a nightmare. Composition has its place and it is definitely not better than inheritance except in "few specialised cases". It can also result in nightmare, just wait till adoption of Rust and go is at the level of Java and C++ in enterprise environment and you will see. Writing clean and maintainable code should be the best practice and writing obfuscated code for performance and security should be reserved for "few specialised cases" but most developers and languages prefer the short and obfuscated to clear and (slightly) longer. RUst and go are perfect examples of why software development is an immature engineering discipline that favors "cool" and "terse" to clear and expressive...and no, C and C++ are not "good old times", they are old and slightly worse but not much worse, or I should clarify, go and rust and not much better because they still do not allow user (programmer) to express the intent clearly and instead force the reader of the code to sound like a person with severe speech impediment.
Post reply on HN