4 ms·
Could someone explain what the paragraphs under "Map specs should be of keysets only" are getting at? I'm trying to map it onto my experience with Clojure and
by jraines 10y ago
Could someone explain what the paragraphs under "Map specs should be of keysets only" are getting at?
I'm trying to map it onto my experience with Clojure and plumatic/schema, but nothing is clicking.
- xmlblog 10y agoIf you have a function that accepts a map of a certain shape and want to write a specification for that map, you should only be specifying the required/optional keys in that spec. You should not be forced to also specify the values for those keys. When you are (as in Schema) then you wind up with redundancies when you have a slightly different map structure that also includes one or more (but not all) of the same keys with the same semantic meaning.
- puredanger 10y agoGenerally in most of the existing libs like Schema you specify that a "person entity" is a map that has particular attributes that have particular properties and a "company entity" is a map that has other attributes (some of which might overlap). In spec, you specify that a first-name attribute is a string and an email attribute matches some regex. Those are specifications about the attributes and can be used across many entity types. A person entity spec is then defined as a map that contains a set of required or optional attributes. A company entity spec is a different map with different attributes, some of which might be shared with a person (like email address). This is in many ways a shift in perspective, allowing you to start defining and reusing attribute specs to a much greater degree. The use of structural systems with mathematical properties (regular expressions for sequence structure and sets for map keys) turns out to have many useful effects in computing error sets, etc.
- zcp 10y agothanks for this excellent explanation; this provides just about all the justification I need. looking forward to toying around with this.
- greghendershott 10y agoThe division -- between predicates for attribute values vs. specs for maps/seqs -- is interesting because AFAICT Datomic schemas ~= the former, while leaving the latter to your app? (Although I guess :db.cardinality/many straddles that line.)
- gw 10y agoHere's my understanding... In Schema, you would represent a map's spec like this: (def my-map {:a s/Str :b s/Int}) In spec, you'd do it like this: (s/def ::a string?) (s/def ::b integer?) (s/def ::my-map (s/keys :req [::a ::b])) In other words, the values are specified separately from the keys. This promotes reuse of specs, which is important especially as they get more complex.
- patricius 10y agoI think that (spec/keys ...) specifies the possible keys of a map, i.e., required and optional keys. The specification of what values these keys take are external to the specification of which keys go into a map. So somewhere else you will have to specify the valid value(s) for some (namespaced) key.
- virmundi 10y agoAnd that's the problem. With Schema you can compound key specs and values. This mashes the code self documenting. With Specs you have to point to another spec. Ask the way down the complex tree.