Live data from Hacker News

Joe Armstrong: Why OO Sucks

harmful.cat-v.org

51–60 of 267 posts

Re: Joe Armstrong: Why OO Sucks

#51
post #24

OO vs. FP is just a matter of whether you focus the nouns or the verbs. The counterargument to the OP is that surely a function that manipulates "data" is less powerful and abstract than one that manipulates objects. For example, take an "interface" or abstract data type like Array, consisting of a length() and a get(i) method. (This is really called List in Java and Seq in Scala.) There may even be an associated typ…

In Haskell I guess it would look like this: I'm still new to Haskell hopefully someone can improve it? data M = M1 | M2 | M3 deriving(Show, Eq, Ord) fromM M1 = 1 fromM M2 = 2 fromM M3 = 3 instance Num M where abs = abs a + b = fromInteger (mod ((fromM a) + (fromM b)) 3) a * b = fromInteger (mod ((fromM a) * (fromM b)) 3) a - b = fromInteger (mod (abs $ (fromM a) - (fromM b)) 3) fromInteger 0 = M3 fromInteger 1 = M1 f…

A more generic version allows you to parameterize based on the bound:

    newtype BoundedInt b = BoundedInt Int

    class Bound b where
      boundRange :: t b -> (Int, Int)

    fromBounded :: BoundedInt b -> Int
    fromBounded (BoundedInt x) = x

    toBounded :: Bound b => Int -> BoundedInt b
    toBounded x =
      let result = BoundedInt x
	  (minb, maxb) = boundRange result
      in if minb  Num (BoundedInt b) where
      abs = toBounded . abs . fromBounded
      negate = toBounded . negate . fromBounded
      signum = toBounded . signum . fromBounded
      x + y = toBounded (fromBounded x + fromBounded y)
      x - y = toBounded (fromBounded x - fromBounded y)
      x * y = toBounded (fromBounded x * fromBounded y)
      fromInteger = toBounded . fromInteger
This assumes you want exceptions for overflow. Nowadays, you can put numbers in the type system, obviating the need for a "Bound" class, but I'm not familiar with it yet. The implementation above will also silently overflow given large enough bounds.

Re: Joe Armstrong: Why OO Sucks

#52

OO vs. FP is just a matter of whether you focus the nouns or the verbs. The counterargument to the OP is that surely a function that manipulates "data" is less powerful and abstract than one that manipulates objects. For example, take an "interface" or abstract data type like Array, consisting of a length() and a get(i) method. (This is really called List in Java and Seq in Scala.) There may even be an associated typ…

"The counterargument to the OP is that surely a function that manipulates "data" is less powerful and abstract than one that manipulates objects."

I don't see how that follows at all. Objects are glorified types. They're a bag of state plus a collection of functions which take that state as an implicit parameter. Polymorphism is "just" a form of delegation, which itself does not require you to glue together data and functionality.

If this were Haskell, you might define a typeclass for a List datatype.

    class List a where
      length :: Int
      get :: Int -> a
      ...
Then implementors for Heap and Array would do something like this in their respective packages

    instance List (Heap a) where
      length x = ...
      get x i  = ...

    instance List (Array a) where
      length x = ...
      get x i  = 
And so on. Functions which want a List add a type restriction:

     addListLengths :: (List a) => [a] -> Int
     addListLengths []     = 0
     addListLengths (x:xs) = length x + addListLengths xs
addLengths doesn't care if List is a Heap or Array, and calling length on a List will do the right thing.

I suspect there are cultural factors at work more than anything else, which does get back to what you say initially: do you prefer to live in the Kingdom of Nouns, or not?

In practice, I don't think there's a List typeclass in Haskell. I suspect people generally just use a bog-standard list. :) If you want a special implementation like a heap, you go find one and use it. I suppose this is one example of a cultural of "explicit is better than implicit."

Myself, I write in Java regularly and I just don't generally see a whole lot of value in the List abstraction over ArrayList or LinkedList or whatever. I suppose the reader can see List and take it as a given that it'll behave in some way. That's something.

On the other hand, I suspect the programmers don't think much about a List, either. It's a bit worrisome to contemplate the idea that not only don't programmers know what object they're really dealing with, but they shouldn't know. I highly recommend perusing "Building Memory-efficient Java Applications: Practices and Challenges"[1], which really gets into this stuff at a technical level. I don't know the extent to which this happens in FP-land; I'm mainly commenting on Java culture as I have observed it.

[1] http://www.cs.virginia.edu/kim/publicity/pldi09tutorials/mem...

Re: Joe Armstrong: Why OO Sucks

#53

Earlier quoted context omitted.

In my experience I'd guess you aren't dealing with a deficiency of OO, after all Python is an OO language. I'd bet you are dealing with over-engineering, which is a cultural issue within the Java/J2EE community. And perhaps a lack of closures (I prefer those over list comprehensions, since they are more general) which make java needlessly verbose.

Languages are not inherently OO or FP, but they support OO or FP style programming. Python supports procedural programming very well, you'll see lots of "def" and no "class". If you argue that the integers and strings manipulated by a procedural Python program are called "objects" and therefore it is still OO, I shall point you to the C standard which indicates that the integers and strings in a C program are also ca…

I agree, but I do think that java, in particular, suffers from two distinct problems:

1) A lack of closures, which, as you point out, turns every obviously functional problem into a ridiculous object model.

2) A culture that creates libraries that suffer from over-abstraction, over-engineering and that tend to model a technical aspect of a problem rather than what a non-expert end user of the library would find intuitive.

Re: Joe Armstrong: Why OO Sucks

#54
Wow, I am genuinely shocked by the comments in this thread. I didn't realise that so many people held the polar opposite view to me. It's a bit like suddenly finding out that all your friends are racist.

I love object oriented programming. For me it aligns perfectly with the way I think - it allows me to produce a system of interrelated 'things' where each thing (or group of things) has a well-defined role and can hide its internal state and behaviour from other things.

When I see how some code tackles a problem I get an emotional response from how 'clean' it is. Does it smell bad or is it a work of beauty and elegance? If the code feels wrong I get an urge to make it better and for me that process of improvement relies heavily on object-oriented concepts. I get a real buzz from creating a clean, elegant solution to a problem: Trying to do that without object-oriented features would be like trying to write a letter by holding the pen with my teeth. Ugh.

Re: Joe Armstrong: Why OO Sucks

#55
I'm all for proper rants against popular tools to keep people on their toes.

This isn't one of those.

"Objects bind functions and data structures together in indivisible units. I think this is a fundamental error since functions and data structures belong in totally different worlds."

Sure—a class defines a type and operations on that type. What's fundamentally wrong about date.addDays(1) vs. date_add_days(date, 1)? (Let's skip the mutable state argument and assume both versions return a new date.)

There is the problem that sufficiently opaque classes are hard or impossible to extend. That's the class author's fault: this is an avoidable problem in every object-oriented language I've used.

"Functions are understood as black boxes that transform inputs to outputs. If I understand the input and the output then I have understood the function. … Functions are usually 'understood' by observing that they are the things in a computational system whose job is to transfer data structures of type T1 into data structure of type T2."

A constructor is a black box that converts a data structure of type T1 into a data structure of type T2. Objects just also have other black box functions defined on them.

Sure, some objects are stateful, but they don't have to be.

"In an OOPL I have to choose some base object in which I will define the ubiquitous data structure, all other objects that want to use this data structure must inherit this object."

Um, no. This is a job for composition, not inheritance.

"Instead of revealing the state and trying to find ways to minimise (sic) the nuisance of state, they hide it away."

They hide state's implementation, for mutable objects.

  std::vector some_list;
  std::cout 
Sure, an allocated piece of memory might have grown, or even moved. Why should I care? I still see the state I care about, presented through a hopefully useful abstraction.

This rant seems to somehow miss the points of both object-oriented and functional programming, instead harping on mostly meaningless (or outright wrong) details. Or am I missing something here?

Re: Joe Armstrong: Why OO Sucks

#56

I've been watching some talks online recently by Rich Hickey of Clojure fame, and he's a very interesting and convincing speaker. He basically makes the same argument that Armstrong makes here. I'm not clear, however, how the pro-FP, anti-OO crowd address the Law of Demeter, which is often summarized as "One dot: good. Two dots: bad." The canonical example where the Law of Demeter serves us well comes from some of th…

Caveat. I never saw any mathematical formalization for Law of Demeter. Contrast this with the Substitution Principle, which is directly defined in terms of logical implication.

With the regard of the example presented, there is at least a trivial solution. There is a BookApi which is concerned with providing Book operations, and there are the Book/Section/Paragraph data types. List getAllSentences(Book) is defined by the BookApi. Changing the data types doesn't affect any client of the BookApi, only the implementation of the BookApi.

Conversely, coupling the methods to the actual data types results in inflexible designs. Should a Book know how to display itself in a gui widget? Which widget library? Should a Book also know how to save itself in a database? Which database api?

Re: Joe Armstrong: Why OO Sucks

#57
post #25

99% of the time I read these articles that say $commonly_used_thing [1] sucks, the arguments are always "it is fundamentally incorrect" or some variant thereof [2], and strawmen [3] abound. Where these arguments fall short are in addressing the simple fact that highly-skilled people produce very neat, well-designed systems that they are pretty happy with from a technical standpoint, and that make money every single d…

Every time someone says $commonly_used_thing sucks, people come out and point out that $commonly_used_thing is being used for $productive_activity. It is possible to do amazing work with broken tools, or with the wrong tools. That doesn't mean these tools aren't broken or that they couldn't be better matched to the job. Not that I think OOP is inherently evil. Reading the article, I don't think the author quite under…

I essentially agree with what you're saying, although in most cases, I would argue against the characterization of the tool as "broken". But I think that's semantics.

If this article was titled "Functional programming offers a number of advantages over OOP when dealing with $productive_activity"[1], my response would have been positive.

[1]: It goes without saying that the article would have to live up to the title. Obviously merely re-titling this article in such a way wouldn't be sufficient.

Re: Joe Armstrong: Why OO Sucks

#58
post #43

I've been watching some talks online recently by Rich Hickey of Clojure fame, and he's a very interesting and convincing speaker. He basically makes the same argument that Armstrong makes here. I'm not clear, however, how the pro-FP, anti-OO crowd address the Law of Demeter, which is often summarized as "One dot: good. Two dots: bad." The canonical example where the Law of Demeter serves us well comes from some of th…

The standard lisp approach is to define your API first, and write code the meets the API. You define your API in a manner that makes the solution to the problem you're trying to solve obvious. So behind this API, you can change your data representation however you please -- just don't break the API. As for your specific question, which representation of a book is the simplest solution? That's the one you should be us…

The funny thing is that most of these APIs wind up with what's essentially a "this" pointer at the front of every argument list so you're really doing OO anyway.

I'd like to read a persuasive critique of OO but so far I haven't found one. Time objects are a really bad example because time calculations are exactly the kind of hairy mess you want to hide behind some kind of abstract API.

Re: Joe Armstrong: Why OO Sucks

#59
post #43

Earlier quoted context omitted.

The standard lisp approach is to define your API first, and write code the meets the API. You define your API in a manner that makes the solution to the problem you're trying to solve obvious. So behind this API, you can change your data representation however you please -- just don't break the API. As for your specific question, which representation of a book is the simplest solution? That's the one you should be us…

Would an API be defined as "A set of functions that define the available operations common to that set?" If so, would those functions then delegate to progressively more concrete functions that work against data structures to perform their duties? I suppose it's obvious where I'm going here. I don't see how this is any different from just saying the word "Object." Don't get me wrong, I'm not trying to come off too sa…

Each Module defines an api that talks about N different ValueTypes. Saying the word Object limits the api to expose exactly one ValueType.

Re: Joe Armstrong: Why OO Sucks

#60
post #39
post #9

I don't get it. If people don't like OO, why don't they just not use it. Just use your favorite methodology to get the job done. Why do they have to bad mouth it?

If we fail to point out the harmful effects of excessive OO usage then there is a higher likelihood of encountering it as legacy code written by people who didn't know any better. This can lead to wasted time and decreased job satisfaction.

[deleted]
Post reply on HN