A map is... Whatever you put in it.
If you need that validation, you just validate the map? You can use established methods like Malli or Clojure Spec for this. If you need to use a record with a fixed schema, just use a record instead of map. In Clojure, you can use most of the map functions for records too.
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.
If you or anyone else remembers, I'd love to watch
The full video: [Time 0:49:06] https://www.youtube.com/watch?v=VSdnJDO-xdg
Transcript here: https://github.com/matthiasn/talk-transcripts/blob/master/Hi...
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.
False dichotomy. There are many options other than arrays. Clojure in particular is fond of hashmaps. You can have your response.headers without OOP.
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.
I really like Clojure, but I really don’t know what some of its fans think (also true of other lisps), like there is a healthy pollination of ideas between languages, lisps are not God’s language.
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/...
When you call a connection or connection pool object, you’re querying its current state. This is absolutely data.
Alan Perlis.
I was more thinking of the means to define your data "classes" (or whatever it is called on this context) though, rather than how it is passed around.