These are good comments that give me things to think about. I'm grateful. * The pattern concerned me because (1) it was just the first thing I came up with, so not sure there wasn't a better way staring me in the face (2) I didn't see any clearly better alternatives, so not sure whether I just don't know enough Clojure (3) it intuitively felt heavyweight with at least four "complected" language features. * Understood about polymorphism. In my real app, I have a lot of it, but I thought I would use protocols & records even when I don't have polymorphism just for uniformity of style: one way to express my "testable types." * You've pointed out an overlap between two different ways to specify structure: (A) requiring keys via records and (B) requiring keys using specs over ordinary maps. Starting with records, I sensed that some of my specs were actually vapid, and now you've told me why. * I think experimenting with mere (collections of) functions over mere maps with structure enforced by specs is a good idea. I'll try it and "weigh" it against this alternative.
On Monday, April 10, 2017 at 1:13:49 PM UTC-7, Didier wrote: > > I think this pattern is fine. > > What specifically about it annoys you? > > You could do it without records, but then you wouldn't be creating a type. > Do you really need a type? > > The advantage of types in Clojure are that they let you do polymorphic > dispatch of them. So they are useful if you have one function which you > want to reuse for many types. > > In your case, I'm not seeing other records implementing the protocol. So > it doesn't seem you need polymorphic dispatch on type. So maybe you can > drop the protocol. > > Records are useful if you need a map with guaranteed keys. Spec makes this > feature less useful, because you can now spec a map and test that it always > has the right keys when used. If you have a record, a fn that works over > that record just needs to check the argument has the type of record, and it > knows the keys exist. If you have a map instead, the fn would need to check > the keys exist. > > Records don't support unions, all keys must exist. In your case, you want > unions, a map with keys x,y or z. So if you use a record, some keys will > always have nil value. So, again, you might be better served by a map. > > Recap. Protocols if you want a common interface accross multiple types. > Records if you want to create a map with guaranteed keys, which will > identify itself as a named java type. > > Your spec can't really be made shorter, since they need custom gens. > > If I was you, I'd experiment with functions over maps. One thing to > consider is that specs are structural types, not nominal. So if you spec a > map, it describes its structure. A function says I take a structure of that > shape, if you give me anything that conforms, I can successfully do my job. > The shape itself has no known runtime name. > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.