HN Theater @HNTheaterMonth

The best talks and videos of Hacker News.

Hacker News Comments on
"The Clean Code Talks -- Inheritance, Polymorphism, & Testing"

Google TechTalks · Youtube · 4 HN points · 5 HN comments
HN Theater has aggregated all Hacker News stories and comments that mention Google TechTalks's video ""The Clean Code Talks -- Inheritance, Polymorphism, & Testing"".
Youtube Summary
Google Tech Talks
November 20, 2008

ABSTRACT

Is your code full of if statements? Switch statements? Do you have the same switch statement in various places? When you make changes do you find yourself making the same change to the same if/switch in several places? Did you ever forget one?

This talk will discuss approaches to using Object Oriented techniques to remove many of those conditionals. The result is cleaner, tighter, better designed code that's easier to test, understand and maintain.

Speaker: Misko Hevery
HN Theater Rankings

Hacker News Stories and Comments

All the comments and stories posted to Hacker News that reference this video.
May 22, 2022 · Mr_P on Flags Are a Code Smell (2014)
It's not so much the existence of the flag, itself, but rather using an if-statement at the deepest-level of the call stack to conditionally modify behavior.

This talk gives a great overview of why boolean flags (rather, if-statements) can be a code smell: https://www.youtube.com/watch?v=4F72VULWFvc

OP's blogpost advocates for data-oriented design (e.g. Entity Component Systems) as a mechanism for avoiding this, whereas the talk I've linked advocates for OOP. Both mechanisms are equally valid (imho) and are inline with widely-adopted industry practices for software architecture.

gentleman11
I second that video: I’ve watched it several times over the years. I still use flags and conditionals, but less of them these days, and it’s made my life a lot easier
Mar 20, 2017 · 2 points, 0 comments · submitted by kiyanwang
Misko Hevery did a Google Tech Talk about this some years ago, he also use a very similar example with switching on the birds.

https://www.youtube.com/watch?v=4F72VULWFvc

simonhorlick
This. If there's anything that's made me a better programmer it's Misko's talks.
Oct 13, 2014 · 1 points, 0 comments · submitted by AndreyKarpov
This google tech talk is basically about the same thing, eliminating conditionals with polymorphism: https://www.youtube.com/watch?feature=player_embedded&v=...
Nov 04, 2010 · 1 points, 0 comments · submitted by CharlesPal
I completely disagree with the example given in this blog. I don't have time to give a full explaination but I believe the google clean code talks gives a far better arguement than I ever could.

On the general principle I agree that overengineering is to be avoided, but I actually think the example shows a clear disregard for Object Orientated principles.

http://www.youtube.com/watch?v=4F72VULWFvc

ErrantX
One of my lecturers wrote the following at the top of our course notes:

Contrary to popular opinion using OOP does NOT mean "thou shalt make every last thing an object"

jonsen
In some sense that's what the second O says, isn't it?

It's not called Object Programming, but Object-Oriented Programming.

bediger
But isn't that where it goes astray?

If we all called it "Class Oriented Programming" we'd come closer to an accurate name. "Class Oriented Programming" as a name might take away the emphasis on instances, and put emphasis on designing classes.

Or not. There appears to be no bottom to human stupidity.

stcredzero
If we apply a design pattern from Smalltalk, we have Concepts. Every Concept has another concept which is its Misconception. This gives us an infinite regress of misconceptions, unless we can come up with a Metamisconception, which is a concept which is its own erroneous misconception. Then we can implement unbounded stupidity in a system of finite size.
edanm
Tell that to Java developers :)
stcredzero
Really, it depends on your environment. In Smalltalk, most things are objects. Not surprisingly, it turns out to be easiest to make most things objects. I find that Smalltalk is best when a program is mostly objects, there's a sprinkling of short-ish procedural methods whose workings are hidden by encapsulation, and perhaps a handful of long optimized algorithmic methods.

I suspect that in Self, it's easier to make more things objects. (jk - everything is an object in Self.) Objects aren't quite as easy to use in C++ and Java. The cost is higher, so the opportunities to use objects with a good cost/benefit payoff are fewer. That's all there is to it.

Does this generalize? In most Functional languages, functions are really easy to use, and can be used in flexible and powerful ways. What's the best way to program in them? Why, using functions! Yup, seems to work. Fancy that!

hboon
In Smalltalk, everything is an object.
infinite8s
Also, functions + closures = objects
ErrantX
A lot of stuff can work as objects; in fact in many cases an object can be the smallest (or simplest, or most logical etc.) piece of code.

But not everything must be abstracted :)

arethuza
So what's wrong with using a switch statement if all you have are 3 operations?

Even if more operations had to be added I'd probably let it grow to the point where the method the switch is in was getting a bit unwieldy then look at refactoring it using a pattern if I really thought it would be worth it.

jedbrown
Depends whether it's in a library where extensibility is a feature.
jemfinch
> So what's wrong with using a switch statement if all you have are 3 operations?

Because you won't always have only three operations. What about division? Exponentiation? Square root? Factorial? Arbitrary user-defined functions? What if you didn't anticipate an operation one of your clients needs? If you use standard OO principles, your client can rectify that problem; if you use a switch statement, they can't.

> Even if more operations had to be added I'd probably let it grow to the point where the method the switch is in was getting a bit unwieldy then look at refactoring it using a pattern if I really thought it would be worth it.

Why not just do it right from the start? It's extremely simple, it's a pattern every OO programmer is familiar with, it's more computationally efficient and has other advantages as well.

It's also not nearly as complicated as the linked Strategy code. The appropriate analogue to the author's switch statement (in Python, since I'm not a Java programmer):

    class Op(object):
      def eval(self, a, b):
        raise NotImplementedError

    class Add(Op):
      def eval(self, a, b):
        return a + b

    class Subtract(Op):
      def eval(self, a, b):
        return a - b

    class Multiply(Op):
      def eval(self, a, b):
        return a * b
It's twelve non-blank lines, more than half of them boilerplate; translated into Java it would probably gain a few keywords and a couple lines of ending braces, but would not grow significantly. Compare this to almost that many lines for the switch version (note that the OP left out the declaration of the enum, the function boilerplate, etc.) for something less maintainable, less extensible, less idiomatic, and with lower performance.
None
None
arethuza
I would guess that 95% of extensible systems are never extended :-)
anamax
I'd guess that more than 5% are extended (maybe 6-8%), but that more than 95% are not extended as expected.

When something is not extended as expected, either you end up with something not as good as you'd have gotten by waiting or you have to rip out some of what you put in for the future without ever using it.

jemfinch
The problem with this term "extended" is that it's unnecessarily limiting. Code needs to be maintained, whether or not it's "extended," and switch statements are by far less maintainable than the alternative polymorphism-based implementation. They don't as readily admit separate testing, and the implementation of specific operations are not isolated from each other, etc. 100% of code is maintained and the polymorphic method is far better for that than the switch statement. A programmer who chooses the latter over the former is being shortsighted.
neutronicus
"switch statements are by far less maintainable than the alternative polymorphism-based implementation"

You know, everyone says this, and I've never quite gotten it. Why is writing another class and implementing another virtual function so much better than adding another clause to a switch statement? At least all the cases of the switch statement are in the same place instead of scattered across a bunch of files.

Polymorphism to me just seems like a switch statement you have to think harder about. Maybe that's why I've always preferred a functional style to an object-oriented one.

Disclaimer: I program in Fortran for a living, so "SELECT-CASE Stockholm Syndrome" is definitely a possibility.

jemfinch
Polymorphism is more maintainable than a switch statement for a few reasons:

1. Polymorphic method implementations are lexically isolated from one another. Variables can be added, removed, modified, and so on without any risk of impacting unrelated code in another branch of the switch statement.

2. Polymorphic method implementations are guaranteed to return to the correct place, assuming they terminate. Switch statements in a fall through language like C/C++/Java require an error-prone "break" statement to ensure that they return to the statement after the switch rather than the next case block.

3. The existence of a polymorphic method implementation can be enforced by the compiler, which will refuse to compile the program if a polymorphic method implementation is missing. Switch statements provide no such exhaustiveness checking.

4. Polymorphic method dispatching is extensible without access to (or recompiling of) other source code. Adding another case to a switch statement requires access to the original dispatching code, not only in one place, but in every place the relevant enum is being switched on.

5. As I mentioned in my previous post, you can test polymorphic methods independent of the switching apparatus. Most functions that switch like the example the author gave will contain other code which cannot then be separately tested; virtual method calls, on the other hand, can.

6. Polymorphic method calls guarantee constant time dispatch. No sufficiently smart compiler is necessary to convert what is naturally a linear time construct (the switch statement with fall through) into a constant time construct.

Now, to answer the objections you offered. You said, "At least all the cases of the switch statement are in the same place instead of scattered across a bunch of files", to which I would reply that in the polymorphic method case, at least all the code related to a particular case is in the same place. In the switch statement case, you're spreading dispatch machinery and data-specific code all over your program, wherever you switch on an enum. In the polymorphism case, that dispatch machinery is abstracted by the compiler (and thus not present in your code at all) and all the code related to specific types of data is centralized in that type's class. The general code remains general, having no knowledge of the specific, per-type implementation.

You also said, "Polymorphism to me just seems like a switch statement you have to think harder about" to which I reply that on the contrary, polymorphism is great in that you don't have to think about it at all. A programmer attempting to demonstrate that a switch statement is correct must delve into the switch statement and show it to be correct for each case. A programmer attempting to demonstrate that a polymorphic call is correct need only ensure that the call's abstract preconditions are satisfied, and can consider the actual implementations of that call to be black boxes that he need not look into.

In response to your disclaimer, I would say that I mean no offense, but it's very possible that Sapir-Whorf is impacting your language preferences here. You find what you do most to be easiest to understand, and what you do most is switch statements, not polymorphism. I am no doubt afflicted with the same condition, but I think as I demonstrated above, there are many objective reasons why polymorphism is superior to a switch statement in most cases.

sprout
Yes, but how much time does it save the other 5% of the time?

If the other 5% of the time stuff takes off and becomes standard throughout the projects using your code, then it can more than make up for it.

arethuza
http://c2.com/xp/YouArentGonnaNeedIt.html
jemfinch
By the clients, sure. But by the original authors?

This design (it's the basic "convert a switch statement to polymorphism" refactoring) turns a ball of mud switch statement into several independently comprehensible classes. Operations can be understood, verified and tested apart from the whole evaluation apparatus.

No doubt many programmers today massively (perhaps even criminally) overengineer their software, but the fact remains, the example chosen by the author is a really bad one.

Google posted a tech talk about this a while ago: http://www.youtube.com/watch?v=4F72VULWFvc which is more comprehensive than the posted article.
HN Theater is an independent project and is not operated by Y Combinator or any of the video hosting platforms linked to on this site.
~ yaj@
;laksdfhjdhksalkfj more things
yahnd.com ~ Privacy Policy ~
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.