Live data from Hacker News

Classes vs. Data Structures

blog.cleancoder.com

11–20 of 184 posts

Re: Classes vs. Data Structures

#11
What the author calls "objects" (or "classes") is really often just "interfaces".

> An Object is a set of functions that operate upon implied data elements

If this is replaced with:

> An Interface is a set of functions, often operate upon implied some implied data elements (but not necessary).

Everything in the article will probably be less confusing.

Re: Classes vs. Data Structures

#12
And while the discussion takes place and the debate rages between classes vs. data structures, there's some poor analyst or data scientist who just needs access to the damned data to load it into a pandas data frame to do things that those designing the objects and data structures never dreamed of in the first place...

Re: Classes vs. Data Structures

#13
post #3

The claim that "an object is a set of functions that operate on implied data elements" has a strange corollary because of how in modern OO languages like Java or C#, there is no syntax or popular naming convention to tell the difference between a data structure and an Object. For example, in Java, a LinkedList object is actually not a linked list, it is a set of functions that operate on an implied linked list. If th…

In Haskell this can be pushed further, by making existential types, i.e. opaque type that's only known to implement some type class. This doesn't seem to be that useful in Haskell (I think it's because of the immutability), but trait objects in Rust are pretty much the same and are used more often.

As a side note, I hope that the situation with pre- and postcondition checking improves (runtime verficiation like in Racket seems too heavyweight for me, dependent types alone are kind of clunky, type refinements are either bolted onto existing languages (LiquidHaskell, F7) and don't always fit, or exist in very obscure ones (F*)), and we can drop information hiding for the sake of safety alone. I don't like how today the "safe" option is to severly limit what you can do with a data type (want to safely index an array? just use an iterator! oh, you wanted to index two arrays at once? just zip them and hope the compiler makes the tuples go away! you wanted O(1) indexing? too bad, no can do).

Re: Classes vs. Data Structures

#14

This is really hard to follow and I'm not sure I'm understanding it the way he intended. Correct me if I'm wrong, but he seems to be saying that, to avoid breaking consumers of your library often by changing the implementation, hide the implementation details behind classes, right? This seems to be a common reaction to someone who experiments with the "freedom of functional programming" where that freedom means opera…

I don’t think he’s exactly advising any particular action. Rather, data structures and objects tend to be badly conflated, and there’s a lot of value in clarifying the distinction between them. You’ll use each in different circumstances, for different reasons, by weighing the needs of the system against the design tools at your disposal.

In Rust, we keep the same distinction by modeling data structures as structs and enums, and modeling the “object” side by traits (whether static- or dynamic-dispatch). Traits decouple a consumer from the particular data and emphasize a behavioral contract, allowing any data structure to implement the desired behavior.

Re: Classes vs. Data Structures

#15
post #14

This is really hard to follow and I'm not sure I'm understanding it the way he intended. Correct me if I'm wrong, but he seems to be saying that, to avoid breaking consumers of your library often by changing the implementation, hide the implementation details behind classes, right? This seems to be a common reaction to someone who experiments with the "freedom of functional programming" where that freedom means opera…

I don’t think he’s exactly advising any particular action. Rather, data structures and objects tend to be badly conflated, and there’s a lot of value in clarifying the distinction between them. You’ll use each in different circumstances, for different reasons, by weighing the needs of the system against the design tools at your disposal. In Rust, we keep the same distinction by modeling data structures as structs and…

So basically mixins, right? Those were hard to use correctly in Ruby, because you might have multiple whose behavior clash because they can access the same data and were not written with each other in mind. I wonder how Rust solves that.

Re: Classes vs. Data Structures

#16
post #6
post #4

Earlier quoted context omitted.

the existence of `List` implies that e.g. `sort` exists? The existence of List implies that operations must exist to insert an element in a list, access to elements in a list, find out the size of the list, etc. Edit: BTW 'implies' is the the magic word in the text. It's what creates all the appearance of meaning. Try to replace it what something else. Now I remember why I disliked Plato so much.

I thought about using `[]`or `indexOf` as examples of operations, but my question still remains: what is implicit about it? It's part of the public interface of `List`. Not at all like the private members of an object, which I think was the analogy being made.

Those aren't implicit because the "public interface" is the Object List, not the Data Structure List.

    struct list {
      float node;
      struct list *next;
    }
Above is the data structure; it implies operations. Below is an interface (class, in the article); it implies data.

    #define LIST_H
    
    float index(struct list *ls, int i);
    int find(struct list *ls, float x);
    void sort(struct list *ls);

Re: Classes vs. Data Structures

#17
post #14

Earlier quoted context omitted.

I don’t think he’s exactly advising any particular action. Rather, data structures and objects tend to be badly conflated, and there’s a lot of value in clarifying the distinction between them. You’ll use each in different circumstances, for different reasons, by weighing the needs of the system against the design tools at your disposal. In Rust, we keep the same distinction by modeling data structures as structs and…

So basically mixins, right? Those were hard to use correctly in Ruby, because you might have multiple whose behavior clash because they can access the same data and were not written with each other in mind. I wonder how Rust solves that.

Not quite. A mixin is a piece of code written once and transcluded into another module. Traits are more related to OOP interfaces: every type implements one in its own way. The difference with interfaces is that traits can be implemented separately from the definition of the underlying data type, which clarifies the distinction between inherent operations on a specific data structure, and derived operations that bind it to a more general contract of use.

Re: Classes vs. Data Structures

#18
post #4
post #2

This conversation reminds me of https://en.wikipedia.org/wiki/Expression_problem . I don't understand: "but the existence of the data structure implies that some operations must exist." Grounding it out to a specific data structure, the existence of `List` implies that e.g. `sort` exists? That direction makes less sense than `sort` implies the existence of e.g. `List`(something to be sorted).

the existence of `List` implies that e.g. `sort` exists? The existence of List implies that operations must exist to insert an element in a list, access to elements in a list, find out the size of the list, etc. Edit: BTW 'implies' is the the magic word in the text. It's what creates all the appearance of meaning. Try to replace it what something else. Now I remember why I disliked Plato so much.

Ding ding ding. The entire article hangs on “imply”.

The question of where data is stored for an object is far less important than how to access data in a data structure. Like, the whole reason the data structure is designed the way it is, is to access it in particular ways.

Re: Classes vs. Data Structures

#19
post #9
post #3

The claim that "an object is a set of functions that operate on implied data elements" has a strange corollary because of how in modern OO languages like Java or C#, there is no syntax or popular naming convention to tell the difference between a data structure and an Object. For example, in Java, a LinkedList object is actually not a linked list, it is a set of functions that operate on an implied linked list. If th…

In a purely oop language, data structures exist as an implementation detail, but you can never access them directly (as in, bypassing the object interface). That's by design.

I get that in your application, you may want to keep a linked list behind its interface 90% of the time. However, considering your system as a whole, at some point you may want to take that linked list data and write it to a database, in which case the cleanest thing is to bypass the interface and extract the "data structure object" so to speak and deal with it in a database-related object, rather than encumbering your LinkedList object with database behaviors.

Re: Classes vs. Data Structures

#20
post #9
post #3

The claim that "an object is a set of functions that operate on implied data elements" has a strange corollary because of how in modern OO languages like Java or C#, there is no syntax or popular naming convention to tell the difference between a data structure and an Object. For example, in Java, a LinkedList object is actually not a linked list, it is a set of functions that operate on an implied linked list. If th…

In a purely oop language, data structures exist as an implementation detail, but you can never access them directly (as in, bypassing the object interface). That's by design.

In a purely oop language, data structures exist as an implementation detail, but you can never access them directly

In Smalltalk, you can have a TreeNode class and instantiate TreeNode instances. This is often the way that binary trees are implemented in Smalltalk. In that case, data structures exist as a design of interacting objects. In that case, you can molest them fairly directly using the object interface.

The same goes for Java and C#. Basically, you can design in such a way, that you can essentially have C or Fortran in any language, even a pure OO language like Smalltalk. The right way to do this in Smalltalk, is to use a Facade, which can be used to hide the guts of your data structure.

Post reply on HN