Event Listeners in Functional Programming

1,822 views
Skip to first unread message

CuppoJava

unread,
Oct 10, 2008, 8:14:55 PM10/10/08
to Clojure
Hi guys,
I'm getting started with Clojure, and I'm programming a small gui.

The Java "idiom" for eg. a button, is to create a button object which
contains a list of "event listeners (closures/callback functions)"
that get called when the button is clicked.

This sort of structure relies upon the side-effects of the call-back
function.

What would be the functional programming equivalent for handling GUI
events?

Thanks a lot
-Patrick

Chouser

unread,
Oct 10, 2008, 9:58:31 PM10/10/08
to clo...@googlegroups.com
On Fri, Oct 10, 2008 at 8:14 PM, CuppoJava <patrick...@hotmail.com> wrote:
>
> The Java "idiom" for eg. a button, is to create a button object which
> contains a list of "event listeners (closures/callback functions)"
> that get called when the button is clicked.

So what is it you want the button to do? Mutability is no sin, and
Clojure gives you tools to manage it.

For example the click listener could dispatch an action to an agent,
which would allow the GUI to continue promptly while the action works
in another thread. Would that be sufficient for what you want to
accomplish?

--Chouser

CuppoJava

unread,
Oct 11, 2008, 12:10:16 PM10/11/08
to Clojure
Yeah, Clojure provides all that I need for GUI programming.
I was just wondering if there's an elegant way of doing GUI in a pure-
functional way, without mutability.

On Oct 10, 7:58 pm, Chouser <chou...@gmail.com> wrote:

Matthias Benkard

unread,
Oct 12, 2008, 5:50:26 AM10/12/08
to Clojure
Hi,

there are some papers about “functional reactive programming” out
there, which you might find interesting. FranTk [0] and, developed
more recently, Grapefruit [1], are functional reactive GUI toolkit for
Haskell, for example.

On the other hand, Gtk2Hs [2], probably the most popular GUI framework
for Haskell, mainly employs, guess what, conventional, imperative
callbacks. As it seems to me that Haskellers are the ones that try
most to write purely functional code, I conclude that this is likely
the most pragmatic way of writing GUIs right now.

I bet that further research is being done in this area, though.

Matthias

[0] http://www.haskell.org/FranTk/
[1] http://www.haskell.org/haskellwiki/Grapefruit
[2] http://www.haskell.org/gtk2hs/

Rich Hickey

unread,
Oct 12, 2008, 9:54:23 AM10/12/08
to Clojure
I think programs with interactive UIs are good examples of programs
which are not functions. That is, they have essential state - there is
an actual screen, a mouse, the mouse cursor has a position, there is a
checkbox, it is checked or not and can toggle etc.

Clojure is specifically designed with the recognition that many
interesting programs are not functions, but that huge portions of them
should be functional (much, much more than in the typical Java/C#/
Python/Ruby program), and that any essential state must be manipulated
in a thread-safe manner, and gives you tools for realizing all of
this.

As has been pointed out, Clojure fns are Runnable and Callable, and
make great callbacks for UIs. Those callbacks can manipulate a
transactional model, send actions to agents etc. Because Clojure's
facilities don't require the threads they run on to be launched by
Clojure, or blessed in any way, they can interoperate with the
threading model of any GUI, including Swing's.

I know people have generated UIs with Netbeans and driven them from
Clojure. A declarative style of UI definition (a la JavaFX/XAML)
should also be easy. You can experiment with functional reactive
programming if that's your cup of tea, but I'd like to emphasize that
it's not necessary to do so.

Clojure's STM already models a system of time-coordinated worlds. You
can make decisions based on information as-of a point in time and make
coordinated changes as-of a point in time. Agents model true
asynchronicity.

What you want to do is stay clear about the role of the UI and its
mutability and keep it there. There may be good reasons for a CheckBox
object to have mutable state but there are none for an Employee object
to do the same. Make your model functional, your state transitions
functions taking and returning immutable values. Then, if you want to
associate those values with identities, put them in a ref or agent.
The single-threadedness of Swing itself should be a clear warning as
to the difficulty (impossibility?) of making a graph-of-mutable-
objects design multithreading capable. Treat the UI as IO and don't
let it infect your design.

If you stick to Clojure's data structures, refs and agents you should
be able to build a robust system with any GUI framework, and have a
lot of fun doing so.

Rich

CuppoJava

unread,
Oct 12, 2008, 11:03:53 AM10/12/08
to Clojure
Thank you for all your help,
I read through some of the papers on functional reactive programming
for GUI, but it seems like it's adding unnecessary complexity to an
otherwise conceptually easy task. I guess GUI is still most intuitive
when modeled as a stateful object. Thank you for the reading though.

Clojure is a joy to program in Rich. Thank you for this elegant
language.
Reply all
Reply to author
Forward
0 new messages