News for hackers. Stuff that matters.
Re:Please do not attempt to simplify this code by dragonwriter on Thursday December 27, 2018 @08:25PM (#18774174)
> I love this! It's the "jazz music" of software development. Something which breaks all the "rules" but does so purposefully and explicitly so that it can become better than the "rules" allow.

I kind of see it as the opposite: “space shuttle style” is code that adheres to heavyweight rules that most software development has abandoned in favor of a more improvisational style.

But in either case it illustrates that code style rules are desirable, or not, based on the context; you need to understand what purpose rules serve and what trade-offs they involve to understand which rules to use; there's no one-size-fits-all solution.

Re:Please do not attempt to simplify this code by 3pt14159 on Thursday December 27, 2018 @10:11PM (#18774619)
I've had this latent thought for a while that I'm finally putting to words:

The complexity goes somewhere.

It's either into lots tests, or it's into something like shuttle style with lots of comments, or it's into a huge QA department, or it's into the type system / DB schema. It could even be going into the org structure!

But something, somewhere is handling the complexity and it is doing so as a partial function to the economic importance of the software to the stakeholders of the software.

Re:Please do not attempt to simplify this code by arduanika on Friday December 28, 2018 @12:43AM (#18775085)
In this case, the questionable choice of a "something" to handle the complexity is jarringly at odds with the high economic importance that the comments convey.

> tests

pv_controller.go has 1715 lines. To be generous, we might say half of it is comments. pv_controller_test.go has 359. Hopefully this code is exercised elsewhere in integration tests?

> a huge QA department

That's what you're signing up for when you choose a language that expresses cases mainly using if/then/else, and when you don't feel like testing every case.

> into the type system

Sum types aren't complex, although they're not familiar to everyone in the way i/t/e is. Even a result type (a straightforward example of a sum type, available e.g. in Rust) would simplify a lot of the "if err != nil" boilerplate, and greatly de-indent this code. It would probably also make invalid cases unrepresentable in a few parts of this file, eliminating a few more branches. In fact, a sum type typically requires an exhaustive pattern match, making practices such as their rule "every 'if' statement has a matching 'else'" the default.

My point is, complexity (and economic utility) are not conserved as you choose between these "somewhere"s. A few basic type system features can drastically reduce complexity for the QA team or eliminate comments and cases from the space shuttle.

Still - good on them for this degree of discipline & for so many well-written comments, with clear contracts about what is modified or not. ATBGE.

Re:Please do not attempt to simplify this code by eecc on Friday December 28, 2018 @03:38AM (#18775570)
Monadic Try, biased Either, Some, pattern matching and destructuting... you don’t even need to know category theory to use and understand them in code, and you let the compiler do all the tough work.

This example - despise the perplexing celebrations - is a product of the limits of Go

Re:Please do not attempt to simplify this code by danieldisu on Friday December 28, 2018 @04:37AM (#18775801)
Yet you can argue that despite it's limitations they could make working (complex) software with it.
Re:Please do not attempt to simplify this code by masklinn on Friday December 28, 2018 @05:55AM (#18776090)
That's not an argument, that's a truism. You can make working (complex) software using nothing but machine code keyed into volatile memory via front-panel switches.
Re:Please do not attempt to simplify this code by martinlaz on Friday December 28, 2018 @11:18AM (#18777607)
can you really?
Re:Please do not attempt to simplify this code by lmm on Friday December 28, 2018 @08:39AM (#18776608)
Isn't that a case of "shit crayons"? People can and do make great things with terrible tools, but that doesn't make those tools any less terrible.
Re:Please do not attempt to simplify this code by dragonwriter on Friday December 28, 2018 @12:59PM (#18778288)
> This example - despise the perplexing celebrations - is a product of the limits of Go

All coding style is a product of the limitations of the language (well, except when it is coding style dictated by the limitations of a different language applied in a cargo cult fashion out of it's appropriate context); and celebrating the choice of how to approach this problem given that it was being done in this language isn't the same as celebrating the language choice. Go would be pretty close to my last choice for anything, but that doesn't stop me from recognizing this as a thoughtful way to apply Go to this problem.

Re:Please do not attempt to simplify this code by lima on Friday December 28, 2018 @08:30AM (#18776575)
> pv_controller.go has 1715 lines. To be generous, we might say half of it is comments. pv_controller_test.go has 359. Hopefully this code is exercised elsewhere in integration tests?

The PV subsystem interfaces with external storage systems, so integration/end-to-end tests are much more useful than unit tests (yes, they do exist).

Re:Please do not attempt to simplify this code by rakoo on Friday December 28, 2018 @04:44AM (#18775834)
So basically complexity would go in the language
Re:Please do not attempt to simplify this code by lmm on Friday December 28, 2018 @05:00AM (#18775904)
A language that spends its complexity budget well can save complexity from a lot of programs. E.g. if you look at https://philipnilsson.github.io/Badness10k/escaping-hell-wit... , language A could offer all 5 of those ad-hoc solutions (making it a very complex language) and language B could just offer monads (making it a relatively simple language), but both languages would be just as effective in alleviating the complexity of programs written in that language.
Re:Please do not attempt to simplify this code by AstralStorm on Friday December 28, 2018 @08:51AM (#18776675)
And then language C(++) just skips unnecessary monads which are syntactic salt and uses exceptions, while providing the optional type for where you really, really want this behavior. Tradeoffs of course, but these were considered.

The main problem here with this "solution" is that any monad looks like every other monad. You can easily lose context and have to rely on naming conventions, which is quite terrible. You cannot spot what the code is doing at a glance.

And if you mess up, the type system and compiler will spout some completely unhelpful message because it parses everything the same.

Code that does very different things should look different, not identical. (Unlike what Lisp and FP people think.) Just think on why we do not use textual buttons everywhere in UI. It's a major reason fewer people accept Lisp than could...

Re:Please do not attempt to simplify this code by lmm on Friday December 28, 2018 @10:09AM (#18777111)
> And then language C(++) just skips unnecessary monads which are syntactic salt and uses exceptions

Exceptions are an ad-hoc solution to a sixth problem. You still have the other five. (Ok, it's possible to use exceptions to replace null. But that still leaves the other four).

C does not have exceptions, or any solution to error-checking hell at all. C++ is a notoriously non-simple language. Neither is at all convincing as a counterargument.

> Code that does very different things should look different, not identical.

In a language with monads, code that does things that are specific to error-handling still looks very different from code that does things that are specific to async I/O. But code that does a thing that is fundamentally the same (parametric), such as composition, looks the same. This is the very essence of programming (and indeed of mathematics): "2 + 2" does something that is, on the surface, very different from "3 + 5", yet there is an important underlying commonality. Code that sorts a list of integers is doing something that is, on the surface, very different from sorting a list of strings, but there's an important underlying commonality. Monads just take the same thing one level higher.

Re:Please do not attempt to simplify this code by pdpi on Friday December 28, 2018 @12:06PM (#18777939)
> Code that does very different things should look different, not identical.

I think the major point you're missing here is that the whole point of pushing monads as a core abstraction is the way they shift what "different things" means.

Re:Please do not attempt to simplify this code by arduanika on Saturday December 29, 2018 @01:51AM (#18782353)
This is a misreading, almost diametric, of what I wrote:

Me: "complexity is not conserved as we choose beween implementations"

You: "So basically complexity is conserved"

Maybe we're getting confused by this word "complexity", so let's break it down into two things: complexity of task handled (COTH) and complexity for programmer (CFP). For a given task of a given complexity, COTH is tautologically the same no matter how you choose to implement. The level of CFP, on the other hand, depends on how you decide to handle complexity. Implementing it in assembly language? High CFP. Implementing it with i/t/e, and commenting loudly your intention to handle all cases? Medium CFP. Enforcing these good, exhaustive standards with the type system? Low CFP. Why does CFP differ? Because the tradeoff matters. In particular, my point was that sum types add a tiny bit of complexity to the language, and remove a TON of complexity from the code. It's not a wash, or even a close contest.

(Notice that I don't make any super-radical suggestions, e.g. that their discipline around mutation/purity should be enforced with types or monads instead of exclamatory comments -- in which case, the CFP added to the language might outweigh the CFP alleviated from the typical file. But my point holds: CFP is not conserved)

Re:Please do not attempt to simplify this code by bitexploder on Friday December 28, 2018 @03:29AM (#18775529)
I don’t think this changes the inherent complexity of the code right? The basic logic of what is being done is still the same. De-indenting code but still having the same complexity, some of which is now abstracted by the language is still complexity. Maybe it somewhat helps the humans reading the code? But don’t you still have to reason about the basic state changes of the system the same way?
Re:Please do not attempt to simplify this code by dnautics on Friday December 28, 2018 @04:05AM (#18775682)
the code itself has the same complexity, but you are pushing the workload to the compiler, not to the human. Given the two options I typically prefer the compiler.
Re:Please do not attempt to simplify this code by AstralStorm on Friday December 28, 2018 @04:30AM (#18775777)
Compilers and libraries are written by humans and are probably the most fallible things ever, optimization wise. I'm not talking 1% here. I'd love to see an opposing compiler with an automated proof that it does what it claims.

Well, unless your computer can read and parse high order proofs over code. Not even Haskell can do that. (It can barely parse F types much less optimize them.) The closest I have come to that feature is Isabelle's simplify and even that is limited.

GCC and Clang can do basic bounds proofs at best and otherwise are tough buggy heuristic beasts. Just look at the trackers.

GHC has a slightly easier job but it's paid for in programming complexity. There are hoops in type system you have to jump to get performant code... and even then the code generated its at best meh quality. There is always some joker telling that it could be compiled for SIMD or multithreaded but that never materialized in usable form.

Re:Please do not attempt to simplify this code by Touche on Friday December 28, 2018 @07:45AM (#18776429)
Compilers can only tell if programs are internally consistent, they can't help ensure that they are correct. Compilers don't know about inputs. Compilers don't know if the branch you wrote goes in the correct direction for a given input.
Re:Please do not attempt to simplify this code by mywittyname on Friday December 28, 2018 @11:45AM (#18777806)
Well, the compiler can optimize away any superfluous branches which exist entirely to act as hints for the programmer.
Re:Please do not attempt to simplify this code by arduanika on Saturday December 29, 2018 @02:07AM (#18782406)
> they can't help ensure that they are correct

Of course they can help. Maybe you meant:

> they can't ensure that they are correct

Re:Please do not attempt to simplify this code by woah on Friday December 28, 2018 @08:58AM (#18776703)
It prevents dumb mistakes like not covering all cases
Re:Please do not attempt to simplify this code by jrumbut on Thursday December 27, 2018 @10:35PM (#18774724)
I would say this is the fundamental problem of making software, and the reason that the whole world could learn JavaScript and yet being able to make great software would still be a rare skill and why even CRUD apps tax the minds of smart people.

Making the right component tackle the right amount of the right complexity is just a hard problem, and I think when it looks easy it's only because your options were constrained.

Re:Please do not attempt to simplify this code by hoorayimhelping on Friday December 28, 2018 @02:34AM (#18775346)
>Tesler's Law, also known as The Law of Conservation of Complexity, states that for any system there is a certain amount of complexity which cannot be reduced.

https://lawsofux.com/teslers-law.html

Re:Please do not attempt to simplify this code by garmaine on Friday December 28, 2018 @04:21AM (#18775747)
Cute, but objectively not true.. using the right tool, or right approach can drastically simplify the solution, sometimes even making intractable problems solvable.
Re:Please do not attempt to simplify this code by liamfd on Friday December 28, 2018 @09:25AM (#18776846)
>

I take this more to mean that the logic you're trying to implement has a fixed, non-zero level of complexity (sometimes called "essential" or "inherent" complexity), which forms the complexity floor of your application. On top of that, your implementation adds additional complexity (sometimes called "accidental" or "incidental" complexity), which is not-zero but not fixed.

So, my reading is that in saying "every application has an inherent amount of complexity that cannot be removed or hidden", the law is referring to the essential complexity. Meaning, the law says "some of the complexity is unavoidable in every application" vs. "the amount of complexity is fixed in every application". I do think the name of the law is a little weird, as it implies the latter meaning.

Re:Please do not attempt to simplify this code by hathawsh on Friday December 28, 2018 @01:04PM (#18778326)
The trouble with Tesler's Law is that it's often difficult to distinguish between essential complexity and incidental complexity. When I face a UX problem that seems like an insurmountable barrier, if I step back and consider many perspectives, I often find a way to change the context so that the problem becomes easy to solve. What feels like essential complexity is often surprisingly incidental.
Re:Please do not attempt to simplify this code by garmaine on Friday December 28, 2018 @09:17PM (#18781315)
What I'm objecting to is the notion that there is a "fixed, non-zero level of complexity." Often real innovations in organization and structure allow for fundamentally simpler implementations. I'm reminded of physics: there's an inherent complexity in solving a rotational problem. But introduce polar coordinates and you fundamentally change the game, removing a dimension from your analysis for some problems, and making the solution trivial.
Re:Please do not attempt to simplify this code by firethief on Saturday December 29, 2018 @12:47AM (#18782117)
In this case your original estimate of the complexity was high due to a choice of coordinates increasing the incidental complexity of the solution
Re:Please do not attempt to simplify this code by starbeast on Friday December 28, 2018 @05:40AM (#18776033)
If it was objectively not true, then you could have infinite compression and any program could be reduced to a single bit.
Re:Please do not attempt to simplify this code by garmaine on Friday December 28, 2018 @09:00AM (#18776712)
If "conservation of complexity" were universally true then ANY compression would be impossible.

This isn't a dichotomy. My point is that there are clear examples of situations where you aren't just pushing complexity around, but actually achieving great simplifications.

Re:Please do not attempt to simplify this code by starbeast on Friday December 28, 2018 @09:28AM (#18776867)
>If "conservation of complexity" were universally true then ANY compression would be impossible.

No it wouldn't. The complexity of a pattern can usually be conserved while reducing its length, but for each pattern there is a limit. This is the entire concept behind the Kolmogorov complexity of a system and any patterns that cannot be reduced any further without removing complexity are at their limit already.

This is also related to the idea that you cannot have a universal compression algorithm.

Re:Please do not attempt to simplify this code by baq on Friday December 28, 2018 @04:46AM (#18775847)
I don’t see how your example makes it false.
Re:Please do not attempt to simplify this code by msjyoo on Friday December 28, 2018 @03:10AM (#18775465)
Wow, that site is beautiful beyond words.
Re:Please do not attempt to simplify this code by AstralStorm on Friday December 28, 2018 @05:01AM (#18775908)
I'd move the unnecessary big banner somewhere. A website is not a book and does not have cover pages.
Re:Please do not attempt to simplify this code by InGodsName on Friday December 28, 2018 @05:58AM (#18776101)
Precisely, you can only move the complexity around but not eliminate it completely.
Re:Please do not attempt to simplify this code by reuben364 on Friday December 28, 2018 @04:43AM (#18775828)
That's kind of a truism though. There will always be a non-zero entropy for the distinct kind of systems you want to build.

Unless there is one system to rule them all, configured exactly the way it is needed out the box.

Re:Please do not attempt to simplify this code by chillacy on Thursday December 27, 2018 @10:53PM (#18774779)
In the most ideal way, the complexity becomes the code structure. People can only keep track of 7 or so odd things in working memory at a time, we tackle complexity through chunking (abstraction), so that these new 7 things are in turn each 7 more things which are in turn 7 more things (ideally).
Re:Please do not attempt to simplify this code by AstralStorm on Friday December 28, 2018 @04:45AM (#18775845)
Your code structure is not my memory chunking structure and it will interfere.

At a point you run the risk of just overloading memory with way to many names and entities by merciless chunking, not to mention create a file or function maze.

Inlining works surprisingly well because you do not have to memorize things and can just read them. Theoretically it is a tooling problem, but nobody wrote a good enough "inline" tool so instead everyone relies on incomplete and buggy textual descriptions.

Re:Please do not attempt to simplify this code by chillacy on Friday December 28, 2018 @09:30AM (#18776873)
I'm not sure what to say, just do the right thing and be more practical than dogmatic I guess? There are situations where it's better not to install an abstraction. There are situations where an abstraction fits super well and is well understood by your dev team.
Re:Please do not attempt to simplify this code by ehnto on Thursday December 27, 2018 @11:42PM (#18774914)
I had this thought when working with a legacy app the company was migrating to a modern platform. The legacy app was enormously complex and contained huge amounts of business logic. Migrating it didn't get rid of all that business logic. Now, using modern software patterns inside a framework with it's own complexities, it was a lot more organised but perhaps even more complex thanks to business logic now needing to fit inside the frameworks idioms and structures. It was nicer to read through, but no less complex.
Re:Please do not attempt to simplify this code by eitland on Friday December 28, 2018 @02:26AM (#18775322)
I added this comment to my quotes collection.

I think you are more or less spot on. Personally I'll mention explicitly (one could argue that you already say this above) that well designed libraries and languages helps you by containing some of the inherent complexity while avoiding to add incidental complexity.

Re:Please do not attempt to simplify this code by k__ on Thursday December 27, 2018 @10:52PM (#18774775)
Probably the reason why libraries and frameworks are so omnipresent.

They solve the complexities the average programmer couldn't control on their own.

Re:Please do not attempt to simplify this code by de_watcher on Friday December 28, 2018 @02:15AM (#18775302)
The job is to distinguish between inherent complexity and accidental complexity.
Re:Please do not attempt to simplify this code by siculars on Friday December 28, 2018 @09:58AM (#18777050)
This^
Re:Please do not attempt to simplify this code by foobar1962 on Friday December 28, 2018 @02:46AM (#18775375)
> I kind of see it as the opposite: “space shuttle style” is code that adheres to heavyweight rules that most software development has abandoned in favor of a more improvisational style.

Most software other than that written for space shuttles and other seriously critical applications.

A colleague of mine works for a telco, and changes to software that runs on satellites takes months to approve and goes through verification stages that include running on simulators and duplicate hardware that is on the ground.