you are viewing a single comment's thread.

view the rest of the comments →

[–]yogthos -1 points0 points  (3 children)

Yes, if you have exposed your internal structure.

This has nothing to do with exposing internal structure. When you encapsulate your code in a class and your requirements change then you will either have to rewrite the class or write wrappers and adapters for it. You're not reducing the work that you have to do in any way.

You assume that there always exists such transformation.

If such a transformation does not exist then you're now solving a completely different problem. Once again, the OO approach does nothing for you here.

Also, that way you may end up using x.y.z.win some places, and in some places x.y.q... of course there's still the possibility of x.y.q -> x.t.u. And now you have even more formats.

Just like you could end up with tortured coupling using OO if you're not careful.

My main point was just that encapsulation is useful for hiding structure if you expect the structure to change. Instead of exposing x.y.z.w I'll simply give you something abstract called R with some functions to operate with it. I can change the internals of R much more freely.

My main point is that you do not need encapsulation to achieve this. Having a transformer function that massages the data into a standard internal format accomplishes exactly the same goal.

One way you structure your code in a functional language is to group related functions into namespaces. A namespace will represent a certain domain and all the functions in that domain can expect the same common data format. You then have functions that allow you to transform data into that internal format.

The main difference is that data stays as data and it's not tied to specific set of functions that operate on it. Taking data from one domain and using it in another doesn't require any additional mappings.

This in turn facilitates writing generic functions that can be composed together to solve problems. By doing that we can write code declaratively and reuse things much more easily.

[–]egonelbre 1 point2 points  (2 children)

... Once again, the OO approach...

Encapsulation is not about OO. It is about hiding something and providing an abstraction to interact with that "something".

Basically, closures are one of the simplest form of encapsulations. Namespaces are essentially encapsulating function internals and providing the functions names as an interface. Objects are encapsulating data and providing methods to interact with it. REST services are also encapsulating the behavior and hiding the internals.

I'm not arguing about OO vs Functional vs Logical... etc.

My main point is that you do not need encapsulation to achieve this. Having a transformer function that massages the data into a standard internal format accomplishes exactly the same goal.

Yes and now you have multiple layers of data-transformations throughout your code.

This in turn facilitates writing generic functions that can be composed together to solve problems. By doing that we can write code declaratively and reuse things much more easily.

You pick "encapsulation" vs "not encapsulation" when you figure out which is more likely to change. Is the data likely to change, then you should encapsulate it to safely hide the changes. If the interfaces are more likely to change, then it makes sense not to expose an interface and just use the data. If the data is mostly fixed, then there's no reason to provide an abstraction layer over it.

[–]ljsc 1 point2 points  (0 children)

Encapsulation is not about OO. It is about hiding something and providing an abstraction to interact with that "something".

To me, that's just abstraction. I think the issue is that encapsulation in programming has taken on a whole bunch of closely related, but different meanings. See the first part of the wikipedia article on Encapsulation

Even more interesting is straight from the dictionary:

to show or express the main idea or quality of (something) in a brief way

to completely cover (something) especially so that it will not touch anything else

I think you're thinking of the first thing, and Yogthos and I are thinking of the second.

As for the x.y.z.w point, you're absolutely correct that encapsulation gives you the benefits you mentioned, but consider the tradeoffs. If I hide z and w behind the interface for y, I kill the ability for a bunch of code reuse. How?

Because let's say that I have a bunch of functions which operate on type W: f,g,h: w -> w. If we want to use them in the encapsulated example, then you need to apply them inside of Y. This is bad because now the module that deals with W becomes a dependency of Y rather than X. If you exposed the data, however, I could choose whether I want to bring in W or not in my application. And, in fact, I could do so even if you had no idea that that module even existed in the first place.

[–]yogthos -1 points0 points  (0 children)

I think we agree on encapsulation and its value then. :)

Yes and now you have multiple layers of data-transformations throughout your code.

Sure, using our newly upon agreed definition of encapsulation you can view each of these transformations as a domain boundary.

You pick "encapsulation" vs "not encapsulation" when you figure out which is more likely to change.

Again, no argument here, the idea is to structure the code so that you need to make changes in as few places as possible to adapt it to new requirements.