Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Point = {x, y} is a strange example. What exactly is being encapsulated? Any Point structure I've ever seen has accessors for x and y, and no other internal data.

In general, I don't see the need for encapsulation in order to qualify for object status. The classic counterexample is CLOS, which doesn't have it -- and the debate over that has been raging for decades [1].

[1]: http://wiki.c2.com/?HowObjectOrientedIsClos

The best basis for the essence of object-orientedness that I ever read was suggested in an article that focused on identity. (I don't remember where I saw this -- possibly from Kent Pitman?) If you could guarantee that some value is exactly the same as a value that you had earlier, and not just a mostly-copy but identical in every respect, then you had an object. Everything else falls out of that.



This is a great question. I thought that myself, so I tried to make a system where I couldn't access x and y. It turns out it's completely reasonable to do so. If you want to move a point, you add a translate method. If you want to compare points you can. You can add and subtract points. If you want to align a group of points on the X access, you can write a method on point to do it. There were very few times when I wanted to actually access x and y rather than act on it.

I do agree, though, nobody actually writes code like that. Does that mean that I think nobody actually does OO? I hadn't actually thought it through that far :-) I think this is why the concept is so vague (your excellent example being a great indicator of that). C++ is often referred to as "C with Objects" and I sometimes think we've gone so far as to say anything with a function that operates on a structure is "Object Oriented". If so, I think we've lost our path a little bit.


You can keep adding mathematical transformations to the Point object all day long (though at some point you'll realize the mathematical operations don't belong there, and the concept of "point" isn't abstract enough - the study of right abstractions here is called "algebra"). But there comes a moment when you want to draw that point on the screen, and suddenly there's a good chance you'll have to access individual components, because the API of your drawing device doesn't understand your particular Point class.

Arguably this is still within purview of "Point" abstraction, but:

> If you want to align a group of points on the X access, you can write a method on point to do it.

This calls for a static method really, otherwise the abstraction becomes subtly wrong. And with static methods you quickly realize that you're using the containing class as just a namespace.

CLOS actually resolves this nicely by having methods being their own things separate from classes. As a related side effect, the typical C++/Java case of "object methods" isn't a special thing in CLOS, it's just a method that happens to be polymorphic only on its first argument. The abstraction around methods seems cleaner, and the class in CLOS is just responsible for encapsulation and inheritance, not for namespacing methods.


It sounds like all you're really doing is taking any function that does want access to X and Y, and shoving it into the Point object where it has that access. Or to put it another way, you're defining any function that wants access as "part of the concept of point". You can indeed accommodate any code with this transform, but is it the right thing to do? Do you gain anything by bloating up 'point' with transformations and comparisons and alignment operators and so on?


Of course you gain something. By encapsulating all methods that operate on X and Y in a single place, Point (where X and Y are defined), it is now _much_ easier to change X and Y. It's all right there in one file.

Point {x, y} may not be the best example, but you can certainly see how this can be beneficial should X or Y become something even slightly more complex. And this is the purpose of encapsulation - to make a system easier to understand and therefore easier to change.


The Point could internally be represented in a polar coordinate system.

I kind of agree that encapsulation isn't needed for object status. The caveat only being that it would be a weird object system where you could be sure there was no encapsulation.

I mean, OK, in some languages you know that. But does it change anything important?

https://en.wikipedia.org/wiki/Polar_coordinate_system


Even if a point uses polar coordinates internally, we can have syntax "p.x" which gets the Cartesian x.

Information hiding is an important concept in low-level-ish systems programming languages in which p.x implies a piece of machine code that offsets 24 bytes from the base address of p, and fetches a four byte integer.


This Point class is a poor example because it does not have anything that is not part of its interface, and, as presented here, does not have any constraints on it.

The intended purpose of encapsulation is to try and preserve integrity of a system by restricting the ways a programmer might put it into an inconsistent state. Knowing that certain constraints are in place simplifies the problem of understanding and debugging a system.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: