EDT interaction

2009-06-13 Thread Wrexsoul

Now I'm working on some Swing code and came up with these, which are
obviously going to be useful:

(defmacro do-on-edt [ body]
  `(SwingUtilities/invokeLater #(do ~...@body)))

(defmacro get-on-edt [ body]
  `(let [ret# (atom nil)]
 (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)]))
 (loop []
   (let [r# @ret#]
 (if r#
   (first r#)
   (recur))

(defmacro future-on-edt [ body]
  `(future (get-on-edt ~...@body)))

The do-on-edt macro executes its body on the EDT and returns nil.

The get-on-edt macro does similarly, but returns whatever the body
returns. It blocks until the body has returned, though, which you may
not want, though since it executes on the EDT it should execute fast.

The future-on-edt macro avoids this blocking behavior. It behaves as
if you scheduled its body to run as a future on the EDT instead of on
whatever thread(s) futures usually run on. In actual fact, the future
it returns is executing the blocking get-on-edt. :)

Action listener code can assume it will run on the edt, but plenty of
other things do not; notably, REPL expressions do not, as well as
anything explicitly launched into another thread and anything executed
as a result of load-file or via a main class.

This code, which I offer to the public domain, also furnishes some
simple examples of macro design, as well as of the use of an atom to
move information between threads, plus a recurrence of the one-cell-
vector idiom for having both nil and meta-nil, distinguishing not-
set-yet from actually-returned-nil. This also showed up in super-lazy-
seq where ultimately one var could end up holding either a boxed
return value or *two* out-of-band values, nil and :skip. (Another
trick for returning out-of-band values is to return a two-element
vector with a value in one cell and an accompanying bit of meta-data
in the other, for example [item found] distinguishing [nil false] from
[nil true]. Other lisps admit of the same trick, using a cons cell
(item . found) for instance, or using nil vs. (item . nil) or any-atom
vs. (item . nil). Don't know if anyone else here is familiar with
dotted-pair notation though, except clojure's author.)
--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---



Re: EDT interaction

2009-06-13 Thread Laurent PETIT

Thank you so much for giving us your light, master of the dotted pair
notation ;-)

2009/6/13 Wrexsoul d2387...@bsnow.net:

 Now I'm working on some Swing code and came up with these, which are
 obviously going to be useful:

 (defmacro do-on-edt [ body]
  `(SwingUtilities/invokeLater #(do ~...@body)))

 (defmacro get-on-edt [ body]
  `(let [ret# (atom nil)]
     (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)]))
     (loop []
       (let [r# @ret#]
         (if r#
           (first r#)
           (recur))

 (defmacro future-on-edt [ body]
  `(future (get-on-edt ~...@body)))

 The do-on-edt macro executes its body on the EDT and returns nil.

 The get-on-edt macro does similarly, but returns whatever the body
 returns. It blocks until the body has returned, though, which you may
 not want, though since it executes on the EDT it should execute fast.

 The future-on-edt macro avoids this blocking behavior. It behaves as
 if you scheduled its body to run as a future on the EDT instead of on
 whatever thread(s) futures usually run on. In actual fact, the future
 it returns is executing the blocking get-on-edt. :)

 Action listener code can assume it will run on the edt, but plenty of
 other things do not; notably, REPL expressions do not, as well as
 anything explicitly launched into another thread and anything executed
 as a result of load-file or via a main class.

 This code, which I offer to the public domain, also furnishes some
 simple examples of macro design, as well as of the use of an atom to
 move information between threads, plus a recurrence of the one-cell-
 vector idiom for having both nil and meta-nil, distinguishing not-
 set-yet from actually-returned-nil. This also showed up in super-lazy-
 seq where ultimately one var could end up holding either a boxed
 return value or *two* out-of-band values, nil and :skip. (Another
 trick for returning out-of-band values is to return a two-element
 vector with a value in one cell and an accompanying bit of meta-data
 in the other, for example [item found] distinguishing [nil false] from
 [nil true]. Other lisps admit of the same trick, using a cons cell
 (item . found) for instance, or using nil vs. (item . nil) or any-atom
 vs. (item . nil). Don't know if anyone else here is familiar with
 dotted-pair notation though, except clojure's author.)
 


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



Re: EDT interaction

2009-06-13 Thread Meikel Brandmeyer

Hi,

Am 13.06.2009 um 23:02 schrieb Wrexsoul:


Now I'm working on some Swing code and came up with these, which are
obviously going to be useful:


And which are partly in clojure.contrib.swing-utils :)


(defmacro do-on-edt [ body]
 `(SwingUtilities/invokeLater #(do ~...@body)))

(defmacro get-on-edt [ body]
 `(let [ret# (atom nil)]
(SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)]))
(loop []
  (let [r# @ret#]
(if r#
  (first r#)
  (recur))


And while we are talking about macro design and
transferring return values between threads:

(defn get-on-edt*
  [thunk]
  (let [ret (atom nil)]
(SwingUtitilities/invokeAndWait #(reset! ret (thunk)))
@ret))

(defmacro get-on-edt
  [ body]
  `(get-on-edt* (fn [] ~body)))


Don't know if anyone else here is familiar with
dotted-pair notation though, except clojure's author.


And please tune down the rhetoric. This is not the
level on which things are discussed in this group.

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: EDT interaction

2009-06-13 Thread Kevin Downey

On Sat, Jun 13, 2009 at 2:02 PM, Wrexsould2387...@bsnow.net wrote:

 Now I'm working on some Swing code and came up with these, which are
 obviously going to be useful:

 (defmacro do-on-edt [ body]
  `(SwingUtilities/invokeLater #(do ~...@body)))

 (defmacro get-on-edt [ body]
  `(let [ret# (atom nil)]
     (SwingUtilities/invokeLater #(reset! ret# [(do ~...@body)]))
     (loop []
       (let [r# @ret#]
         (if r#
           (first r#)
           (recur))

 (defmacro future-on-edt [ body]
  `(future (get-on-edt ~...@body)))

 The do-on-edt macro executes its body on the EDT and returns nil.

 The get-on-edt macro does similarly, but returns whatever the body
 returns. It blocks until the body has returned, though, which you may
 not want, though since it executes on the EDT it should execute fast.

 The future-on-edt macro avoids this blocking behavior. It behaves as
 if you scheduled its body to run as a future on the EDT instead of on
 whatever thread(s) futures usually run on. In actual fact, the future
 it returns is executing the blocking get-on-edt. :)

 Action listener code can assume it will run on the edt, but plenty of
 other things do not; notably, REPL expressions do not, as well as
 anything explicitly launched into another thread and anything executed
 as a result of load-file or via a main class.

 This code, which I offer to the public domain, also furnishes some
 simple examples of macro design, as well as of the use of an atom to
 move information between threads, plus a recurrence of the one-cell-
 vector idiom for having both nil and meta-nil, distinguishing not-
 set-yet from actually-returned-nil. This also showed up in super-lazy-
 seq where ultimately one var could end up holding either a boxed
 return value or *two* out-of-band values, nil and :skip. (Another
 trick for returning out-of-band values is to return a two-element
 vector with a value in one cell and an accompanying bit of meta-data
 in the other, for example [item found] distinguishing [nil false] from
 [nil true]. Other lisps admit of the same trick, using a cons cell
 (item . found) for instance, or using nil vs. (item . nil) or any-atom
 vs. (item . nil). Don't know if anyone else here is familiar with
 dotted-pair notation though, except clojure's author.)
 


get-on-edt uses a busy loop, which is icky. I would use a
blockingqueue. if you are not constrained by 1.0 compatibility
promise/deliver just hit the new git repo. a promise is a new kind of
reference type that provides a blocking deref.

http://github.com/richhickey/clojure/blob/1a0e23d0e78ef3d3a3a6267a68adcfc414d3fb56/src/clj/clojure/core.clj#L4152


-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

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



Re: EDT interaction

2009-06-13 Thread Meikel Brandmeyer

Hi,

Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer:


(defmacro get-on-edt
 [ body]
 `(get-on-edt* (fn [] ~body)))


Of course ~...@body instead of ~body...

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: EDT interaction

2009-06-13 Thread Kevin Downey

On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote:
 Hi,

 Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer:

 (defmacro get-on-edt
  [ body]
  `(get-on-edt* (fn [] ~body)))

 Of course ~...@body instead of ~body...

 Sincerely
 Meikel



I know you (Meikel) already fixed it, but I guess it is a good idea to
explain that have a macro expand to a #() form is a bad idea.
the original do-on-edt macro did expand to a #() form, which means if
you passed in another #() form you would end up with nested #() forms,
which causes an exception.

-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

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



Re: EDT interaction

2009-06-13 Thread Aaron Cohen

Isn't this a case of wrapping a Java API needlessly?

What's so bad about: (SwingUtilities/invokeLater my-func) ?
-- Aaron



On Sat, Jun 13, 2009 at 5:59 PM, Kevin Downeyredc...@gmail.com wrote:

 On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote:
 Hi,

 Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer:

 (defmacro get-on-edt
  [ body]
  `(get-on-edt* (fn [] ~body)))

 Of course ~...@body instead of ~body...

 Sincerely
 Meikel



 I know you (Meikel) already fixed it, but I guess it is a good idea to
 explain that have a macro expand to a #() form is a bad idea.
 the original do-on-edt macro did expand to a #() form, which means if
 you passed in another #() form you would end up with nested #() forms,
 which causes an exception.

 --
 And what is good, Phaedrus,
 And what is not good—
 Need we ask anyone to tell us these things?

 


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



Re: EDT interaction

2009-06-13 Thread Kevin Downey

it depends how often you are pushing stuff onto the EDT. I have a
similar macro called EDT so I can do stuff like (EDT (.setText foo
bar)) alternatively I would need to type (SwingUtilities/invokeLater
#(.setText foo bar)) or even (SwingUtilities/invokeLater (fn []
(.setText foo bar)))

On Sat, Jun 13, 2009 at 5:23 PM, Aaron Cohenremled...@gmail.com wrote:

 Isn't this a case of wrapping a Java API needlessly?

 What's so bad about: (SwingUtilities/invokeLater my-func) ?
 -- Aaron



 On Sat, Jun 13, 2009 at 5:59 PM, Kevin Downeyredc...@gmail.com wrote:

 On Sat, Jun 13, 2009 at 2:55 PM, Meikel Brandmeyerm...@kotka.de wrote:
 Hi,

 Am 13.06.2009 um 23:29 schrieb Meikel Brandmeyer:

 (defmacro get-on-edt
  [ body]
  `(get-on-edt* (fn [] ~body)))

 Of course ~...@body instead of ~body...

 Sincerely
 Meikel



 I know you (Meikel) already fixed it, but I guess it is a good idea to
 explain that have a macro expand to a #() form is a bad idea.
 the original do-on-edt macro did expand to a #() form, which means if
 you passed in another #() form you would end up with nested #() forms,
 which causes an exception.

 --
 And what is good, Phaedrus,
 And what is not good—
 Need we ask anyone to tell us these things?

 


 




-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

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