Sometimes I'm just too eager; I changed the macro so that the first argument to the function is the current record (i.e. "this").
user=> (definvokerecord (fn [this & args] (apply + args)) ATEST []) user.ATEST user=> (def a (ATEST.)) #'user/a user=> (a 1 2 3) 6 user=> (a 1 2 3 4 5) 15 Jonathan On Mon, Jun 20, 2011 at 3:28 PM, Jonathan Fischer Friberg < odysso...@gmail.com> wrote: > 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