Maybe I should add how to actually use it: the first argument is a function which will be called when the record is called. the rest is simply the arguments to defrecord, as usual.
Jonathan On Mon, Jun 20, 2011 at 3:23 PM, Jonathan Fischer Friberg < odysso...@gmail.com> wrote: > Here is said macro: > https://gist.github.c > <https://gist.github.com/1035590>om/1035590<https://gist.github.com/1035590> > > user=> (definvokerecord (fn [& args] (apply + args)) ATEST []) > user.ATEST > user=> (ATEST.) > #:user.ATEST{} > user=> (def a (ATEST.)) > #'user/a > user=> (a 1 2 3) > 6 > user=> (a 1 2 3 4 5) > 15 > > I haven't tested it with other protocols, but it should work. ;) > > Jonathan > > > On Sun, Jun 19, 2011 at 3:58 PM, Ken Wesson <kwess...@gmail.com> wrote: > >> On Sat, Jun 18, 2011 at 10:47 AM, David Nolen <dnolen.li...@gmail.com> >> wrote: >> > On Sat, Jun 18, 2011 at 4:44 AM, Sam Aaron <samaa...@gmail.com> wrote: >> >> >> >> Is it possible to use this approach to create a callable record which >> can >> >> take a variable number of arguments? >> >> >> >> I can't get the following to work: >> >> >> >> (defrecord Foo [a] >> >> clojure.lang.IFn >> >> (invoke [this & args] (println (str a args)))) >> >> >> >> (def yo (Foo. "sam")) >> >> >> >> (yo 1 2 3 4) ;=> >> >> >> sc-one.Foo.invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; >> >> [Thrown class java.lang.AbstractMethodError] >> >> >> >> Sam >> > >> > defrecord/type methods don't support rest args. >> >> Not without some hoop jumping, anyway, but ... >> >> => (defn my-var-arg-fn [& args] (apply str args)) >> #'user/my-var-arg-fn >> => (defrecord Foo [] >> clojure.lang.IFn >> (invoke [this] (my-var-arg-fn)) >> (invoke [this o1] (my-var-arg-fn o1)) >> (invoke [this o1 o2] (my-var-arg-fn o1 o2)) >> (applyTo [this, arglist] >> (clojure.lang.AFn/applyToHelper my-var-arg-fn arglist))) >> user.Foo >> => ((Foo.) "hello" "world") >> "helloworld" >> => (apply (Foo.) "hello" "world") >> "helloworld" >> >> To really make it work you unfortunately need about 18 more (invoke >> ...) methods, each with one additional parameter, which is annoying. A >> macro could be written to simplify the job. That's for making the >> records themselves be functions that accept varargs. To make a random >> method do so you'd need to overload it, similarly to the multiple >> versions of invoke above, for each arity, or better yet you'd write a >> helper function: >> >> (defrecord Foo >> SomeProto >> (my-meth-impl [this [& args]] ...)) >> >> (defn my-meth [some-foo & args] >> (my-meth-impl some-foo args)) >> >> which just passes the arg seq in as a single, second seq argument to >> the record's actual method, which destructures its second argument... >> >> -- >> Protege: What is this seething mass of parentheses?! >> Master: Your father's Lisp REPL. This is the language of a true >> hacker. Not as clumsy or random as C++; a language for a more >> civilized age. >> >> -- >> 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