Is there a reliable implementation of letrec in clojure? Anybody using
it?
I have found a post from 2008, with an implementation which I don't
understand (and it's said to be slow), and which I don't know whether
to trust.(It's also supposed to be slow).
Thanks,
Razvan
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
--
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?
I don't quite understand why people are saying this. Anyway, It's not
enough for me.
Razvan
On Dec 14, 9:56 pm, David Nolen <dnolen.li...@gmail.com> wrote:
(button :id b1 :listener #(...)) => (let [b1 (new JButton)] ...)
(panel [:id p1] (button :id b1 ...) (button :id b2 ...)) => (let [p1
(new JPanel) b1 (button :id b1 ...) b2 (button :id b2 ...)] ...)
How to make the listener in b1 refer to b2?
Razvan
On Dec 14, 11:09 pm, David Nolen <dnolen.li...@gmail.com> wrote:
> Do you have a minimal example of what you are trying to do?
>
to implement letrec in a language with eager evaluation strategy some
kind of mutability is probably needed. Consider for example a self-
referential definition such as
(let [fibo (lazy-cat [1 1] (map + fibo (rest fibo)))]
(take 10 fibo))
This will not work since fibo is not in scope when the binding is
established. The standard solution would probably be something like
this
(let [fibo (promise)]
(deliver fibo (lazy-cat [1 1] (map + @fibo (rest @fibo))))
(take 10 @fibo))
Not as nice as the original version due to explicit dereferencing, but
workable. As an alternative one could use a macro to expand to this
and use a code walker (or symbol-macros) to automatically include the
@ calls. The following is untested, but should be close:
(defmacro letrec [binding & body]
(let [[var expr] binding
g-var (gensym)]
`(let [~g-var (promise)]
(symbol-macrolet [~var @~g-var]
(deliver ~g-var ~expr)
~@body))))
and voila
(letrec [fibo (lazy-cat [1 1] (map + fibo (rest fibo)))]
(take 10 fibo))
produces (1 1 2 3 5 8 13 21 34 55).
Best,
Nils
you'll probably have to rewrite your panel macro, so that it recognizes the button (and label, etc) macros ((= #'button (resolve &env sym)) in 1.3) and extracts the ids from the subform. Then you construct a global let which contains all the individual id namings. Then you group all '...' parts (from your standalone button example) in the body of the let.
Sincerely
Meikel
if you always follow the let structure you outlined the following might work. Untested, though. Note, that things work recursively with this approach.
(def ours? #{#'button #'label ...})
(defmacro panel
[{:keys [id]} & components]
(let [[bindings body]
(reduce (fn [[bindings body] component]
(if (and (seq? component)
(ours? (resolve &env (first component))))
(let [[_let local-bindings & local-body]
(macroexpand-1 component)]
[(into bindings local-bindings) (into body local-body)])
; Keep stuff we don't know.
[bindings (conj body component)]))
[[id `(JPanel.)] []]
components)]
`(let ~bindings
~@body
...
~id)))
Sincerely
Meikel