A language or system is object oriented if it supports the dynamic creation and use of objects. Support means that objects are easy to define and use. It is possible to encode objects in C or Haskell, but an encoding is not support."
I'm perfectly happy to not call Haskell "object oriented", but I fail to see how the "record of closures" pattern fails to meet all of his criteria including ease of creation and use.
Edited to add: To be clear, I fully agree with him that typeclasses have nothing to do with OO in Haskell, by his definition of OO.
That being said, you can easily create a data type in Haskell that contains a bunch of "methods" that live in the IO monad and mutate other bits of data the object contains that also live in the IO monad, but it's a bit of a forced paradigm.
Sure, though to be clear I'm not taking any position on that question above. I just think that the pattern solidly fulfills all of the criteria he gave, and it's not a terrifically obscure one.
'That being said, you can easily create a data type in Haskell that contains a bunch of "methods" that live in the IO monad and mutate other bits of data the object contains that also live in the IO monad, but it's a bit of a forced paradigm.'
I think what you're getting at here is that persistent identity and mutable state are necessary parts of IO? It's clear that they're often assumed to be; I've encountered the question before and I lean weakly "no", although not with confidence. More importantly, they are explicitly disclaimed as being an inherent part of IO as defined in the article, so were not what I was speaking to. I agree that an IO-backed message passing object framework 1) could be built in Haskell and 2) would not be a natural fit.
1. "An object is a behavior." This is a meaningless or misleading use of "is" to me. I prefer "an X with behavior" or "a thing distinguished by (considered for?) its behavior."
2. The statement that not all Java classes define objects (for example, ones with lots of fields), and that saying this is in keeping with common ways of speaking. No, a programmer would call any object in Java an "object." I get that the point is to say that a struct does not make an object, but the point seemed overstated in that case.
3. Objects must have "recognizable identity," but you don't have to be able to compare the identity of two objects (really it should say two object values or two references). "Recognizing" is being used in a very abstract way here, to avoid invoking state to explain the potential difference between objects. I think it's a little too subtle, even if the point is elaborated on later. If you have any other way to articulate what gives objects identity even if you can't detect it directly, I think it would help. To most readers, I think "recognizing" identity would mean being able to check whether you have a reference to a given object or not, which means being able to compare references. Are there OO languages where you can't? I'm not objecting to downplaying identity.
The original OO language, that is the lambda calculus, had no reference comparison -- All You Can Do Is Send A Message is the slogan in general. http://www.erights.org/elib/equality/grant-matcher/history.h... lists some less familiar ones.
Given mutability, identity determines how a message to one object reference affects what happens when you invoke another one. If you go up from the above URL you'll see a bunch more discussion.