Macros and side-effects

View: New views
4 Messages — Rating Filter:   Alert me  

Macros and side-effects

by Maurí­cio CA :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I just had this small anoyance: when writing bindings from Gtk
to another language (Haskell, but it's not Gtk2hs, it's just
a personal use binding), I assigned constants to the value of
many macros in GObject Type Information section. Those would be
G_TYPE_CHAR, G_TYPE_INT etc.

Those macros are actually constants, except for one: G_TYPE_GTYPE.
It calls a function, and since the assignment was done at compile
time, I didn't have g_type_init() called.

I don't know if this is important for other languages, as
side-effects need special care in Haskell. But is there some
general rule I could follow on that?

Thanks,
Maurício

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Macros and side-effects

by David Nečas (Yeti)-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Oct 25, 2009 at 11:29:59AM -0200, Maurí­cio CA wrote:

> I just had this small anoyance: when writing bindings from Gtk
> to another language (Haskell, but it's not Gtk2hs, it's just
> a personal use binding), I assigned constants to the value of
> many macros in GObject Type Information section. Those would be
> G_TYPE_CHAR, G_TYPE_INT etc.
>
> Those macros are actually constants, except for one: G_TYPE_GTYPE.
> It calls a function, and since the assignment was done at compile
> time, I didn't have g_type_init() called.
>
> I don't know if this is important for other languages, as
> side-effects need special care in Haskell. But is there some
> general rule I could follow on that?

Two comments:

1) This is not a small annoyance concerning G_TYPE_GTYPE.  Every single
type macro in in Gtk+ and other libs expands to a gtk_foo_get_type()
call, just the atomic types in GObject are constants.

2) Is this side effect relevant for Haskell?  The C function

double get_log5(void)
{
    static double log5 = 0.0;
    if (log5 == 0.0)
        log5 = log(5.0);
    return log5;
}  

definitely has a side effect.  But no language wrapping this function
should need to care about it.  Conversely, every function has some
side-effects: on CPU caches and branch prediction, it can cause page
faults that the OS has to handle taking almost arbitrary actions, it
causes the internal state of the interpreter/virtual machine to change,
it takes time and consumes power.  Each such side effect is observable
-- and important for some people.  But then nothing could be functional.

So only side-effects that are side-effects for the abstract language
are considered.  All calls to g_gtype_get_type() and gtk_foo_get_type()
return the same constant.  So does it matter for the abstract language
how this constant is implemented?

Yeti

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Macros and side-effects

by Maurí­cio CA :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 > 2) Is this side effect relevant for Haskell? The C function
 > (...) definitely has a side effect. But no language wrapping
 > this function should need to care about it. (...)

 > So only side-effects that are side-effects for the abstract
 > language are considered. All calls to g_gtype_get_type() and
 > gtk_foo_get_type() return the same constant. So does it matter
 > for the abstract language how this constant is implemented?

I usually consider all foreign code to have possible effects. I
see no beneficts in doing otherwise, although I don't speak for
other haskellers. If I dress something into a Haskell "pure"
value, I have no guarantees on when it is going to be first
determinated -- for instance, I can't be sure g_type_init has been
called before gtk_foo_get_type() -- and I get little in exchange.

Just to show you how I got into trouble: using the usual tools
for binding from Haskell, I have to choose between taking values
at compile time or runtime. Since I can't assume all values are
available at compile time, I need to have a function that returns
it at runtime. So, as an example, I would write a helper function.

int helper_G_TYPE_DOUBLE ()
{
   return G_TYPE_DOUBLE;
}

This is not usually a problem, as I have a few macros to do that
for me. But I didn't do that with G_TYPE_GTYPE because it was
among many constants, and I toke the lazy path.

Thanks,
Maurício

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list

Re: Macros and side-effects

by David Nečas (Yeti)-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Oct 25, 2009 at 07:05:17PM -0200, Maurí­cio CA wrote:

> > 2) Is this side effect relevant for Haskell? The C function
> > (...) definitely has a side effect. But no language wrapping
> > this function should need to care about it. (...)
>
> > So only side-effects that are side-effects for the abstract
> > language are considered. All calls to g_gtype_get_type() and
> > gtk_foo_get_type() return the same constant. So does it matter
> > for the abstract language how this constant is implemented?
>
> I usually consider all foreign code to have possible effects. I
> see no beneficts in doing otherwise, although I don't speak for
> other haskellers. If I dress something into a Haskell "pure"
> value, I have no guarantees on when it is going to be first
> determinated -- for instance, I can't be sure g_type_init has been
> called before gtk_foo_get_type() -- and I get little in exchange.

If global initialization is not possible, then the wrapper for every
such function/value must check if the initialization has been already
done and possibly perform it.  This way they still behave like
constants.

> Just to show you how I got into trouble: using the usual tools
> for binding from Haskell, I have to choose between taking values
> at compile time or runtime. Since I can't assume all values are
> available at compile time, I need to have a function that returns
> it at runtime. So, as an example, I would write a helper function.
>
> int helper_G_TYPE_DOUBLE ()
> {
>   return G_TYPE_DOUBLE;
> }
>
> This is not usually a problem, as I have a few macros to do that
> for me. But I didn't do that with G_TYPE_GTYPE because it was
> among many constants, and I toke the lazy path.

Well, you will have to do this for every GTK_FOO_TYPE, so it should not
make much difference...   Anyway, such wrapper needs to ensure
g_type_init() is called before evaluating GTK_FOO_TYPE.

Yeti

_______________________________________________
gtk-list mailing list
gtk-list@...
http://mail.gnome.org/mailman/listinfo/gtk-list