Live data from Hacker News

The Most Important Code Isn't Code

zachholman.com

61–70 of 83 posts

Re: The Most Important Code Isn't Code

#61
post #57
post #56

Earlier quoted context omitted.

A friend of mine who was a smalltalk programmer for 17 years told me that the median length of his methods over his career was four lines. I think that this is admirable and wish my code were more like that.

It seems that having many small methods trades one complexity for another. For methods that are only used once and sequentially, it seems to me that it's easier to follow if they are all inlined (by the programmer). If the methods can be reused elsewhere, it's a different matter. On the other hand, methods are modules, giving syntactic and compiler-supported semantic separation - and you can do things like return ear…

I think one key thing to keep in mind is that it is better to chose a style that is more likely to obviously have no errors, rather than one that has no obvious errors. (Wirth?)

With longer methods, it becomes more strenuous to say that it obviously has no errors.

And in It seems that having many small methods trades one complexity for another. is not a fair representation, as the implied relationship is not linear.

Re: The Most Important Code Isn't Code

#62
post #61
post #57

Earlier quoted context omitted.

It seems that having many small methods trades one complexity for another. For methods that are only used once and sequentially, it seems to me that it's easier to follow if they are all inlined (by the programmer). If the methods can be reused elsewhere, it's a different matter. On the other hand, methods are modules, giving syntactic and compiler-supported semantic separation - and you can do things like return ear…

I think one key thing to keep in mind is that it is better to chose a style that is more likely to obviously have no errors, rather than one that has no obvious errors. (Wirth?) With longer methods, it becomes more strenuous to say that it obviously has no errors. And in It seems that having many small methods trades one complexity for another. is not a fair representation, as the implied relationship is not linear.

C.A.R. Hoare (according to http://www.gdargaud.net/Humor/QuotesProgramming.html anyway), but I prefer Douglas Adams' formulation, though less clever: their fundamental design flaws are completely hidden by their superficial design flaws

Yes, it's true that the compiled-supported semantic modularity of methods helps here: e.g. it can't access other methods' local variables, you can see what goes in and what goes out. But, in a long method, you can manually enforce the same modularity on sequential parts (you can even use local variables scoped by {} to borrow some compiler support). But, yes, point taken.

Can you elaborate on the relationship not being linear? I think you mean that the many parts of a long method can interact (if the coder doesn't enforce this manually).

Re: The Most Important Code Isn't Code

#63
post #58
post #50

Earlier quoted context omitted.

What do you think of short methods?

For fun, I'm going to write my thoughts before reading what you said about it elsewhere in the thread. What do you think of short methods? I'm skeptical of them. I think it's a mistake to try to make functions short for the sake of making them short. It's a mistake because adding a new function also adds complexity (i.e. more code, plus opacity between the calling and called) - not a lot, but greater than zero - so i…

> After you do that for a while, your program stops evolving as an expression of the problem being solved, because you've built it out of primitives that refer only to the internals of the program rather than to concepts drawn from the problem space.

Wow, nicely said.

You also remind me of the problem of removing "accidental duplication", or overfitting: this is when you factor out common code, but it turns out later that it's not really common - lots of minor and sometimes major distinctions occur as you implement more of the problem. It was only by accident that the code happened to be the identical at that stage of development. The theory constructed (the factoring out) gave too much weight to limited information (an early stage of the program), overfitting to that specific information. Generalizing from two instances is almost as bad generalizing from one. In your terms, it models the program not the problem.

It's so refreshing to hear similar thoughts to mine. :)

Re: The Most Important Code Isn't Code

#64
post #62
post #61

Earlier quoted context omitted.

I think one key thing to keep in mind is that it is better to chose a style that is more likely to obviously have no errors, rather than one that has no obvious errors. (Wirth?) With longer methods, it becomes more strenuous to say that it obviously has no errors. And in It seems that having many small methods trades one complexity for another. is not a fair representation, as the implied relationship is not linear.

C.A.R. Hoare (according to http://www.gdargaud.net/Humor/QuotesProgramming.html anyway), but I prefer Douglas Adams' formulation, though less clever: their fundamental design flaws are completely hidden by their superficial design flaws Yes, it's true that the compiled-supported semantic modularity of methods helps here: e.g. it can't access other methods' local variables, you can see what goes in and what goes out.…

Elaborating: Less complexity in each method leads to less overall complexity. And yes, the worst of long methods is that the internal interaction usually leads to more complexity.

Re: The Most Important Code Isn't Code

#65
post #60
post #56

Earlier quoted context omitted.

A friend of mine who was a smalltalk programmer for 17 years told me that the median length of his methods over his career was four lines. I think that this is admirable and wish my code were more like that.

Hell, this reminds me of another thing I want to say. The word that leaps out here is "smalltalk". The short-method school of OO came from the Smalltalk world. It has since been extrapolated to other languages. I am skeptical of this extrapolation. It's fashionable to say language choice doesn't matter that much, but I think language choice has a powerful effect in conditioning how one thinks about one's program. Dif…

With respect to specificity of languages, Uncle Bob in "Clean Code" also advocates for extremely short methods in C#, on the same order as what my friend uses. Different languages do give rise to different ideas, but I think that what matters more is how that language thinks about Objects and Classes, as one example. For example, in Smalltalk, methods are messages. In C++ and other contemporaneous langages, nobody talks about messages. They are still procedural chunks, more or less. This fact has a very big influence on how programs are written.

Then in CLOS, you have generic methods that don't belong to a class, which is really a third view quite independent of the other two ways of looking at OO. And you get multiple inheritance without any confusion. And taking a look at those suckers, they are generally not very long at all. I have a bunch that are zero lines outside of the defgeneric part.

So short methods are also very evident in PGs code. While slightly longer, they are the equivalent of the four-line smalltalk method, and brutally simple. Arc takes this to the next level. Kind of like writing Lisp without vowels.

Re: The Most Important Code Isn't Code

#66
post #64
post #62

Earlier quoted context omitted.

C.A.R. Hoare (according to http://www.gdargaud.net/Humor/QuotesProgramming.html anyway), but I prefer Douglas Adams' formulation, though less clever: their fundamental design flaws are completely hidden by their superficial design flaws Yes, it's true that the compiled-supported semantic modularity of methods helps here: e.g. it can't access other methods' local variables, you can see what goes in and what goes out.…

Elaborating: Less complexity in each method leads to less overall complexity. And yes, the worst of long methods is that the internal interaction usually leads to more complexity.

I was asking about the "non-linear" part.

Re: The Most Important Code Isn't Code

#67
post #62
post #61

Earlier quoted context omitted.

I think one key thing to keep in mind is that it is better to chose a style that is more likely to obviously have no errors, rather than one that has no obvious errors. (Wirth?) With longer methods, it becomes more strenuous to say that it obviously has no errors. And in It seems that having many small methods trades one complexity for another. is not a fair representation, as the implied relationship is not linear.

C.A.R. Hoare (according to http://www.gdargaud.net/Humor/QuotesProgramming.html anyway), but I prefer Douglas Adams' formulation, though less clever: their fundamental design flaws are completely hidden by their superficial design flaws Yes, it's true that the compiled-supported semantic modularity of methods helps here: e.g. it can't access other methods' local variables, you can see what goes in and what goes out.…

You're talking about avoiding temporary variables (see the refactoring book), which is an independent feature. Just talking about method length will only illuminate so much.

Re: The Most Important Code Isn't Code

#68
post #66
post #64

Earlier quoted context omitted.

Elaborating: Less complexity in each method leads to less overall complexity. And yes, the worst of long methods is that the internal interaction usually leads to more complexity.

I was asking about the "non-linear" part.

Perhaps poor choice of phrase. It is my feeling that moving complexity out of methods and possibly having it in the interrelationships between methods results in a net gain in understandability. Perhaps asymmetric would have been a better word?

Re: The Most Important Code Isn't Code

#69
post #61
post #57

Earlier quoted context omitted.

It seems that having many small methods trades one complexity for another. For methods that are only used once and sequentially, it seems to me that it's easier to follow if they are all inlined (by the programmer). If the methods can be reused elsewhere, it's a different matter. On the other hand, methods are modules, giving syntactic and compiler-supported semantic separation - and you can do things like return ear…

I think one key thing to keep in mind is that it is better to chose a style that is more likely to obviously have no errors, rather than one that has no obvious errors. (Wirth?) With longer methods, it becomes more strenuous to say that it obviously has no errors. And in It seems that having many small methods trades one complexity for another. is not a fair representation, as the implied relationship is not linear.

With longer methods, it becomes more strenuous to say that it obviously has no errors.

I disagree. The proper comparison is not between one long function and one short one (that's a no-brainer), it's between a long function and a corresponding set of short functions plus all their interactions. Posing the comparison correctly makes the complexity tradeoff look very different. I'm not saying it's obvious, but the prima facie bias goes the other way.

There's a shortcut for answering this kind of question that may not be infallible but is very useful: program length. Things that make a program longer tend to increase its complexity. One should hesitate to argue that something which inflates code size is making a program simpler. But that is what the short-methods-OO school does routinely.

I don't see why one can't take overall program size as the basic measure of total complexity.

Edit: from another comment in this thread I gather that you tend to see interactions between functions as less complicated than code inside functions. Boy, do we look at this differently! If a function can do a single meaningful thing in isolation, of course I'd factor it out (that's almost another no-brainer). Those are what PG calls "utilities" in his Lisp books. They're meant for random access. But when functions start to interact with too many other functions in ways that affect application logic, my complexity Geiger counter goes crazy. I'd much rather have those interactions isolated in one place, where nobody else can get random access to them and introduce even more dependencies. As befits a truly different world-view, I'm puzzled as to how you can even hold yours.* It seems like a simple matter of combinatorics.

* Doesn't stop the discussion from being delightful though. Just to be clear.

Re: The Most Important Code Isn't Code

#70
post #65
post #60

Earlier quoted context omitted.

Hell, this reminds me of another thing I want to say. The word that leaps out here is "smalltalk". The short-method school of OO came from the Smalltalk world. It has since been extrapolated to other languages. I am skeptical of this extrapolation. It's fashionable to say language choice doesn't matter that much, but I think language choice has a powerful effect in conditioning how one thinks about one's program. Dif…

With respect to specificity of languages, Uncle Bob in "Clean Code" also advocates for extremely short methods in C#, on the same order as what my friend uses. Different languages do give rise to different ideas, but I think that what matters more is how that language thinks about Objects and Classes, as one example. For example, in Smalltalk, methods are messages. In C++ and other contemporaneous langages, nobody ta…

I like your phrase "how that language thinks". C# doesn't think like Smalltalk, so it's a mistake to write C# code as if it does. "Uncle" Bob is not a reliable source here.

It's been a while since I've read any of PG's code, so the following may be off-base, but I don't think he has any heritage in the OO-short-method school. In his books, at least, he's usually looking for functions that work like language constructs. The hallmark of such constructs is that they can be composed orthogonally. This is not at all true of the long delegation chains favored by classic OO.

As for brutal simplicity - a thousand times yes! But what we're discussing is how do you get it. More precisely, how do you get it at the only level that counts: the whole-program level. Otherwise you're just shifting complexity around, and probably thereby increasing it.

Edit: Two addenda. (1) I'm surprised to see PG's code come up in the discussion the way it did, because his writings were probably the thing that cured me of OO, or at least convinced me to check myself into detox. (2) I just had the scary thought that someone might read this discussion and think that I'm arguing against short functions in favor of long ones. God no. I'm arguing in favor of short programs against longer programs that have many more function definitions and interactions. Somebody assure me that was clear.

Post reply on HN