Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: matt@gushee.net
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Polymorphic class types?
Date: Sat, 22 Oct 2005 10:59:17 +0900 (JST)	[thread overview]
Message-ID: <20051022.105917.85812016.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <4359534A.7080706@gushee.net>

From: Matt Gushee <matt@gushee.net>

> So you are probably starting to get a sense of the problem: I need a
> basic framework of display logic that is independent of the application
> data, for positioning cards on the canvas, handling events, etc. But I
> also need to be able to get and set the content of cards in response to
> GUI events--the content being some arbitrary data structure, as
> mentioned above.

The trouble with your approach (that I leave below) is that you do not
distinguish between the programmer's view of the card and the canvas
view of the card. Clearly the canvas does not need to know what is in
the card, just how to show it.

So you have a type

class type card = object
  method id : string
  method place : int -> int -> unit
  method show : ?expanded:bool -> unit -> unit
  method hide : unit -> unit
  method expand : unit -> unit
  method collapse : int -> int -> unit
  method title : string
end

(everything but contents)

and another type

class type ['a] data_card = object
  inherit card
  method content : (string * 'a) list
end

which real cards will implement.

Then you canvas does not need a type parameter:

class type cp_canvas = object
  ...
  method cards : card list
  method get_card : string -> card
  method add_card : card -> unit
  ...
end

Now you will say: but when I use get_card I won't be able to get to
the real card anymore.
Sure, but that's not really a problem. Actually, in my experience I
would never use get_card anyway. If I have a way to connect events to
card, then I will define one handler for each card (or card family),
that will internally know the type of the exact card, so everything
works ok.

Lablgtk basically works that way: you add widgets to the GUI
structure, but you never try to extract information about them
afterwards.
One exception if for widgets the toolkit created for you internally,
for which you don't have enough information. But if you're designing
the toolkit this should not happen...

A smaller technical point: you are going to have to coerce your cards
to the type card. This can be done through (mycard :> card), but in
practice type inference is slow for that, and you don't want to see
the error message when it fails.
The approach in Lablgtk is to define a concrete class card, which
would include a coercing method
class virtual card = object (self)
   ...
   method as_card = (self :> card)
end
This way you just have to call the method to coerce any subclass to
the required type.

Jacques Garrigue

> So I have been trying to work with parameterized class type like this:
> 
>   class type ['a] card = object
>     method id : string
>     method place : int -> int -> unit
>     method show : ?expanded:bool -> unit -> unit
>     method hide : unit -> unit
>     method expand : unit -> unit
>     method collapse : int -> int -> unit
>     method content : (string * 'a) list
>     method title : string
>   end
> 
>   class type ['a] cp_canvas = object
>     method base : Widget.canvas Widget.widget
>     method cards : 'a card list
>     method get_card : string -> 'a card
>     method add_card : 'a card -> unit
>     method show : selection -> unit
>     method hide : selection -> unit
>     method expand : selection -> unit
>     method collapse : selection -> unit
>   end
> 
> But I don't think it's going to work. The sticking point is that there
> need to be various subtypes of cards, each with appropriate display
> logic for its content type, yet the canvas needs to be able to manage
> cards in a generic manner--i.e. it needs to work with the 'card'
> type--but of course that type doesn't exist, because 'card' takes a
> parameter, right?


      parent reply	other threads:[~2005-10-22  1:59 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-10-21 20:44 Matt Gushee
2005-10-22  1:51 ` [Caml-list] " skaller
2005-10-22  5:53   ` Matt Gushee
2005-10-22  8:52     ` skaller
2005-10-22  1:59 ` Jacques Garrigue [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20051022.105917.85812016.garrigue@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=matt@gushee.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox