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

Reply via email to