Hi Dave, Somewhat related: I've been looking at Prismatic's Schema [1] along with ordinary pre and post conditions to apply stricter runtime controls on suites of functions that take and return maps:
user=> (require '[schema.core :as sc]) nil user=> (def FooIn "FooIn must have a string at :bar, a number at :baz, and no other keys" { :bar sc/Str :baz sc/Num }) #'user/FooIn user=> (def FooOut "FooOut must have :baz and :qux, but can have any other keys/values" { :baz sc/Num :qux sc/Str sc/Any sc/Any }) #'user/FooOut user=> (defn foo #_=> "Input map must match FooIn, returns FooOut" #_=> [ {:keys [bar baz] :as m}] #_=> {:pre [(sc/validate FooIn m)] #_=> :post [(sc/validate FooOut %)]} #_=> (assoc m :qux "zoop")) #'user/foo user=> (doc foo) ------------------------- user/foo ([{:keys [bar baz], :as m}]) Input map must match FooIn, returns FooOut nil user=> (doc FooIn) ------------------------- user/FooIn FooIn must have a string at :bar, a number at :baz, and no other keys nil user=> (doc FooOut) ------------------------- user/FooOut FooOut must have :baz and :qux, but can have any other keys/values nil user=> (foo { :bar "1" :baz 2 }) {:qux "zoop", :baz 2, :bar "1"} user=> (foo { :bar 1 :baz 2 }) ExceptionInfo Value does not match schema: {:bar (not (instance? java.lang.String 1))} schema.core/validate (core.clj:165) user=> (foo { :bar "1" :baz 2 :beez 3 }) ExceptionInfo Value does not match schema: {:beez disallowed-key} schema.core/validate (core.clj:165) It's not compile time, requires multiple declarations, and imposes some runtime cost, but in a repl workflow can provide guidance and immediate feedback. Prismatic has gone significantly further in the keyword functions space with Plumbing and Graph. [2] HTH, Jonah 1. https://github.com/Prismatic/schema 2. https://github.com/Prismatic/plumbing On Fri, Aug 15, 2014 at 7:47 AM, Dave Tenny <dave.te...@gmail.com> wrote: > This is getting old. Any suggestions or plans to fix it? Do I need to > use some other common declaration style for functions? > > ; CIDER 0.5.0 (Clojure 1.6.0, nREPL 0.2.3) > user> (defn foo [& {:keys [bar]}] bar) > #'user/foo > user> (foo :baz 1) > nil > > In my opinion the compilation of the call to foo should have complained > about :baz not matching a known parameter. > > Failure to do this leads to lots of extra debugging because someone had a > typo in a keyword name, > e.g. ":Name" instead of ":name" or :product instead of :project, or > whatever. > > This is probably the leading cause of unexpected program operation in > clojure for me. > > > -- > 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.