Live data from Hacker News

Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

web.archive.org

31–40 of 113 posts

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#31
post #11

Earlier quoted context omitted.

> I only kind of "got it" when I did something nobody would recommend anymore, and learned QBasic, and wrote a bunch of ghastly code with goto's all over the place and practically everything being a global. An aside: It's okay to learn that way, when you're 10. A lot of my own big programming revelations have come from ignoring best practices and accidentally trying to implement or construct them from first principle…

Totally agree. I think we make a mistake trying to harp on doing things "right" too much for new programmers, because they end up with analysis paralysis.

I think this is why you often see people reinvent GOTO. Everyone who started with BASIC (and moved on) knows why you won't do that any more. But someone today starting with python might not understand. [replace GOTO with any bad example]

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#32

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

These days I find composition via dependency injection (of interfaces, not concrete implementations) to be a much better way to solve #3.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#33

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

> 3. Often you want to use the default protocol implementation with some changes. Instead of re-implementing the rest of the protocol, it's highly convenient to be able to specify only the differences.

> #3 is the core reason why inheritance was developed.

No, absolutely not. As sibling comments say, composition is sufficient for that. I can only see exactly one reason why inheritance is necessary: to allow superclasses to call methods defined in subclasses, also known as late binding.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#34

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

Well said. And #3 is also an area where Functional Programming falls completely flat. There is simply no easy way in any FP language that I know to capture such a simple mechanism as: "Reuse 90% of this piece of code but alter just this 10%". Specialization is a very, very powerful aspect of OOP, one that's extremely easy to explain and which comes in handy to model a surprisingly wide variety of problems.

[deleted]

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#35

Earlier quoted context omitted.

Functional programmers will reply that you can use partial evaluation and higher-order functions to do that. The sad reality is that since so many people are only familiar with the strawman version of OOP rather than the real thing intelligently discussing the advantages and disadvantages of these paradigms is very hard.

Yes, I've heard them say that indeed. They often gloss over a lot of issues about these. For example, partial evaluation is limited by the fact that parameters need to be ordered a certain way and you can't realistically cover all combinations. Higher order functions don't enable any kind of useful specialization at all. And of course, all modern OOP languages also support higher order functions, so they are the ones…

Could you give some concrete examples? At the moment it's just assertions.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#36

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

I'm not sure why inheritance was developed. I had thought it happened in Smalltalk between 1971 and 1976; in Smalltalk-76 http://worrydream.com/refs/Ingalls%20-%20The%20Smalltalk-76%... it's justified as follows: "This capability leads to a highly factored system." The first example given is that Window has subclasses such as a text editor for the source code of a class. (This was before per-method editing.) A later example is Number, which provides many comparisons such as ≤ and ≠ in terms of a smaller number of basic comparisons.

However, it turns out it was in SIMULA 67, taken from a 1965 proposal by Tony Hoare for record handling in Algol, which I haven't been able to find yet. That is, it was proposed in a context where objects had fields, but not methods, and thus not protocols either. SIMULA 67 had overriding of superclass methods if they were marked “virtual”, as in C++.

Turning back to Window and Number, an alternative using composition instead of inheritance puts the shared and unshared code in different objects. The Window class becomes one class only, with a field indicating what its contents are, to which it delegates paint messages and handling of input events; Number becomes a wrapper that expects its contents to implement How does this differ from the approach using inheritance? It's a great deal more hassle to change your mind about which methods are delegated to the wrapped object, but much easier to be sure that other refactorings are correct, because it's much easier to tell which methods could potentially be “overridden by a subclass”. It affords the possibility of changing the contents of a Window over time—particularly useful in languages like Python where reloading code after a modification creates new classes rather than modifying the existing ones. It costs an extra allocation and an extra method call on every delegated method (fatal in the case of SmallInteger, normally a subclass of Number, but SmallInteger is already a collection of hacks for efficiency; giving it an independent implementation of the Number protocol is reasonable).

Perhaps we should regard inheritance as an efficiency and convenience hack for cases where memory is tight or we're initially exploring an OO design, one we should remove later to improve maintainability once it's more or less clear how to divide up the responsibilities.

Smalltalk-80 used inheritance for its collections library, in a way that does not respect LSP, perhaps understandably because Barbara Liskov was on the other coast, and CLU was a very different language from Smalltalk. Some more recent languages like Java modeled their collections after Smalltalk’s. I don't think it's entirely fair to ding Josh Bloch for this.

Rigorously modeling inheritance (with overriding, open recursion, and covariant self type) turns out to be quite challenging; I recommend Abadí and Cardelli's A Theory of Objects to those who are interested.

The most interesting thing I'm looking at right now with regard to software design is Jackson's Alloy model checker, which does a kind of abstract-interpretation exhaustive test of your high-level design to verify that in examples to a certain size, your desired properties hold. This is of course a different level of abstraction from the factoring of the implementation to eliminate duplication, but it can tell you which contemplated protocols are fatally flawed.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#37

Earlier quoted context omitted.

Functional programmers will reply that you can use partial evaluation and higher-order functions to do that. The sad reality is that since so many people are only familiar with the strawman version of OOP rather than the real thing intelligently discussing the advantages and disadvantages of these paradigms is very hard.

Yes, I've heard them say that indeed. They often gloss over a lot of issues about these. For example, partial evaluation is limited by the fact that parameters need to be ordered a certain way and you can't realistically cover all combinations. Higher order functions don't enable any kind of useful specialization at all. And of course, all modern OOP languages also support higher order functions, so they are the ones…

Do any functional languages support partial evaluation using named parameters? That would solve the parameter ordering complaint.

As for higher order functions you would write a function that does the 90% and accepts a function parameter for the other 10%.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#38

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

Well said. And #3 is also an area where Functional Programming falls completely flat. There is simply no easy way in any FP language that I know to capture such a simple mechanism as: "Reuse 90% of this piece of code but alter just this 10%". Specialization is a very, very powerful aspect of OOP, one that's extremely easy to explain and which comes in handy to model a surprisingly wide variety of problems.

Give me a new function that is a partial of some other function where I can define the 10% to change than any of the arcane polymorphism magic.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#39

>In good OO programming, we don’t make class hierarchies in order to satisfy our inner Linnaeus. This correctly identifies one of the worst problems with how people construct OO programs when they get out of college. They are infected with the idiotic desire to make neat taxonomies. They don't know why. They can't even explain the rules that make one taxonomy good and another one bad. They just feel some immense pres…

Teaching your points 1, 2 and 3 seem to be overlooked in many courses. It's as if they know that you have to do these things, but they don't know why. As if "Oh, you have to do this because polymorphism."

I think if they took a single lecture to teach these specific points of OO, we'd get more effective developers straight out of school.

Re: Goodbye, shitty Car extends Vehicle object-orientation tutorial (2011)

#40

Earlier quoted context omitted.

Yes, I've heard them say that indeed. They often gloss over a lot of issues about these. For example, partial evaluation is limited by the fact that parameters need to be ordered a certain way and you can't realistically cover all combinations. Higher order functions don't enable any kind of useful specialization at all. And of course, all modern OOP languages also support higher order functions, so they are the ones…

Do any functional languages support partial evaluation using named parameters? That would solve the parameter ordering complaint. As for higher order functions you would write a function that does the 90% and accepts a function parameter for the other 10%.

OCaml has named (“labeled”) parameters, and of course you can use combinators like flip to bind positional parameters like the second or third. I'm not sure what the relevance to inheritance is, though, and “partial evaluation” usually means an optimization strategy rather than just currying.
Post reply on HN