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

Reply via email to