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 hi…
Joe Armstrong: Why OO Sucks
71–80 of 267 posts
Re: Joe Armstrong: Why OO Sucks
#72OO 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…
If you just need a set of numbers which only has those three, a helper function with a modulus seems easier. Or an infinite list of [1,2,3]. But it's not clear to me what the use case is, so...
Re: Joe Armstrong: Why OO Sucks
#73I can express my OO ideas in erlang with no problem (objects become processes). I cannot express my concurrency ideas-- that erlang makes super easy-- in the OO languages. Maybe Go changes this but I haven't used Go yet.
Re: Joe Armstrong: Why OO Sucks
#74I'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 basic idea is to use a generalization of pattern matching. Languages like ML and Haskell support pattern matching, but in rather limited ways. Crucially, patterns are not first-class citizens of the language. (For Haskell, at least, there are some libraries to remedy this, but I don't know how effective they are.)
So how can we generalize pattern matching to help you solve your book problem? Normal patterns allow you to match data types in the form C x₁ x₂... where C is some constructor and x₁ x₂... are either matchable symbols or arbitrary patterns. An example of a pattern would be Chapter (Cons (Section content) rest). We differentiate between the matchable symbols and the constructors on case: lowercase means matchable, uppercase means constructor. This is somewhat limited: you cannot easily write code that is generic over the constructor at the head of the pattern. You could write a function that counts the sections in a chapter, but you could not write a function that counts the sections in anything.
So let's relax the restriction that patterns have to be headed by a constructor. We can now have patterns in the form x y. These are static patterns: you can match data against them without evaluating the pattern. With this, we can imagine writing a function to count sections generically:
count_sections x = 0 -- If this is some terminal, it cannot be a section
count_sections (Section content) = 1 + count_sections content
count_sections (x rest) = count_sections rest
This goes through the entire data type you passed in and counts all the sections it sees. It assumes sections can be nested. This will let you count the sections in a Book or a Chapter or a Series or whatever you want.So, this is generic over the data you pass in. However, if you wanted a function to count Chapters or Sentences or what have you, you would be forced to write it. This calls for another extension to pattern matching: dynamic patterns. Patterns are now in the form x ŷ where x is a variable and ŷ is a matchable symbol. Constructors are still uppercase, so Section is a constructor and not a variable.
A variable in a pattern can be instantiated with another pattern. So now we can write a truly generic count function:
count constructor (constructor) = 1
count constructor (constructor x̂) = 1 + count x̂
count _ (x̂ ŷ) = count ŷ
So now if you want to count chapters in your book, you would just invoke count Chapter book. If you want to count sections in your chapter? Easy: count Section chapter.You can also use patterns and constructors for polymorphism by overloading functions on different constructors. One interesting idea is to allow adding cases to functions after their definition. This way you could have an existing toString function and then, when you've defined a book, add a new case to it:
toString += | Book title content -> "Book: " ++ title
This way you can have a toString function that works on any type of data.All my examples are obviously in pseudocode. (And hey, it looks nothing like Python! The whole "runnable pseudocode mantra annoys me.) I haven't covered all the edge-cases, and I haven't even begun talking about a type system for this mess. Happily, there's somebody who has, and wrote a book about it (that's where I got all these ideas): Pattern Calculus by Barry Jay[1].
[1]: http://www.amazon.com/Pattern-Calculus-Computing-Functions-S...
I'm also not sure whether this is the best possible approach. However, I think it's certainly very neat. If you like this idea, the book is definitely worth a look.
Re: Joe Armstrong: Why OO Sucks
#75Earlier quoted context omitted.
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…
Reading the article, I don't think the author quite understands OOP. The original author is Joe Armstrong ( http://www.sics.se/~joe/ ), the creator of Erlang.
Either that, or I'm completely misunderstanding him. He can't be talking about hating composition, though, can he? He uses it in his own Erlang examples!
Re: Joe Armstrong: Why OO Sucks
#76I'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…
For a book, I would keep the text itself as something very simple, such as a big old list of lines. A chapter is a range of lines. A section is also a range of lines. Adding subsections is a matter of adding a field to Book and it is (surprise) a range of lines, too. You could implement this as a byte offset if you wanted, but you get the idea. If the text of the book is data, the rest is metadata. IMO it should live…
Maybe, but I'm not sure. If you don't encapsulate the data behind an API, then I suspect that you will eventually be sorry. And if you do encapsulate the data behind an API, then you're doing OO.
You may be right that your design for the representation of the book may be better than the typical naive OO representation, but there's nothing that forces an internal OO representation to be naive, or for an FP one to be sophisticated.
I guess what I'm saying is that I still don't understand how the FP approach is supposed to be different from the OO approach using the Law of Demeter. With the law of Demeter, methods only return data, not other objects ("two dots: bad"), so it's not as object-filled as a more naive OO approach. And in a case such as your FP representation for a book, where the representation is bound to be rather complicated, it seems that you will surely want to encapsulate it, in which case, the FP approach has adopted some OO. I.e., the FP approach and the OO approach have met in the middle and have become the same.
Re: Joe Armstrong: Why OO Sucks
#77Earlier quoted context omitted.
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…
So, basically what you are saying, as far as I can tell, is that there is absolutely no difference between the OO approach using the Law of Demeter and the FP approach. (Though with an FP approach, you are perhaps more likely to make things immutable, which is a good thing.) If so, perhaps this isn't surprising, as Demeter was layered upon Scheme. Regarding writing to databases or to screens, decent OO programmers do…
Regarding Demeter, naming an anecdotically supported observation "Law" is a bit of a stretch ;)
Re: Joe Armstrong: Why OO Sucks
#78Re: Joe Armstrong: Why OO Sucks
#79Earlier quoted context omitted.
harmful.cat-v.org has a lot of odd opinions: http://harmful.cat-v.org/software/dynamic-linking/ http://harmful.cat-v.org/political-correctness/girls-in-CS
The second link is to gibberish from reddit. Not sure if it's a joke or if it represents the opinions of cat-v. But the first link is on the money. I would not call it "odd" as that seems to carry a negative connotation. Rather, it's sensible, albeit irreverent, thinking to question dynamic linking (as the Plan 9 people have) and alas the mainstream of software development has a difficult time thinking sensibly and p…
> All the purported benefits of dynamic linking [..] are myths while it creates great (and often ignored) problems.
which is tripe.
In my view, the fundamental problem with static linking as we currently know it is that when libraries release bug fixes-- especially security fixes (which I think are the real clincher), but really any of the minor bug fixes that happen all the time in more complex libraries-- you almost certainly want all the programs on the system that use the library to switch to the new code, and by the nature of libraries, there are probably a lot of them. In some cases you could rely on a distro / traditional package manager to provide new binaries for everything, but that would be a lot of wasted bandwidth and even if you don't use proprietary software, you probably want to be able to use some software from outside the distro. So you really need an automatic re-linker of some sort and probably a new binary format that can be re-linked, and some infrastructure to keep track of what binaries exist on the system and what they depend on. Plan 9 never had that, and at that point I think you're solving more fundamental problems than static vs. dynamic linking (which is a good thing) and should take a step back and see what you can do with it, but who knows-- it might be interesting to talk about, but you have to come up with it first. :)
General comments on your post: I think the boundary of a library is not quite arbitrary, because
- libraries tend to be developed independently by different people! It might be nice to develop things in a more unified fashion, but in general I don't think you can avoid people having specific (functional) interests and areas of expertise, and it's nice to have a unit of code that someone can "own".
- random interdependencies tend to be a bad thing; ask Google. Organization is good.
- many libraries have the job of parsing file formats or doing other things where the selection of which functions to invoke generally comes from user-supplied data-- you can't ask for half of FreeType or, dare I say it, WebKit; you need to be able to parse whatever the user throws at you, so it's all or nothing.
Which is not to say here couldn't be improvements.
Re: Joe Armstrong: Why OO Sucks
#80OO 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…
I'm a Haskell n00b, but there is Functor, Foldable and friends, right? That's basically what you're talking about, although the methods are generalaized map, fold and so on instead of get and length. It seems like this just supports your point: there's nothing making functions operating on data in an FP less abstract than objects and methods.