6 ms·
Question: What's the difference between nested oop objects (composition over inheiritance) vs maps of nested structures?
by PreachSoup 3y ago
Question: What's the difference between nested oop objects (composition over inheiritance) vs maps of nested structures?
- xmcqdpt2 3y agoTo paraphrase a well known saying, objects are the poor person's nested maps and vis versa.
- gleenn 3y agoRich Hickey has a great talk about how Objects are data structures with unique interfaces that are unnecessary complexity. He showed and example of a web server with a web request object with request headers etc etc. Doing simple things like collecting information out of that nested object structure is bespoke and harder than it should be for no real gain. If everything is a map or list or set, it becomes completely trivial to extract and manipulate data from a structure. It's a subtle difference at first but when everything is like that it makes your system far simpler. Unfortunately I can't remember exactly where the part of this talk is.
- bavell 3y ago> Unfortunately I can't remember exactly where the part of this talk is. If you or anyone else remembers, I'd love to watch
- deleted 3y ago[deleted]
- sharms 3y agoHere is this specific part cut out from the larger talk "Clojure made simple": https://www.youtube.com/watch?v=aSEQfqNYNAc https://www.youtube.com/watch?v=aSEQfqNYNAc
- janosos 3y agohttps://youtu.be/aSEQfqNYNAc https://youtu.be/aSEQfqNYNAc The full video: [Time 0:49:06] https://www.youtube.com/watch?v=VSdnJDO-xdg https://www.youtube.com/watch?v=VSdnJDO-xdg Transcript here: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ClojureMadeSimple.md https://github.com/matthiasn/talk-transcripts/blob/master/Hi...
- deleted 3y ago[deleted]
- tyre 3y ago“No real gain” I don’t agree with this. iirc Rack ultimately uses and array to represent HTTP responses. It has three members: the status code, the headers, and the response body. If you’re shipping a new change, is it easier to mistake response[0] or response.headers? This is a trivial example, but the general class (ha) of trade-off is amplified with more complex objects. I love clojure and lisp but the blindness behind a statement like “no real gain” has always kneecapped adoption.
- augustl 3y agoIn Clojure, response.headers is still data :) You just use the built-in ways of reading named keys, such as (:headers response) or (get headers :response).
- augustl 3y agoErrata: (get response :headers)
- outworlder 3y ago> If you’re shipping a new change, is it easier to mistake response[0] or response.headers False dichotomy. There are many options other than arrays. Clojure in particular is fond of hashmaps. You can have your response.headers without OOP.
- greg7mdp 3y agoThis? https://www.youtube.com/watch?v=aSEQfqNYNAc https://www.youtube.com/watch?v=aSEQfqNYNAc
- gleenn 3y agoYes, this hit home so hard. All objects are bespoke mini languages that add little to no value and simultaneously make it hard to remember and hard to use. Just use maps!
- javajosh 3y agoConstraints always have value. Without constraints programmers are confronted with the naked complexity of mapping between the set of all possible states of N bits which is (2^N)!.
- gsinclair 3y agoMore constraints don’t necessarily have more value, though. Each constraint needs to be thought through, not just have its value assumed.
- oblio 3y agoAn object is a schema, though. A map is... Whatever you put in it.
- deleted 3y ago[deleted]
- xpe 3y agoThis comment is talking specifically in the context of Clojure. In the Clojure culture (so to speak) maps may also have a schema, as used by various schema checking tools, which are richer than runtime type checks. (Not the same as database schema) Nit: I would not say that a JVM object is a schema, because there’s more to it. Rich is well known for saying that the idea of an object complects two things: (1) a record-like (struct) data structure with the (2) code to manipulate it. Sometimes it’s even more complected because in some languages classes can make assumptions about state across all objects and threading.
- kaba0 3y agoI think there is a need for objects. An active connection, talking to the GPU, etc are not data -- identity is essential for their operation. OOP is probably the best way to model such,.. well objects, allowing them a private, encapsulated state, and making it only modifiable, or even viewable through a well-defined public interface that enforces all its invariants.
- gleenn 3y agoClojure uses objects for connections and things, but POJOs are harmful IMHO because it makes manipulation and collecting data a bespoke task every time. Every time you change the data, you have to change a class to represent the JSON and the ORM class and .... this is all just data
- kaba0 3y agoWell, that’s what Java records are for. As for having to change the type description, that’s more of a static typing discussion, though it can be generated — having a single source of truth and generating others is imo the best approach.
- ledauphin 3y agoJava records weren't even a gleam in the eye of James Gosling when Clojure was solving these problems at its inception.
- lmm 3y agoStandard ML had records since the '70s. Both Clojure and Java would benefit from taking more from what came before, though Java at least had the excuse of being designed for low-powered set-top boxes.
- filoeleven 3y agoAccording to the link below, ML records are mostly handled by hash-maps in Clojure, except that there’s no canonical key/val order or strict typing by default. ML record: {first = "John", last = "Doe", age = 150, balance = 0.12} Clojure hash-map: {:first "John", :last "Doe", :age 150, :balance 0.12} Destructuring a record in an ML function: fun full_name{first:string,last:string,age:int,balance:real}:string = first ^ " " ^ last (It’s unclear from the example whether or not all of the destructured values are required in the function signature. I hope they are not, but I left them in since I don’t know. The caret positioning raises further questions.) Destructuring a map in a Clojure function: (defn full-name [{:keys [first last]}] (str first “ “ last)) I don’t know if I’m missing something that ML offers with its records aside from more strict typing, which you can also have in Clojure when it’s useful. In both cases, it looks like it’s applied at the function declaration and not the record declaration. https://www.cs.cornell.edu/courses/cs312/2008sp/recitations/rec02.html https://www.cs.cornell.edu/courses/cs312/2008sp/recitations/...
- PreachSoup 3y agoMost of the time, the class name is used just as a nominal type identifier. That's what we do at least
- deleted 3y ago[deleted]
- blatant303 3y ago"It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures." Alan Perlis.