> The protocol method clearly has access to the contents field of the record, scoped by the record definition.

Thank you for pointing this out. I have learned something today. I didn't know that protocols implemented inline within the deftype and defrecord macros were actually given direct access to the fields. And even more surprising to me, that mutable fields on deftype are actually made package restricted. Well then, I have to concede it to you, even within my definition of OOP, deftype is now an equivalent construct to my concept of objects. Those methods are no longer trait like, they're full blown object methods, with special privileges, and tight coupling to the mutable data fields. They can not be defined separately to the type, and a type can not be extended outside its definition to support such methods.

> I am not saying that traits/protocols/interfaces/typeclasses are necessary for OO, I am saying that they are sufficient.
> Object isn't a keyword in any of the languages we've mentioned. But we know how to find them and what they are. I don't understand why you can't see this one.

So how would you define OO? I get it your are in the camp that equal polymorphism to OO? And by the way, I do see it. Clojure/Script has object-based constructs. If you think of the more general sense for object, which is identity + attributes, records fit the bill. This is defined here https://en.wikipedia.org/wiki/Object_(computer_science)#Obje.... Now, I also agree with you, it even has a construct that groups data and behavior together in the form of deftype with mutable fields. So at this point, it has support for OOP.

What I'm really arguing is just a taxonomy. I see three distinct characteristics. The grouping of data and behavior together behind an object (OO). The ability to dispatch to different implementations of a procedure based on the datatype (type polymorphism). And the ability to inherit behavior from the behavior of an associated parent (inheritance). And this is my preferred taxonomy.

In that sense, prior to me learning about deftype with mutable fields, I saw Clojure/Script as supporting type polymorphism using either protocols or multi-methods. And inheritance through multi-methods. But I did not see anything to group data and behavior together behind an object. Thus I did not consider it had support for OO.

I know some people say polymorphism alone is the essence of OO. Thus Haskell, Rust, Clojure/Scipt, Go, PureScript, and others are all OO languages. I don't know though, I feel the average dev doesn't think of it that way.

Other people think of OO as the bundling of data and behavior, and that seemed much more reasonable to me. This is how the Gang of Four book defines OO for example. And this is how I like to think of it also.

But, after this conversation, I wonder if I don't prefer the definition from the wiki link I shared. Where OOP is the combination of all three. A single construct which groups data and behavior, and allows polymorphism as well as inheritance. And this is what is known as an object, and all three must be present to be considered OOP. With this definition, I think Clojure/Script wouldn't fit as OOP. Since, and tell me otherwise, deftype doesn't support inheritance. And multi-methods don't group data and behavior.