Live data from Hacker News

Goodbye, Object Oriented Programming (2016)

medium.com

21–30 of 41 posts

Re: Goodbye, Object Oriented Programming (2016)

#21
I get what he is talking about, but to be honest alI never encountered a situation where I intentionally or unintentionally got to diamond inheritance. I just didn't... As for the add/addAll example, the smart thing to do is just not put too much in the public method or just declare it final...

Re: Goodbye, Object Oriented Programming (2016)

#22

It is always seems kind of cute when someone discovers something new and thinks it's a silver bullet. On a side note, .NET is not a language, it's a framework, like JVM. In fact F# runs on .NET and it is purely functional.

Did you read the end of the article? I mean I get what you are talking about, but I think the author went out of his way to say that he doesn't think FP is going to be a silver bullet.

Re: Goodbye, Object Oriented Programming (2016)

#23
I doubt there's very few OOP hardliners on here, I'm certainly not. So, let me play devil's advocate here a bit.

For the monkey-banana-jungle problem, it seems the developer started from a monkey-banana type in a previous project, rather than just the monkey. It seems in this case you would refactor the existing monkey-banana class, and extract a plain "monkey" class that satisfies both projects.

I've done things like this in the past, and it's a headache, but it's less painful than starting over from scratch. Most OOP languages will offer good type checking for the refactoring process, and can easily catch any errors. Also, dead code elimination can remove most of the unused methods and types from a large codebase.

Diamond inheritance is a bigger problem. However the example they give is terrible. Why wouldn't the powered device type be a common ancestor? One way forward here is to use composition plus an interface to satisfy a new top level type with shared functionality. It's ugly, but gives you some form of consistency over types that need to be loosely coupled.

The fragile base class problem is equally stupid imho. Counting is managed in two different ways from two different methods? Yikes! They also didn't think to test this, and the change passed all of existing automated tests? Yikes!

You can shoot yourself in the foot with functional programming as well. Anything that is shared can become fragile. Forming abstractions that cut across multiple concerns is still problematic and error prone. It's common to bring a jungle when you need a banana no matter what PL technique you use.

Re: Goodbye, Object Oriented Programming (2016)

#24

I feel that whenever someone complains about OO, it almost always starts with "I tried mapping everything to a class" and I always want to ask "Why?".

In Java everything has to be a class.

I prefer C++/Python style where things don't have to be classes. They can just be independent functions.

Re: Goodbye, Object Oriented Programming (2016)

#25
post #2

Yes! This is basically why my new language is functional, and not OO. I bought in the OO dogma in college, but programming in functional languages is just so much easier.

Any chance you can talk more in depth about this? I'm really curious! FP seems wonderful, but there are few side-by-side code examples out there.

That may be less useful than you think, since the FP versions of many OO design patterns are just functions. The FP design patterns can end up being quite different than the similar OO versions, if you can even call them design patterns.

So, all of this below is written in terms of FP beginners, so if I make a claim, it's in those terms, not general functional programming terms. I know that some of the information below is not entirely correct, just bear with me.

Some argue that FP doesn't really have design patterns, which isn't true, but can be a useful mental model to keep you from getting hung up on them while you're learning. Consider than many of OO's design patterns are built to structure mutations on data. FP, by contrast, doesn't (typically) mutate data. That's where things diverge, and that's fairly early in the learning process.

All that said, there are slews of things that can be "close enough" one-to-one mapped to an OO version, it's just that most of those things are fairly trivial. Map/filter/reduce vs. for-loops, for example.

Perhaps you could start there. Rewrite some for-loops with map/filter/reduce. Learn the rules they follow, learn what a monoid is and what laws it follows and why they're useful, go from there. Something that helped me early on was implementing each of those in terms of the others. For example, implementing filter with reduce.

Experimenting with good "playground" languages can help a lot. Hy[1] is an example of that, it's Lisp-flavored Python. You'll have a Lisp with a standard library that's very widely known, and you only need to install a Python module to use it (rather than, say, the entire Clojure stack).

The biggest takeaway is that FP is geared very heavily towards writing programs and data pipelines that are built with small, composable pieces that are ideally also associative. You can of course do this with OO, but then your code ends up looking like this:

    someFunc(anotherFunc(thirdFunc(data)))
Or:

    var someVal = thirdFunc(data)
    var anotherVal = anotherFunc(someVal)
    var finalVal = someFunc(anotherVal)
Or:

    // Mutate
    data = thirdFunc(data)
    data = anotherFunc(data)
    data = someFunc(data)
Compare to Clojure's version:

    ((comp third-func another-func some-func) data)
And Haskell's (might be wrong, I'm not a Haskell programmer):

    (thirdFunc . anotherFunc . someFunc) data
[1]: http://docs.hylang.org/en/stable/

Re: Goodbye, Object Oriented Programming (2016)

#26
post #2

Yes! This is basically why my new language is functional, and not OO. I bought in the OO dogma in college, but programming in functional languages is just so much easier.

Any chance you can talk more in depth about this? I'm really curious! FP seems wonderful, but there are few side-by-side code examples out there.

Sure. I presume you're asking about why FP is easier, though if you're wondering about my language there's more info at https::/darklang.com.

I think the quote about the gorilla and the banana and the jungle is a really important piece. It's just hard to compose things in OO languages unless they're designed to be used together. Whereas in an FP language, you focus on simpler primitives (arrays, hashtables, nullable types, and errors values typically, depending on the language), and you have a ton of functions that know how to work with those, so you kinda use them for everything.

A second reason is static typing (doesn't apply to the lisp family of FP). Good static typing makes it very easy to understand what's happening, and makes it hard(er) to make errors. For example, in OCaml, Elm and Haskell, it's impossible to have a NullPointerException, which is the biggest bug class in Java. Similarly, the biggest problem in a python/ruby codebase is "what exactly is this thing I have", a problem eliminated by the type system as well.

Of course, these features have a cost. It can sometimes be trickier to do things that are easy in dynamic OO languages like Python (and of course Haskell has layers of complexity so I don't recommend going near it), esp the learning curve if you're not familiar with FP. But being in deep in a functional codebase is much much easier than being in a deep in a java, ruby, python, js, etc, codebase.

If you're looking to check FP out, I recommend Elm, ReasonML, or Clojure.

Re: Goodbye, Object Oriented Programming (2016)

#27
This is overly simplistic and ranty. Sure, the OOP community got high on its own supply for a decade or two and is now getting some well-deserved criticism, but that doesn't make OOP the devil and it certainly doesn't make all of its claimed virtues null and void (no pun intended).

The "Banana Monkey Jungle" problem applies to any paradigm that involves defining things in terms of other things, including functions that call other functions. You avoid it by writing code that's well-decoupled, no matter what paradigm you're using.

The diamond problem is well-documented and has been solved or worked around by numerous variations on inheritance (referring to methods by their class explicitly, composition, etc.). It's a real problem with Java's "pure" inheritance, but the author doesn't really add anything new to that discussion.

The fragile base class problem is mostly a problem of poor interface definition (read: documentation). Assumptions were made because there was ambiguity, and then those assumptions went from true to not true.

"Object Oriented languages don’t make Contain and Delegate easy to do. They were designed to make Inheritance easy." It's clear this author has spent most of his time in Java. It's true that vanilla Java makes it difficult/annoying to implement delegation, but C# can do it just fine, as can TypeScript and (I believe) C++.

The Hierarchy Problem, once again, is solved by composition.

The author naively suggests that encapsulation is bad, but what he really means is that hiding values behind their functions is bad (debatable, but not crazy). Encapsulation is an essential building block of writing any nontrivial amount of code. Functions themselves are encapsulation. Libraries are encapsulation.

Finally, in the Polymorphism section, he actually bothers to distinguish the principle from how it's been traditionally applied inside OOP, unlike throughout the rest of the article.

OOP is flawed. OOP as passed down by the Java priests from On High circa 1995 was extremely flawed. But I'm weary of reading people's rants about it, especially when they can't distinguish ideas like encapsulation and polymorphism from OOP, and can't distinguish OOP from Java 1.0. Essays like this throw the baby out with the bathwater. These days some of OOP's critics are just as zealous as its proponents were in the 00s.

Re: Goodbye, Object Oriented Programming (2016)

#28
post #19

For anyone not wanting to read the opinion behind the click-bait-titled article, here's the TLDR: the author never learned how to write OO code and is now declaring it dead. Every problem he brought up is easily solvable by writing good code. FYI, I'm a big proponent of FP, but I'm not a proponent of disparaging things I don't fully understand.

> Every problem he brought up is easily solvable by writing good code.

I'm curious, how? Would you mind use one of his examples along with some good code?

Re: Goodbye, Object Oriented Programming (2016)

#29
post #25

Earlier quoted context omitted.

Any chance you can talk more in depth about this? I'm really curious! FP seems wonderful, but there are few side-by-side code examples out there.

That may be less useful than you think, since the FP versions of many OO design patterns are just functions. The FP design patterns can end up being quite different than the similar OO versions, if you can even call them design patterns. So, all of this below is written in terms of FP beginners, so if I make a claim, it's in those terms, not general functional programming terms. I know that some of the information be…

The usual Haskelly way is

  thirdFunc . anotherFunc . someFunc $ data

Re: Goodbye, Object Oriented Programming (2016)

#30
post #26

Earlier quoted context omitted.

Any chance you can talk more in depth about this? I'm really curious! FP seems wonderful, but there are few side-by-side code examples out there.

Sure. I presume you're asking about why FP is easier, though if you're wondering about my language there's more info at https::/darklang.com. I think the quote about the gorilla and the banana and the jungle is a really important piece. It's just hard to compose things in OO languages unless they're designed to be used together. Whereas in an FP language, you focus on simpler primitives (arrays, hashtables, nullable…

Thank you! Do you have any thoughts on Elixir/Erlang/LFE? Elixir is dynamic, but seems to have many of the benefits of a static type system by use of Dialyzer, Erlang's static type analysis tool.
Post reply on HN