How to port a mixin to clojure

138 views
Skip to first unread message

Jesse Aldridge

unread,
Feb 11, 2009, 3:55:48 AM2/11/09
to Clojure
I'm trying to re-implement some python stuff in clojure. Here's how
it works: I have a class called ArrowKeySelection. I use this class
as a mixin with various gui classes. The class adds some abstract
logic for handling keys - the arrow keys move a selector around a
matrix and the enter key calls an activation method with the selected
object. The implementation details are left to the extending class.

My python class looks something like this:

class ArrowKeySelection:
def __init__(self):
self.selected_row, self.selected_col = (0,0)

def on_key_down(self, code):
if keycodes.is_arrow_key(code):
... move the selector around
if code == "return" or code == "space":
...
self.activate(selected)

def get_selected(self):
...

def select(self, desired_object):
...

def num_cols(self):
...
def num_rows(self):
...

...

----------

Then when I use it, I make something like this:

----------

class TableWidget(HtmlWidget, ArrowKeySelection):
def __init__(self, strings):
HtmlWidget.__init__(self, None)
self.strings = strings

ArrowKeySelection.__init__(self)

self.set_html()

def set_html(self):
... construct an html table from the current state

def on_key_down(self, code):
ArrowKeySelection.on_key_down(self, code)
self.set_html()

def activate(self, object):
...

------------

So what would be the best way to re-implement this functionality in
clojure?

Chas Emerick

unread,
Feb 11, 2009, 6:12:29 AM2/11/09
to clo...@googlegroups.com
I'm not sure I would call that a mixin -- really, all that's going on
is Python is allowing you to call any function, anywhere. In a
language like Scala that does have what I'd consider "real" mixins
(traits over there), then on_key_down would become a function
available in TableWidget's "namespace". (Not trying to make trouble
here, just a pedantic note on terminology -- I quite like Python.)

Anyway, it seems like all you need is to implement your
ArrowKeySelection functionality in one lib, and call its functions
from your UI widget's method implementations. There is the slight
detail of getting ArrowKeySelection's contribution to the widget's
state rolled in, but if you're using, say, a clojure map for your
widget's state (hopefully wrapped in a ref to keep those multithread
gremlins away), then it's easy enough to add an 'init' function to
ArrowKeySelection's namespace that will add the fields it requires to
any given map. Your widgets can then hook into that when they're
first initializing their state map.

- Chas

David Nolen

unread,
Feb 11, 2009, 10:14:31 AM2/11/09
to clojure
There are quite a few ways to do what you're describing (and no particular prescribed way).  You want to look at multimethods and tag hierarchies.


Tags can have multiple parents.

I'm working on a project called Spinoza (search the mailing list for that and CLJOS) which you might want to give a look if you want to see one perspective on what a syntax to do the above might look like.  It also uses multimethods and hierarchies but it removes the need to manually deal with tags or explicitly call object initializers.
Reply all
Reply to author
Forward
0 new messages