On 10 Feb, 12:23, Mark Carter <alt.mcar...@googlemail.com> wrote:
> Any ideas how I could implement
> this?

I've made a stab at it, but I'm not there yet.

(import (java.util ArrayList List))

(defn arraylist->list [aList]
  (let [size (. aList size)]
    (loop [accum nil
           index 0]
      (if (< index size)
        (recur (concat accum (list (. aList get index))) (inc index))
        accum))))

(defn collect-lambda [f]
  (let [alist (new ArrayList)
        emit (fn [new-member] (. alist add new-member))]
    (f emit)
    (arraylist->list alist)))


So far, so good. Now I can type

(collect-lambda (fn [emit]
                  (emit 1)
                  (emit 2)))

and get the result (1 2) - which is what we expect. There's a lot of
goo there, though, which would be nice to eliminate via a macro. I
really want to be able to say that emit is part of my syntax.

To try to solve this problem, I started out by defining unpartial -
which is kind of the opposite of partial:

(defmacro unpartial [x & body]
  `(fn [~x] ~...@body))

Seems an odd thing to do just now, but there's a logic to it. I can do
things like
((unpartial y (+ y 2)) 3)
and get the value 5 - again, this is what I expect.

I now try to define the macro that I'm really interested in:

(defmacro collect [& body]
  `(let [f# (unpartial emit ~...@body)]
    (collect-lambda f#)))

Admittedly, my understanding of composing macros is very shaky.

However, when I do
(collect
 (emit 1)
 (emit 2))
expecting the result (1 2), I instead get the error
java.lang.Exception: Can't use qualified name as parameter: user/emit
Grrr. How can I fix this?

I can get closer if I define collect as

(defmacro collect [emitter & body]
  `(let [f# (unpartial ~emitter ~...@body)]
    (collect-lambda f#)))

and use it by
(collect emit
 (emit 15)
 (emit 6))
to return (15 6). But I'd rather like to be able to omit the emit
parameter.

-- 
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