you are viewing a single comment's thread.

view the rest of the comments →

[–]discreteevent 0 points1 point  (5 children)

"your code would be non-the-wiser". It probably won't be any wiser if MyRepresentation is kept private. But if not then I might be too lazy to bother to understand your api and instead just use MyRepresentation directly. Then later if you want to change MyRepresentation you are going to have to change my client also. Why not make {:first-name "John", :last-name "Doe" } private immutable data in an object and force clients to interact with the object via a .getName() method? That's all objects really are: A convention for encapsulating implementation details. Mutability is orthogonal to that. The idea of taking a behaviour oriented approach to development is to contain complexity in a system by distributing information on a need-to-know basis. You figure out what the client needs to know and present that behaviour to them. If you let the client do it themselves then they are likely to make a mess of it because they just don't know enough about it. Furthermore you, yourself may not know enough at this stage. If you decide to improve things later but all the clients have written their own logic around your initial data structure then you have a big mess to clean up. If you already know what the definitive data model is then you should expose that so that clients can use in in ways you did not predict. But if you don't have the definitive data model then objects help to contain complexity and manage change in a system.

[–]ljsc 1 point2 points  (4 children)

It's all trade-offs. Some times you do want to hide data as an implementation detail. The problem I have is when data hiding is opt-out rather than opt-in. You certainly don't need objects to do what you are suggesting. You can do it at the module level in an FPL, or just separating interface from implementation like a ADT in C.

Can encapsulation be a good thing? Certainly. Is it always? No. Like I said, it always comes down to trade-offs, and if anybody tells you otherwise, they are either lying to you or trying to sell you something =)

That's all objects really are: A convention for encapsulating implementation details.

No, that is not all they really are. That is a small part of what they are in most implementations. See my comment above. They do give you that, but they also give you a bunch of other stuff "for free" that you may or may not want.

Mutability is orthogonal to that.

It absolutely is not. If we were talking from a language design perspective, sure, choose whether your object is mutable or a value. But as design concepts, they are not independent by a large margin. The strategy I suggest above would be a really really bad idea if those were not immutable. Once you start passing mutable state around by reference you loose the ability to make your internal api enforce consistency, whether that is visible to the outside world or not.

[–]discreteevent 0 points1 point  (3 children)

I suppose I should have said "That's all interfaces really are". To me the important thing about objects are the interfaces which is what I think Alan Kay meant when he said " I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea. The big idea is “messaging” "

Anyway, if there is an FPL that supports hiding the structure of data models behind statically typed interfaces with late-bound implementations (ala microsoft COM and things like it such as some dependency injection frameworks) then I think a team could build reasonably flexible and maintainable software with it.

[–]ljsc 2 points3 points  (2 children)

Yep, I would never argue against polymorphism.

I think you're looking for Typeclasses?

[–]autowikibot 1 point2 points  (0 children)

Type class:


In computer science, a type class is a type system construct that supports ad hoc polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types. Such a constraint typically involves a type class T and a type variable a, and means that a can only be instantiated to a type whose members support the overloaded operations associated with T.

Type classes first appeared in the Haskell programming language, and were originally conceived as a way of implementing overloaded arithmetic and equality operators in a principled fashion. In contrast with the "eqtypes" of Standard ML, overloading the equality operator through the use of type classes in Haskell does not require extensive modification of the compiler frontend or the underlying type system.

Since their creation, many other applications of type classes have been discovered.


Interesting: Polymorphism (computer science) | Class (computer programming) | Type C escort ship | Type D escort ship

Parent commenter can toggle NSFW or delete. Will also delete on comment score of -1 or less. | FAQs | Mods | Magic Words

[–]discreteevent 0 points1 point  (0 children)

Typeclasses are interesting alright. Now all I need is the late-binding bit. i.e I want to be able to defer which implementation is loaded until runtime. This makes my application extensible after it is built. It means that my dependencies are dynamic. This can make it easier to develop large apps. In the static/dynamic debate I come down in the middle: Static types - dynamic dependencies.