plumatic / plumbing

Prismatic's Clojure(Script) utility belt

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature suggestion: defs

gfredericks opened this issue · comments

Any interest in a destructuring-driven macro for defining multiple things at once?

E.g.,

(defs [a b & more] (range))

a ;; => 0
b ;; => 1
more ;; => (2 3 4 ...)

I think this has been implemented before in other places, and could probably be done in a generic way that doesn't require reimplementing destructuring or anything nasty like that.

Would be happy to code it up myselfs too.

I'm on the fence about this one.

In particular, I see the utility, but also
feel like preserving a little ceremony around each global def can help both humans or tooling understand a codebase, and this may muddy those waters a bit.

Can you please share a real use case where you've wanted this, and your thoughts on the above? Thanks :)

My pattern with schema-bijections has been this sort of thing repeated a lot:

(def MySchema
  {...})

(let [[json-schema to-json from-json] (jsonify-schema MySchema)]
  (def MySchemaJSON json-schema)
  (def MySchema<-JSON from-json)
  (def MySchema->JSON to-json))

I'd like to think there is a better way to generalize this that doesn't involve needing 4 vars per schema. One half-messy idea is a single function memoized over the identity of the schema (so it doesn't have to do the schema bijecting all the time). :-/

Thanks! From what I see on the surface, I think I might try a protocol and record (or similar), so I could use a single var to def a Bijection instance, and then call from-json, etc on that. Would that be a reasonable approach here, or are there other concerns that make separate vars more desirable?

I'm still uncertain about a good way of managing these things long-term, because there are use cases for having more than one bijection for a given schema and I don't know what the cleanest way to support that is. It probably shouldn't be having N*3 vars though, so I'm happy to close this.

For interested observers from The Future I think this impl is probably good:

(defmacro defs
  [names-form expr]
  (let [all-names (->> names-form (tree-seq coll? seq) (filter symbol?))]
    `(let [~names-form ~expr]
      ~@(for [name all-names] `(def ~name ~name)))))

For more than one bijection, could you use a different var to def each Bijection protocol instance? If that's not clear, I'm happy to elaborate on what I mean.

I'm open to adding if there's a good use case that's doesn't have an idiomatic solution without it, so just trying to suss this out. Thanks for talking things through with me!