Re: Structures thought question



On Sat, 2008-11-15 at 07:06 -0500, Owen Taylor wrote:
> For each of the following functions:

I'm a little late, but...

>  A) What are the correct direction annotations for the arguments
>    (in/out/inout)

It is indicated in the function type signatures below:

>  B) How is it invoked from Javascript? From your language of choice?

Here's how we'd bind them in Haskell, purely functional so no mutating
arguments, just returning new objects.

> void clutter_color_from_pixel (ClutterColor *dest,
>                                guint32       pixel);

Clutter.colorFromPixel :: Pixel -> Clutter.Color

> void gdk_region_union (GdkRegion       *source1,
>                        const GdkRegion *source2);

Gdk.Region.union :: Gdk.Region -> Gdk.Region -> Gdk.Region

note we have to allocate a new region for the result. No mutating
existing ones.

> void gdk_region_get_clipbox (const GdkRegion *region,
>                              GdkRectangle    *rectangle);

Gdk.Region.getClipbox :: Gdk.Region -> Gdk.Rectangle

> void gtk_text_buffer_insert (GtkTextBuffer *buffer,
>                              GtkTextIter   *iter,
>                              const gchar   *text,
>                              gint           len);

If we were able to be purist here we'd say it returns a new
Gtk.TextBuffer, however since we're binding the real GtkTextBuffer which
is mutable not persistent we have to throw up out hands and toss this
operation into the IO monad to indicate it is not pure:

Gtk.TextBuffer.insert :: Gtk.TextBuffer -> Gtk.TextIter
                      -> String -> IO ()

> gboolean clutter_color_parse (const gchar  *color,
>                               ClutterColor *dest);

Clutter.Color.parse :: String -> Maybe Clutter.Color 

Using the Maybe type to indicate if the parsing was successful or not.
For example:

case Clutter.Color.parse "foo" of
  Nothing    -> error "oh no!"
  Just color -> ... etc

In practise we'd hide this explicit error handling using an error monad.

> gboolean gdk_colormap_alloc_color (GdkColormap *colormap,
>                                    GdkColor    *color,
>                                    gboolean     writeable,
>                                    gboolean     best_match);

I don't have quite enough information here to know what is really going
on. Is the GdkColormap being mutated? I'll assume not but assume that
the GdkColor is an in/out parameter. I'm not sure what the writable is.
If it means if we're allowed to modify the color or colour map then we
cannot bind this as a single function, as the in and out parameteres
would be different for the case of writable true or false.

Gdk.Colormap.allocColor :: Gdk.Colormap -> Bool -> Bool
                        -> Gdk.Color -> Gdk.Color


On the issue of two or three argument operations, it is helpful for
functional languages if the three argument versions are available. Eg
the OO language would mutate the object like:

eg in the OOP lang:
self.op(other)  
would be bound in underlying C as something like:
self = op(self, other)

while the functional language
op arg1 arg2
would turn into C code like:
result = new_thing()
result = op(arg1, arg2)
return result

which makes the overall result pure (ignoring memory allocation). This
style of binding works well for things which we think of as being "by
value" like colours, regions etc. Obviously it doesn't work for binding
C objects that have reference semantics and methods that mutate the
internal object state. Those have to be bound in pure languages using
their cunning tricks for handling IO operations.

Duncan



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]