6 ms·
> With that definition - it's absolutely correct to say that the code should be as simple as possible. Yet, it is humans who need to read it. This is the end g
by olau 9y ago
> With that definition - it's absolutely correct to say that the code should be as simple as possible.
Yet, it is humans who need to read it. This is the end goal.
If you rewrite the code to satisfy a theoretical objective criteria of simplicity, but end up with something that people reading the code find harder to read, then you have failed.
It's the same when you design a UI.
- virgilp 9y agoBut if you don't have an objective criteria of simplicity, how can you even hope to have universal agreement of what is "simpler"? Humans are complicated beasts. Saying "people find the code harder to read" doesn't help me know what I should do. If I have no objective criteria, then it must be subjective, and then all that "simple" means is that "this is easiest for me right now" - which, from experience, I claim to be a very unlikely path to produce code that multiple people agree to be "simple". (except if the problem was trivial to begin with - but then, who cares?)
- vec 9y ago"Which is the better painting, Van Gogh's Starry Night or Seurat's La Grande Jatee?" is a deeply subjective question. "Which is the better painting, Van Gogh's Starry Night or a kindergartener's watercolor of their family?", on the other hand, appears to have a correct answer. There are multiple competing definitions of "simple" with respect to code and multiple kinds of simplicity that often have to be traded off against one another, and reasonable programmers can and do disagree about which compromises to make and where. Code quality (including, but not limited to legibility) is in many regards a subjective endeavor. That doesn't mean, though, that all decisions are equally justifiable. Trust your sense of aesthetics. It's usually trying to tell you something important, even if you don't know how to put it into words yet. With subjective endeavors there is no perfect, but there is usually better. Chase that.
- virgilp 9y agoIn your first example, both are exceptional, so really "which is better" is irrelevant. In the second, the difference is so big that it's obvious for anyone which is better, but that still doesn't make it useful for getting better at painting. "Paint more like a Van Gogh and less like a kindergarten kid" is not useful advice. People do have art critics and manuals that attempt to write down exactly what made Van Gogh paintings great. Those writings are useful, and many artists do indeed study them.
- vec 9y agoMaybe I read too much into your original comment, but it reminded me of a pitfall that I see too many engineering types fall into, namely that because something can't be formalized then it must be arbitrary, unimportant, or both. In particular, this seems like a counterproductive way to frame the issue: > If I have no objective criteria, then it must be subjective, and then all that "simple" means is that "this is easiest for me right now" Here's a few other (actionble) things that "simple" can mean. * seems to reliably be easiest for me every time I look at it * was judged to be better by the three or four people I could get to give me an opinion * follows a heuristic that a bunch of smart people all seem to agree generally makes things better * mirrors whatever we did on this project the last time we were in this situation Even if all it means is "easiest for me right now", that's still probably going to get better results than "the first thing that popped into my head that might work". There is no objective definition of simple. On behalf of the maintenance programmers of the world, please don't take that to mean it's not worth trying anyway.
- virgilp 9y ago> There is no objective definition of simple. Oh, I agree with that. What I meant was that "this doesn't mean there can't be objective criteria about what is simple and what is not; or that it's futile to attempt objective definitions of 'this is simple/this is not' ". "Easiest for me right now", in my experience, only leads to simplicity in trivial cases. Simplicity requires intense thought & explorations, it's never easy (except, again, in trivial circumstances).
- sp332 9y agoThere's a term for the objective measures of quality: kwalitee. It's kinda like quality, but quality is hard to define let alone measure, so kwalitee is good enough for some purposes. https://pypi.python.org/pypi/Cheesecake https://pypi.python.org/pypi/Cheesecake https://qa.perl.org/phalanx/kwalitee.html https://qa.perl.org/phalanx/kwalitee.html
- geokon 9y agoWell humans reading your bit of code is not the only end goal. My intuition tells me that when I've refactored something to be simple-but-hard it ends up making more maintainable code. There is less state being maintained, less lines of code to maintain, less coupling. Yes it requires a bit more time to understand, but there is also less stuff to understand. Bad code and bad decisions snowball into bad projects
- crdoconnor 9y agoMy intuition tells me that good code is when I reach a localized minima balancing coupling, amount of code written, expressive density of the code, clarity of purpose and ability to fail quickly under invalid conditions. There are often times when I could make the code simpler but it would be longer and vice versa and my decision about which one to pick is purely personal.
- rimliu 9y agohttps://www.sandimetz.com/99bottles/ https://www.sandimetz.com/99bottles/ is all about that. It starts with a few different ways to solve the same problem and then goes into comparing them using chosen criteria. And then it goes on to implement the solution using TDD. Very underappreciated book, imho.
- dbcurtis 9y agoYes, simply optimizing for less state and fewer side-effects, and letting the chips fall where they may, is 80% of the benefit. Most of what I do is realtime and/or robotics. Basically, varitions on: power_on_self_test() while True: recover_from_everything_that_has_gone_wrong_so_far() If the only rule you enforce is making sure every piece of state has a damn good reason for existing life is improved. OK, on re-read this sounds like more like a rant, and less like a philosphy of life. Oh well.
- Verdex_3 9y agoWhat's the alternative though? Write your code such that people subjectively find it easy to read? Then you have to know the set of all people who are going to read your code AND how their internal (and possibly inconsistent) "easy" function works AND those people can never change personally AND no additional people can be added to that set unless they match someone else's "easy" function AND the sum of all the readers' "easy" functions have to result in at least some chunk of code being "easy". At least with an objective criteria anyone who doesn't understand your code has something objective they can get better at in order to understand your code. And this is something that everyone can synchronize on from now and here to infinity and everywhere.
- yebyen 9y agoI don't think you can solve complex problems and guarantee the solutions are easy to understand. (You've hit the nail on the head.) But you can absolutely solve many complex problems without straying outside of the set of simple arrangements or simple configurations of purely simple solutions. It may still be hard to understand. It was probably hard to write, too. It should not be hard to refactor, if at all possible, when the scope of the problem has predictably changed later on.
- jeremiep 9y agoSimplicity is about the cognitive overhead to understand code, the simpler it is the less effort it requires to reason about. That doesn't mean you don't have to learn anything to understand it. Going the easy route usually means dumbing down things and while it can help reading in the moment it definitely doesn't help in the long run as the code evolve over time.
- dbcurtis 9y agoI agree. Idiom plays a huge role. Example: Python list and dictionary comprehensions can often make the result clear much more easily and succictly than the equivalent loop. But you have to learn Python comprehensions, and the common idioms. And it is possible to take it too far, and write an overly-complicated and obtuse comprehension that is difficult to reason about. The goal should be code that is easy to reason about, given a reader that is familiar with the popular idioms. I think that for most languages, thoughtfully chosing good names and writing idiomatic code goes a long way to reducing the cognitive load in reasoning about code. I also find that Python's syntax helps readabilty, and that also decreases cognitive load. Over the holidays I spent some quality time reading up on Rust and starting to climb the learning curve. I'm still at the stage that I find Rust's syntax jarring. It looks like so much ASCII salad. I can't help but think that a little more attention paid to natural syntactic flow would make Rust code easier to reason about for the long haul. Of course, I'm only at the beginning stages of learning Rust idioms -- a fair analaysis can only be done after I have learned them well. But still, it looks like Rust values screen real estate over readabilty, which is a misguided optimization IMHO.
- steveklabnik 9y agoWe chose a lot of Rust's syntax to be familiar to those who use "curly brace and semicolon" languages, and some stuff from functional languages. It's not really about brevity.
- dbcurtis 9y agoFair enough. I get twitchy-semicolon-pinky when I switch back and forth between Python and C. I have much sympathy for Python core devs... I don't really do C++ because most of my C is embedded real-time, so dynamic data structures are not a thing, out of an abundance of conservatism. If I did C++, I'm sure I'd find Rust less jarring. My excitement about Rust is mainly the potential for using Rust for embedded real time -- but I see microcontrollers are still 3rd tier support. It seems like Rust the language is directed at exactly that problem, but Rust's build system and overall ecosystem are not embedded-aware, unless there is plan for xargo to get tier 1 support? So... this isn't the thread for it but I have to ask... the only Rust reference I've seen to list/hash comprehensions is somebody who did a macro. So... is that the idiomatic way to do a list comprehension in Rust? Or is Rust going to make comprehensions first-class syntax? It seems to me that if it can be done in a macro, it isn't a big leap to make it part of the language.