Not being good at reading other peoples mind, I’ll give my guess as to what Timothy was trying to suggest:
If you define your input as a map with keys such as: {:type :switched ; can be :switched :dual or :something :pos 54} You can make something like: (defmulti verify-pos-for :type) (defmethod verify-pos-for :switched [{:keys [pos]}] (or (= pos 0) (= pos 90))) (defmethod verify-pos-for :dual [m] (nil? (:pos m))) (defmethod verify-pos-for :default [{:keys [pos]}] (and (<= pos 90) (>= pos 0))) (defn verify-pos [{:keys [pos] :as m}] (or (nil? pos) (verify-pos-for m))) I have most certainly messed up your logic, but I do feel multi methods are kind of cool for this. Erik. > On 26. mai 2016, at 22.25, John Szakmeister <j...@szakmeister.net> wrote: > > On Thu, May 26, 2016 at 2:12 PM, Timothy Baldridge <tbaldri...@gmail.com> > wrote: >> I would suggest reviewing your data model a bit. One of the problems you >> are experiencing is that you are overloading the inputs to your function. >> And since they are overloaded you have to create a state machine of sorts to >> parse out if the data is valid. Another approach is to use namespaced keys >> in a map then dispatching on the contents of the map. This removes a lot of >> ambiguity in the code. > > Can you describe what you mean a little more? I think what you're > trying to say it that I should somehow separate switched axes from > variable axes, etc., despite that the same data is present in > both--just with slightly different semantics. > > The problem I see there is then I have to somehow figure out which > version to grab from the map. If I'm following correctly, you're > perhaps suggesting that I pull the type information higher into the > data model so I can use it to know which version to grab out of the > map? If that's the though process, it seems to me that it's > cluttering things rather than making it better--at least from my > ability to understand what the data model is actually saying. Having > the type grouped under the axis seems more coherent to me. > > I've probably misunderstood what you're saying though, so an example > of what you mean would be really helpful. I'm certain that you're > telling me something profound, but I'm just not parsing it out. :-) > >> Then you can use something like clojure.spec to validate your data: >> >> (s/def :pos.switch/value #{0 90}) >> (s/def :pos.slider/value (set (range 90))) > > Is there a way to cope with 0 and 90 actually being variable? What I > mean is that I don't know what the valid range is until I talk with > the back end equipment. So I can't say at compile time what the valid > range will be. I took that bit out of my example because I felt it > was making things too complex to be useful. > >> (s/def :switch/change (s/or :nil nil? >> :switch (s/keys :req [:pos.switch/value]) >> :slider (s/keys :req [:pos.slider/value]))) >> >> (s/valid? :switch/change {:pos.switch/value 42}) ; => false >> (s/valid? :switch/change {:pos.slider/value 42}) ; => true >> (s/conform :switch/change {:pos.switch/value 0}) ; => [:switch >> {:pos.switch/value 0}] >> (s/conform :switch/change nil) ; => >> [:nil nil] >> (s/conform :switch/change {:pos.slider/dual 0}) ; => >> :clojure.spec/invalid >> >> (s/exercise :switch/change) ; => Generates >> 10 example data sets >> >> And as you see from this example, you can use specs to dispatch, validate >> and even generate test data for your application. > > This is definitely interesting, though I thought spec was geared more > towards testing and less towards runtime validation. Well, now that I > say that, I guess what was said is that spec wasn't meant to be > enabled for everything all the time... you call out the bits you want > to do at runtime. It's probably still too new for me to use though, > especially since I'm currently using ClojureScript and clojure.spec > isn't available there yet. But definitely good to know about. Thank > you for the example! > > -John > > -- > 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. -- 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.