Re: mixins/multiple inheritance

2012-02-09 Thread Matthias Diehn Ingesman
The problem with the protocols approach is that it leads to an explosion in 
the number of explicitly defined records. His example was only with labels, 
but I can imagine he might have borders and any number of other decorations 
on the widgets, in which case he would need something like

(defrecord Textfield ...)
(defrecord LabelledTextfield ...)
(defrecord BorderedTextfield ...)
(defrecord LabelledAndBorderedTextfield ...)
; and so on for each combination of decorator and widget

With the other approach he would only need a record for each widget and one 
for each decorator.

-- 
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: mixins/multiple inheritance

2012-02-09 Thread David Nolen
I think the suggestions thus far are not ideal. Both protocols and
multimethods provide a way to define a default case. The default case gives
you opportunity to adopt a delegation / component based design.

(defprotocol IFlightOrgan
  (flight-organ [this]))

(defprotocol IFlight
  (can-fly? [this])
  (fly [this] [this body]))

(extend-type Object
  IFlight
  (can-fly? [this]
(satisfies? IFlightOrgan this))
  (fly
([this]
   (fly (flight-organ this) this))
([this body]
   (fly (flight-organ this) body

Now any type that provides a flight-organ can fly (note we even handle the
self-sufficient case). How the flight organ is acquired is completely up to
the provider - it could be a field or it could done via map lookup (if you
need the type to be the aggregate of many components).

This paper is really worth reading, Organizing Programs Without Classes
http://cs.au.dk/~hosc/local/LaSC-4-3-pp223-242.pdf

David

On Sun, Feb 5, 2012 at 4:15 PM, Razvan Rotaru razvan.rot...@gmail.comwrote:

 Hi,

 I found some posts about this topic, but they did not clarify things
 in my head well enough, so I have to start my own... :)

 I'm basically craving for multiple inheritance or mixins, at least
 with my current way of thinking. I haven't really gone deep enough
 with multimethods or protocols, so I might be a little off track by
 looking for multiple inheritance.

 Let's take an example:

 I want to implement some gui widgets, so there's a main method
 render which draws the widget on the screen. I want to have two
 types:

 - Textfield
 - Datetimepicker

 Each can be mixed with the Label widget, so that we have:

 - LabelledTextfield
 - LabelledDatetimepicker

 So, two challenges occur:
 1/ the render method for Label needs to call the render method for
 it's mixed widget (either Textfield or Datetimepicker) - let's
 assume that labels are rendered around the actual widget, so that we
 have a simple way to mix the implementations of render method
 2/ the Label widget comes with its own data (the label text)

 For the second thing, I think it will work with defrecords, since the
 label can be a map entry which can be stored in the actual widget,
 even if it's not mixed with Label. I still want to point this out in
 case there are other ways of achieving this.

 How can I achieve 1? Are there alternatives for 2?

 Thanks for reading,
 Razvan

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

-- 
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: mixins/multiple inheritance

2012-02-08 Thread Matthias Diehn Ingesman
Hm, I wrote a reply yesterday figuring it would show up today (seeing as I 
accidentally double posted last time because it did not show up at once), 
but that reply seems to be lost.

I see what you mean now, I think. Seeing as you will have to build your 
hierarchies yourself you might try something like the following:

(defrecord Label [text])
(defrecord TextField [text])

(defmacro c-mix [orig o-args mixin m-args]
  `(with-meta
(new ~orig ~o-args)
{:mixin (new ~mixin ~m-args)}))

;; Extracting the mixin instance
(defn mixin [o]
  (:mixin (meta o)))

(defmulti render (fn [x] (or (class (:mixin (meta x)))
 (class x
(defmethod render TextField [x] (:text x))
(defmethod render Label [x] (str (:text (mixin x)) :  (render (with-meta 
x {}

(def labelledtextfield (c-mix TextField Foo Label Name))
(def textfield (TextField. Foo))

(render textfield) ;= Foo
(render labelledtextfield) ;= Name: Foo

This will allow you to emulate dynamic mixin composition by using the c-mix 
macro which is like a constructor call that attaches an instance of the 
mixin object as meta data. I know you would like to avoid macros, but since 
it is not possible to instantiate an object from a function parameter I 
don't think you can avoid them entirely.

Ad-hoc hierarchies using derive might also combine well with this solution, 
but then you would have to stay away from defrecord and define your own 
types I think.

Regards,
 Matthias

-- 
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: mixins/multiple inheritance

2012-02-08 Thread Cedric Greevey
Is there a reason not to just use protocols for your mixins?

(defprotocol Labelled
  whatever)

(defprotocol Textfield
  whatever-else)

(defprotocol Datetimepicker
  something)

(defrecord Label
  Labelled
  whatever ...)

(defrecord Textbox
  Textfield
  whatever-else ...)

(defrecord LabelledTextbox
  Labelled
  whatever ...
  Textfield
  whatever-else ...)

and so forth, and probably punt to external fns for anything that
would otherwise get duplicated between Textbox and LabelledTextbox, or
between Label and LabelledTextbox, and so forth.

-- 
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: mixins/multiple inheritance

2012-02-08 Thread Alex Baranosky
Cedric's is the approach I would take.  Like he said, use private functions
for the shared code.

On Wed, Feb 8, 2012 at 8:49 PM, Cedric Greevey cgree...@gmail.com wrote:

 Is there a reason not to just use protocols for your mixins?

 (defprotocol Labelled
  whatever)

 (defprotocol Textfield
  whatever-else)

 (defprotocol Datetimepicker
  something)

 (defrecord Label
  Labelled
  whatever ...)

 (defrecord Textbox
  Textfield
  whatever-else ...)

 (defrecord LabelledTextbox
  Labelled
  whatever ...
  Textfield
  whatever-else ...)

 and so forth, and probably punt to external fns for anything that
 would otherwise get duplicated between Textbox and LabelledTextbox, or
 between Label and LabelledTextbox, and so forth.

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


-- 
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: mixins/multiple inheritance

2012-02-06 Thread Matthias Diehn Ingesman
It sounds like a use for the decorator pattern, or am I missing
something? In case I am not I have given it a shot using records and
protocols:

(defrecord TextField [text])
(defrecord DatetimePicker [datetimes])
(defrecord Label [text widget])

(defprotocol Renderable
  (render [this]))

(extend-protocol Renderable
  TextField
  (render [this]
(str [ (:text this) ]))

  DatetimePicker
  (render [this]
(apply str (:datetimes this)))

  Label
  (render [this]
(str (:text this) :  (render (:widget this)

(comment
  (def textfield (TextField. Foo))
  (def datetimepicker (DatetimePicker. [:yesterday :today :tomorrow]))
  (def labeledtextfield (Label. Name textfield))
  (def labeleddatetimepicker (Label. Date datetimepicker))
  (render textfield) ;= [Foo]
  (render datetimepicker) ;= :yesterday:today:tomorrow
  (render labeledtextfield) ;= Name: [Foo]
  (render labeleddatetimepicker) ;= Date: :yesterday:today:tomorrow
  )

1/ is handled by the Renderable implementation of Label calling the
Renderable implementation of whatever widget is decorated by the Label
instance.

2/ is handled by having the label decorator as a record.

Regards,
 Matthias

On 5 Feb., 22:15, Razvan Rotaru razvan.rot...@gmail.com wrote:
 Hi,

 I found some posts about this topic, but they did not clarify things
 in my head well enough, so I have to start my own... :)

 I'm basically craving for multiple inheritance or mixins, at least
 with my current way of thinking. I haven't really gone deep enough
 with multimethods or protocols, so I might be a little off track by
 looking for multiple inheritance.

 Let's take an example:

 I want to implement some gui widgets, so there's a main method
 render which draws the widget on the screen. I want to have two
 types:

 - Textfield
 - Datetimepicker

 Each can be mixed with the Label widget, so that we have:

 - LabelledTextfield
 - LabelledDatetimepicker

 So, two challenges occur:
 1/ the render method for Label needs to call the render method for
 it's mixed widget (either Textfield or Datetimepicker) - let's
 assume that labels are rendered around the actual widget, so that we
 have a simple way to mix the implementations of render method
 2/ the Label widget comes with its own data (the label text)

 For the second thing, I think it will work with defrecords, since the
 label can be a map entry which can be stored in the actual widget,
 even if it's not mixed with Label. I still want to point this out in
 case there are other ways of achieving this.

 How can I achieve 1? Are there alternatives for 2?

 Thanks for reading,
 Razvan

-- 
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: mixins/multiple inheritance

2012-02-06 Thread Matthias Diehn Ingesman
It sounds a little like the decorator pattern would do the trick for
you in this case - am I missing something? In case I am not, I have
given it a shot using records and protocols:

(defrecord TextField [text])
(defrecord DatetimePicker [datetimes])
(defrecord Label [text widget])

(defprotocol Renderable
  (render [this]))

(extend-protocol Renderable
  TextField
  (render [this]
(str [ (:text this) ]))

  DatetimePicker
  (render [this]
(apply str (:datetimes this)))

  Label
  (render [this]
(str (:text this) :  (render (:widget this)

(comment
  (def textfield (TextField. Foo))
  (def datetimepicker (DatetimePicker. [:yesterday :today :tomorrow]))
  (def labeledtextfield (Label. Name textfield))
  (def labeleddatetimepicker (Label. Date datetimepicker))
  (render textfield) ;= [Foo]
  (render datetimepicker) ;= :yesterday:today:tomorrow
  (render labeledtextfield) ;= Name: [Foo]
  (render labeleddatetimepicker) ;= Date: :yesterday:today:tomorrow
  )

1/ is handled by the Renderable implementation for Label calling the
Renderable implementation on whatever widget it decorates with a
label.

2/ is handled by having the Label decorator widget as a record.

Regards,
 Matthias

On 5 Feb., 22:15, Razvan Rotaru razvan.rot...@gmail.com wrote:
 Hi,

 I found some posts about this topic, but they did not clarify things
 in my head well enough, so I have to start my own... :)

 I'm basically craving for multiple inheritance or mixins, at least
 with my current way of thinking. I haven't really gone deep enough
 with multimethods or protocols, so I might be a little off track by
 looking for multiple inheritance.

 Let's take an example:

 I want to implement some gui widgets, so there's a main method
 render which draws the widget on the screen. I want to have two
 types:

 - Textfield
 - Datetimepicker

 Each can be mixed with the Label widget, so that we have:

 - LabelledTextfield
 - LabelledDatetimepicker

 So, two challenges occur:
 1/ the render method for Label needs to call the render method for
 it's mixed widget (either Textfield or Datetimepicker) - let's
 assume that labels are rendered around the actual widget, so that we
 have a simple way to mix the implementations of render method
 2/ the Label widget comes with its own data (the label text)

 For the second thing, I think it will work with defrecords, since the
 label can be a map entry which can be stored in the actual widget,
 even if it's not mixed with Label. I still want to point this out in
 case there are other ways of achieving this.

 How can I achieve 1? Are there alternatives for 2?

 Thanks for reading,
 Razvan

-- 
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: mixins/multiple inheritance

2012-02-06 Thread Razvan Rotaru
Thanks,

This works, but there's a problem: the labeledtextfield is not a
textfield anymore, it's a label. Therefore it does not behave like a
textfield (which implements other protocols as well). I need multiple
inheritance, in one way or another. I've been trying to find a way to
implement with multimethods.

For example, if label was a mixin, then it means I could do something
like this:

(def textfield (new TextField Foo)
(def labeledtextfield (new (mix TextField Label) Name Foo))

(render textfield) ;= [Foo]
(render labeledtextfield) ;= Name: [Foo]

Oh, and I'd like to stay away from macros, if possible. :)

Razvan

On Feb 6, 12:20 pm, Matthias Diehn Ingesman matdi...@gmail.com
wrote:
 It sounds a little like the decorator pattern would do the trick for
 you in this case - am I missing something? In case I am not, I have
 given it a shot using records and protocols:

 (defrecord TextField [text])
 (defrecord DatetimePicker [datetimes])
 (defrecord Label [text widget])

 (defprotocol Renderable
   (render [this]))

 (extend-protocol Renderable
   TextField
   (render [this]
     (str [ (:text this) ]))

   DatetimePicker
   (render [this]
     (apply str (:datetimes this)))

   Label
   (render [this]
     (str (:text this) :  (render (:widget this)

 (comment
   (def textfield (TextField. Foo))
   (def datetimepicker (DatetimePicker. [:yesterday :today :tomorrow]))
   (def labeledtextfield (Label. Name textfield))
   (def labeleddatetimepicker (Label. Date datetimepicker))
   (render textfield) ;= [Foo]
   (render datetimepicker) ;= :yesterday:today:tomorrow
   (render labeledtextfield) ;= Name: [Foo]
   (render labeleddatetimepicker) ;= Date: :yesterday:today:tomorrow
   )

 1/ is handled by the Renderable implementation for Label calling the
 Renderable implementation on whatever widget it decorates with a
 label.

 2/ is handled by having the Label decorator widget as a record.

 Regards,
  Matthias

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


mixins/multiple inheritance

2012-02-05 Thread Razvan Rotaru
Hi,

I found some posts about this topic, but they did not clarify things
in my head well enough, so I have to start my own... :)

I'm basically craving for multiple inheritance or mixins, at least
with my current way of thinking. I haven't really gone deep enough
with multimethods or protocols, so I might be a little off track by
looking for multiple inheritance.

Let's take an example:

I want to implement some gui widgets, so there's a main method
render which draws the widget on the screen. I want to have two
types:

- Textfield
- Datetimepicker

Each can be mixed with the Label widget, so that we have:

- LabelledTextfield
- LabelledDatetimepicker

So, two challenges occur:
1/ the render method for Label needs to call the render method for
it's mixed widget (either Textfield or Datetimepicker) - let's
assume that labels are rendered around the actual widget, so that we
have a simple way to mix the implementations of render method
2/ the Label widget comes with its own data (the label text)

For the second thing, I think it will work with defrecords, since the
label can be a map entry which can be stored in the actual widget,
even if it's not mixed with Label. I still want to point this out in
case there are other ways of achieving this.

How can I achieve 1? Are there alternatives for 2?

Thanks for reading,
Razvan

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