Difficulty finding correct way to type hint inside a deftype in Clojure 1.3 alpha4
I wanted to compare some similar code for 1.2 versus 1.3 alpha4, and I'm having trouble finding something I want that compiles with 1.3 alpha4. Here is one try, stored in a file knucleotide.clj. It is not the complete program, but it does exhibit the error I'm having trouble with, and is significantly shorter than what I started with. -- (ns knucleotide (:gen-class)) (set! *warn-on-reflection* true) (definterface IByteString (calculateHash [b offset])) (deftype ByteString [^{:unsynchronized-mutable true :tag bytes} byteArr ^{:unsynchronized-mutable true :tag int} hashVal ^{:unsynchronized-mutable true :tag int} cnt] IByteString (calculateHash [this b offset] (let [^bytes buf b len (int (alength byteArr))] (loop [i (int 0) offset (int offset) temp (int 0)] (if (== i len) ;; Following line is bad for Clojure 1.3alpha4 (set! hashVal temp) ;; Following line is OK, but not the behavior I want. ;; temp (let [b (int (aget buf offset)) bb (byte b)] (aset byteArr i bb) (recur (inc i) (inc offset) (+ (* temp 31) b (defn -main [& args] ) -- Then I try to do AOT compilation with this command, and get the errors shown below. It appears that I'm not doing type hinting correctly so that 1.3 knows that the local temp is an int. Can anyone see how to make something similar that works? % java -Dclojure.compile.path=. -cp /Users/andy/lein/clj-1.3.0-alpha4/ lib/clojure-1.3.0-alpha4.jar:. clojure.lang.Compile knucleotide Compiling knucleotide to . Exception in thread "main" java.lang.VerifyError: (class: knucleotide/ ByteString, method: calculateHash signature: (Ljava/lang/Object;Ljava/ lang/Object;)Ljava/lang/Object;) Expecting to find integer on stack, compiling:(knucleotide.clj:9) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3212) at clojure.lang.Compiler.compile1(Compiler.java:6712) at clojure.lang.Compiler.compile(Compiler.java:6773) at clojure.lang.RT.compile(RT.java:368) at clojure.lang.RT.load(RT.java:407) at clojure.lang.RT.load(RT.java:381) at clojure.core$load$fn__4389.invoke(core.clj:5306) at clojure.core$load.doInvoke(core.clj:5305) at clojure.lang.RestFn.invoke(RestFn.java:409) at clojure.core$load_one.invoke(core.clj:5130) at clojure.core$compile$fn__4394.invoke(core.clj:5317) at clojure.core$compile.invoke(core.clj:5316) at clojure.lang.Var.invoke(Var.java:401) at clojure.lang.Compile.main(Compile.java:56) Caused by: java.lang.VerifyError: (class: knucleotide/ByteString, method: calculateHash signature: (Ljava/lang/Object;Ljava/lang/ Object;)Ljava/lang/Object;) Expecting to find integer on stack at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) at knucleotide$fn__4.invoke(knucleotide.clj:9) at clojure.lang.AFn.applyToHelper(AFn.java:159) at clojure.lang.AFn.applyTo(AFn.java:151) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3207) ... 13 more Thanks, Andy -- 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
Re: Ridiculously massive slowdown when working with images
On Mon, Jan 31, 2011 at 08:00, Bill James wrote: > Benny Tsai wrote: >> Nice! That version runs in 6 milliseconds on my machine, fastest of >> all the code posted so far. One more idea: use 'unchecked-inc' >> instead of 'unchecked-add'. This takes it under 3 milliseconds in my >> tests. >> >> (defn java-like [^bytes cpu_array] >> (let [buffer-size (int buffer-size)] >> (loop [i (int 0)] >> (if (< i buffer-size) >> (let [i2 (unchecked-inc i) >> i3 (unchecked-inc i2) >> i4 (unchecked-inc i3) >> a (aget cpu_array i4)] >> (amove cpu_array i3 i4) >> (amove cpu_array i2 i3) >> (amove cpu_array i i2) >> (aset cpu_array i a) >> (recur (unchecked-inc i4))) >> > > Yes, that speeds it up considerably. If I can get Java server > installed > on my machine, I'll post some timings. What is this "java server" of which you speak. In JVMs I'm familiar with (Sun/Oracle, OpenJDK) it's just a matter of passing the option -server to java when starting it. // Ben -- 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
Re: Difficulty finding correct way to type hint inside a deftype in Clojure 1.3 alpha4
On Mon, Jan 31, 2011 at 3:10 AM, Andy Fingerhut wrote: > I wanted to compare some similar code for 1.2 versus 1.3 alpha4, and I'm > having trouble finding something I want that compiles with 1.3 alpha4. ... > (loop [i (int 0) > offset (int offset) > temp (int 0)] As far as I am aware, 1.3 doesn't do local primitives like this anymore. Just using the literal 0 for i and temp will make them primitive longs. As for offset, (long offset) might work. On the other hand, Java wants ints rather than longs for things like array indices and I don't know if auto-demotion will happen (in Java you'd get an error about not being allowed to do an implicit narrowing conversion, and you'd have to explicitly cast long to int). It may be worth a try, anyway. -- 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
how to print-dup records?
This is my attempt: (defn record? [a] (and (map? a) (not (instance? clojure.lang.APersistentMap a (defmethod print-dup clojure.lang.IPersistentMap [m, ^Writer w] (if (record? m) (do (.write w "#=(") (print-dup (class m) w) (.write w ". ") (doall (map #(do (print-dup % w) (.write w " ")) (map second (seq m (.write w ")") ) (do (#'clojure.core/print-meta m w) (.write w "#=(") (.write w (.getName (class m))) (.write w "/create ") (#'clojure.core/print-map m print-dup w) (.write w ")" ;;used from http://groups.google.com/group/clojure/browse_thread/thread/cb5246d07142a3dc?fwc=2&pli=1 (defn frm-save "Save a clojure form to file." [file form] (with-open [w (java.io.FileWriter. (if (instance? File file) file (File. file)))] (binding [*out* w *print-dup* true] (prn form (defn frm-load "Load a clojure form from file." [file] (with-open [r (java.io.PushbackReader. (java.io.FileReader. (if (instance? File file) file (File. file] (let [rec (read r)] rec))) However, it appears that the reader cant read classes For example (defrecord Foo [a]) (frm-save "/home/seth/Desktop/test" (Foo. 2)) (frm-load "/home/seth/Desktop/test") Another problem is that it saves it as the ns it is in, for example my- ns.Foo, and when you reload it it wont find my-ns.Foo unless you have required it. But, editing the test file to just output #=(#=foo. 2 3 ) and then loading that throws a class not found exception. Any general way to print-dup these records? -- 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
Re: Ridiculously massive slowdown when working with images
On Jan 31, 5:46 am, B Smith-Mannschott wrote: > > Yes, that speeds it up considerably. If I can get Java server > > installed > > on my machine, I'll post some timings. > > What is this "java server" of which you speak. In JVMs I'm familiar > with (Sun/Oracle, OpenJDK) it's just a matter of passing the option > -server to java when starting it. > > // Ben Usually Windoze doesn't have the Java server executable. You have to download the Java JDK. -- 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
Re: Ridiculously massive slowdown when working with images
(set! *warn-on-reflection* true) (def buffer-size 192) (def array (byte-array buffer-size)) (defmacro add [m n] `(unchecked-add (int ~m) (int ~n))) (defmacro uinc [m] `(unchecked-inc ~m)) (defmacro amove[a i j] `(aset ~a ~j (aget ~a ~i))) (defn java-like0 [^bytes cpu_array] (loop [i (int 0)] (if (< i (int buffer-size)) (let [b (byte (aget cpu_array i)) g (byte (aget cpu_array (unchecked-add i (int 1 r (byte (aget cpu_array (unchecked-add i (int 2 a (byte (aget cpu_array (unchecked-add i (int 3] (aset cpu_array i a) (aset cpu_array (unchecked-add i (int 1)) b) (aset cpu_array (unchecked-add i (int 2)) g) (aset cpu_array (unchecked-add i (int 3)) r) (recur (unchecked-add i (int 4))) ;;; Make buffer-size a local. (defn java-like1 [^bytes cpu_array] (let [buffer-size (int buffer-size)] (loop [i (int 0)] (if (< i (int buffer-size)) (let [b (byte (aget cpu_array i)) g (byte (aget cpu_array (unchecked-add i (int 1 r (byte (aget cpu_array (unchecked-add i (int 2 a (byte (aget cpu_array (unchecked-add i (int 3] (aset cpu_array i a) (aset cpu_array (unchecked-add i (int 1)) b) (aset cpu_array (unchecked-add i (int 2)) g) (aset cpu_array (unchecked-add i (int 3)) r) (recur (unchecked-add i (int 4 ;;; Move byte directly from array[i] to array[j]. ;;; Assign index values to local variables. ;;; Eliminate "byte" hint. (defn java-like2 [^bytes cpu_array] (let [buffer-size (int buffer-size)] (loop [i (int 0)] (if (< i buffer-size) (let [ i2 (add i 1) i3 (add i 2) i4 (add i 3) a (aget cpu_array i4) ] (amove cpu_array i3 i4) (amove cpu_array i2 i3) (amove cpu_array i i2) (aset cpu_array i a) (recur (add i 4))) ;;; Use unchecked-inc instead of unchecked-add. (defn java-like3 [^bytes cpu_array] (let [buffer-size (int buffer-size)] (loop [i (int 0)] (if (< i buffer-size) (let [ i2 (uinc i) i3 (uinc i2) i4 (uinc i3) a (aget cpu_array i4) ] (amove cpu_array i3 i4) (amove cpu_array i2 i3) (amove cpu_array i i2) (aset cpu_array i a) (recur (uinc i4))) (dotimes [i 4] (let [func-name (str "java-like" i) func (resolve (symbol func-name))] (println func-name) (dotimes [_ 7] (time (func array) I think it will be faster on my laptop, but for now here are the results on a rather old desktop. Clojure 1.2; Java 1.5.0_07 (server); Pentium 4 3.2GHz (2 cores) java-like0 "Elapsed time: 81.954298 msecs" "Elapsed time: 24.381966 msecs" "Elapsed time: 16.528463 msecs" "Elapsed time: 12.656007 msecs" "Elapsed time: 12.666522 msecs" "Elapsed time: 13.240584 msecs" "Elapsed time: 12.625828 msecs" java-like1 "Elapsed time: 56.773426 msecs" "Elapsed time: 19.099019 msecs" "Elapsed time: 16.669669 msecs" "Elapsed time: 6.325035 msecs" "Elapsed time: 6.400674 msecs" "Elapsed time: 6.374463 msecs" "Elapsed time: 6.266154 msecs" java-like2 "Elapsed time: 46.15 msecs" "Elapsed time: 11.840942 msecs" "Elapsed time: 10.842774 msecs" "Elapsed time: 5.56714 msecs" "Elapsed time: 5.655566 msecs" "Elapsed time: 5.611824 msecs" "Elapsed time: 5.509589 msecs" java-like3 "Elapsed time: 37.785107 msecs" "Elapsed time: 8.711968 msecs" "Elapsed time: 8.377959 msecs" "Elapsed time: 7.094104 msecs" "Elapsed time: 3.637105 msecs" "Elapsed time: 3.757499 msecs" "Elapsed time: 3.589582 msecs" -- 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
Re: Ridiculously massive slowdown when working with images
On Jan 31, 1:40 pm, Bill James wrote: > (set! *warn-on-reflection* true) > > (def buffer-size 192) > (def array (byte-array buffer-size)) > > (defmacro add [m n] `(unchecked-add (int ~m) (int ~n))) > (defmacro uinc [m] `(unchecked-inc ~m)) > (defmacro amove[a i j] `(aset ~a ~j (aget ~a ~i))) > > (defn java-like0 [^bytes cpu_array] > (loop [i (int 0)] > (if (< i (int buffer-size)) > (let [b (byte (aget cpu_array i)) > g (byte (aget cpu_array (unchecked-add i (int 1 > r (byte (aget cpu_array (unchecked-add i (int 2 > a (byte (aget cpu_array (unchecked-add i (int 3] > (aset cpu_array i a) > (aset cpu_array (unchecked-add i (int 1)) b) > (aset cpu_array (unchecked-add i (int 2)) g) > (aset cpu_array (unchecked-add i (int 3)) r) > (recur (unchecked-add i (int 4))) > > ;;; Make buffer-size a local. > (defn java-like1 [^bytes cpu_array] > (let [buffer-size (int buffer-size)] > (loop [i (int 0)] > (if (< i (int buffer-size)) > (let [b (byte (aget cpu_array i)) > g (byte (aget cpu_array (unchecked-add i (int 1 > r (byte (aget cpu_array (unchecked-add i (int 2 > a (byte (aget cpu_array (unchecked-add i (int 3] > (aset cpu_array i a) > (aset cpu_array (unchecked-add i (int 1)) b) > (aset cpu_array (unchecked-add i (int 2)) g) > (aset cpu_array (unchecked-add i (int 3)) r) > (recur (unchecked-add i (int 4 > > ;;; Move byte directly from array[i] to array[j]. > ;;; Assign index values to local variables. > ;;; Eliminate "byte" hint. > (defn java-like2 [^bytes cpu_array] > (let [buffer-size (int buffer-size)] > (loop [i (int 0)] > (if (< i buffer-size) > (let [ i2 (add i 1) > i3 (add i 2) > i4 (add i 3) > a (aget cpu_array i4) > ] > (amove cpu_array i3 i4) > (amove cpu_array i2 i3) > (amove cpu_array i i2) > (aset cpu_array i a) > (recur (add i 4))) > > ;;; Use unchecked-inc instead of unchecked-add. > (defn java-like3 [^bytes cpu_array] > (let [buffer-size (int buffer-size)] > (loop [i (int 0)] > (if (< i buffer-size) > (let [ i2 (uinc i) > i3 (uinc i2) > i4 (uinc i3) > a (aget cpu_array i4) > ] > (amove cpu_array i3 i4) > (amove cpu_array i2 i3) > (amove cpu_array i i2) > (aset cpu_array i a) > (recur (uinc i4))) > > (dotimes [i 4] > (let [func-name (str "java-like" i) > func (resolve (symbol func-name))] > (println func-name) > (dotimes [_ 7] > (time > (func array) > > I think it will be faster on my laptop, but for now here are > the results on a rather old desktop. > > Clojure 1.2; Java 1.5.0_07 (server); Pentium 4 3.2GHz (2 cores) > > java-like0 > "Elapsed time: 81.954298 msecs" > "Elapsed time: 24.381966 msecs" > "Elapsed time: 16.528463 msecs" > "Elapsed time: 12.656007 msecs" > "Elapsed time: 12.666522 msecs" > "Elapsed time: 13.240584 msecs" > "Elapsed time: 12.625828 msecs" > java-like1 > "Elapsed time: 56.773426 msecs" > "Elapsed time: 19.099019 msecs" > "Elapsed time: 16.669669 msecs" > "Elapsed time: 6.325035 msecs" > "Elapsed time: 6.400674 msecs" > "Elapsed time: 6.374463 msecs" > "Elapsed time: 6.266154 msecs" > java-like2 > "Elapsed time: 46.15 msecs" > "Elapsed time: 11.840942 msecs" > "Elapsed time: 10.842774 msecs" > "Elapsed time: 5.56714 msecs" > "Elapsed time: 5.655566 msecs" > "Elapsed time: 5.611824 msecs" > "Elapsed time: 5.509589 msecs" > java-like3 > "Elapsed time: 37.785107 msecs" > "Elapsed time: 8.711968 msecs" > "Elapsed time: 8.377959 msecs" > "Elapsed time: 7.094104 msecs" > "Elapsed time: 3.637105 msecs" > "Elapsed time: 3.757499 msecs" > "Elapsed time: 3.589582 msecs" Much faster on my laptop. Core2 Duo P8600 2.4GHz Clojure 1.2 java version "1.6.0" Java(TM) SE Runtime Environment (build 1.6.0-b105) Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode) java-like0 "Elapsed time: 40.007319 msecs" "Elapsed time: 11.8015 msecs" "Elapsed time: 10.262477 msecs" "Elapsed time: 10.363887 msecs" "Elapsed time: 10.242364 msecs" "Elapsed time: 10.163024 msecs" "Elapsed time: 10.518935 msecs" java-like1 "Elapsed time: 36.042849 msecs" "Elapsed time: 8.833804 msecs" "Elapsed time: 8.630427 msecs" "Elapsed time: 8.084827 msecs" "Elapsed time: 8.001296 msecs" "Elapsed time: 8.166401 msecs" "Elapsed time: 8.024763 msecs" java-like2 "Elapsed time: 24.401704 msecs" "Elapsed time: 4.934146 msecs" "Elapsed time: 4.368991 msecs" "Elapsed time: 4.326248 msecs" "Elapsed time: 4.326248 msecs" "Elapsed time: 4.328203 msecs" "Elapsed time: 4.288813 msecs" java-like3 "Elapsed time: 18.028548 msecs" "Elapsed time: 1.968686 msecs" "Elapsed time: 1.94494 msecs" "Elaps
Re: how to print-dup records?
We wrapped defrecord in a macro that created a factory function then had print-dup print a call to that function. https://github.com/david-mcneil/defrecord2 You can also find pprint in there too. On Jan 31, 11:26 am, Seth wrote: > This is my attempt: > > (defn record? [a] > (and (map? a) (not (instance? clojure.lang.APersistentMap a > > (defmethod print-dup clojure.lang.IPersistentMap [m, ^Writer w] > (if (record? m) > (do (.write w "#=(") > (print-dup (class m) w) (.write w ". ") > (doall (map #(do (print-dup % w) (.write w " ")) (map second (seq > m > (.write w ")") > ) > (do > (#'clojure.core/print-meta m w) > (.write w "#=(") > (.write w (.getName (class m))) > (.write w "/create ") > (#'clojure.core/print-map m print-dup w) > (.write w ")" > > ;;used > fromhttp://groups.google.com/group/clojure/browse_thread/thread/cb5246d07... > (defn frm-save > "Save a clojure form to file." > [file form] > (with-open [w (java.io.FileWriter. > (if (instance? File file) file (File. file)))] > (binding [*out* w *print-dup* true] (prn form > > (defn frm-load > "Load a clojure form from file." > [file] > (with-open [r (java.io.PushbackReader. > (java.io.FileReader. (if (instance? File file) file (File. > file] > (let [rec (read r)] > rec))) > > However, it appears that the reader cant read classes > For example > > (defrecord Foo [a]) > (frm-save "/home/seth/Desktop/test" (Foo. 2)) > (frm-load "/home/seth/Desktop/test") > > Another problem is that it saves it as the ns it is in, for example my- > ns.Foo, and when you reload it it wont find my-ns.Foo unless you have > required it. But, editing the test file to just output > > #=(#=foo. 2 3 ) > > and then loading that throws a class not found exception. > > Any general way to print-dup these records? -- 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
Defrecord and = docstring clarifications (regarding record equality)
I just ran into the following surprise: user> (defrecord P []) user.P user> (defrecord Q []) user.Q user> (= (P.) (Q.)) false user> (.equals (P.) (Q.)) true This is not a bug (but I do find it confusing -- I did not expect (P.) and (Q.) to collide as map keys): http://groups.google.com/group/clojure/browse_frm/thread/7ba5215d59f2f177 However, the docstring of defrecord says it "will define type-and- value-based equality and hashCode". Perhaps this could be clarified? Along the same lines, the docstring of = says "same as Java x.equals(y), except it ... compares numbers and collections in a type- independent manner". To me, this seems to imply the opposite of what actually happens with records. Thanks, Jason -- 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
Re: Defrecord and = docstring clarifications (regarding record equality)
On Mon, Jan 31, 2011 at 11:33 PM, Jason Wolfe wrote: > I just ran into the following surprise: > > user> (defrecord P []) > user.P > user> (defrecord Q []) > user.Q > user> (= (P.) (Q.)) > false > user> (.equals (P.) (Q.)) > true > > This is not a bug (but I do find it confusing -- I did not expect (P.) > and (Q.) to collide as map keys): > http://groups.google.com/group/clojure/browse_frm/thread/7ba5215d59f2f177 > > However, the docstring of defrecord says it "will define type-and- > value-based equality and hashCode". Perhaps this could be > clarified? It seems clear enough to me that type is a factor in equality. The real bug here is that .equals returns true in this case. > Along the same lines, the docstring of = says "same as Java > x.equals(y), except it ... compares numbers and collections in a type- > independent manner". To me, this seems to imply the opposite of what > actually happens with records. There is where clarification is needed, namely that records are not "collections" for this purpose. Alternatively, records could have an enforced mapping {:type TheRecordsClass} that does not actually take up storage space, but appears when records are queried and automatically imposes the desired equality semantics if records were simply treated as maps -- other than that a plain map with the same type key-value pair could now compare equal to the record. (Would that be a bad thing though?) -- 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
Re: Ridiculously massive slowdown when working with images
On Jan 31, 1:33 pm, Bill James wrote: > On Jan 31, 5:46 am, B Smith-Mannschott wrote: > > > > Yes, that speeds it up considerably. If I can get Java server > > > installed > > > on my machine, I'll post some timings. > > > What is this "java server" of which you speak. In JVMs I'm familiar > > with (Sun/Oracle, OpenJDK) it's just a matter of passing the option > > -server to java when starting it. > > > // Ben > > Usually Windoze doesn't have the Java server executable. > You have to download the Java JDK. More precisely, the missing file is C:\Program Files\Java\jre6\bin\server\jvm.dll -- 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
Re: How to disallow unlisted optional argument keys?
You win sir. That is the most beautiful way. sincerely, --Robert McIntyre On Sun, Jan 30, 2011 at 7:59 PM, Bill James wrote: > Alexander Yakushev wrote: >> Why not use a constraint? It looks much cleaner. >> >> (defn hello [& {:keys [a b] :as input}] >> {:pre [(= (set (keys input)) #{:a :b})]} >> "hello") >> >> You can learn more about constraints here: >> http://vimeo.com/channels/fulldisclojure#8399758 > > > {:pre [(clojure.set/subset? (set (keys input)) #{:a :b})]} > > -- > 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 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