Generic functions for procedures in the (gnome gobject)
module.
Guile-GNOME exists to wrap a C library, libgobject
, its types, and the
set of libraries that based themselves on the GLib types.
Procedure invocation feels very similar in Scheme and in C. For example, the C
gtk_widget_show (widget)
transliterates almost exactly to the Scheme
(gtk-widget-show widget)
.
GLib-based libraries are not random collections of functions, however.
GLib-based libraries also implement classes and methods, insofar that it is
possible in C. For example, in the above example, show
may be seen to be
a method on instances of the <gtk-widget>
class.
Indeed, other object-oriented languages such as Python express this pattern
directly, translating the show
operation as the pleasantly brief
widget.show()
. However this representation of methods as being bound to
instances, while common, has a number of drawbacks.
The largest drawback is that the method itself is not bound to a generic
operation. For example, mapping the show
operation across a set of
widgets cannot be done with the straightforward map(show, set)
, because
there is no object for the show
operation. Instead the user must locally
bind each widget to a variable in order to access a method of the abstract
show
operation: map(lambda widget: widget.show(), set)
.
Additionally, most languages which express methods as bound to instances only
select the method via the type of the first (implicit) argument. The rule for
these lanugages is, “gtk-widget-show
is an applicable method of the
show
operation when the first argument to show
is a
<gtk-widget>
.” Note the lack of specification for other arguments; the
same object cannot have two applicable methods of the show
operation. A
more complete specification would be, “gtk-widget-show
is an applicable
method of the show
operation when applied to one argument, a
<gtk-widget>
.” It is a fine difference, but sometimes important.
For these and other reasons, the conventional way to implement generic operations in Lisp has been to define generic functions, and then associate specific methods with those functions. For example, one would write the following:
;; defining a generic function, and one method implementation (define-generic show) (define-method (show (widget <gtk-widget>)) (gtk-widget-show widget)) ;; invoking the generic function (show my-widget)
One benefit of this approach is that method definitions can be made far away in space and time from type definitions. This leads to a more dynamic environment, in which methods can be added to existing types at runtime, which then can apply to existing instances.
Naturally, there is an impedance mismatch between the conventions used in the C
libraries and their Scheme equivalents. Operations in GLib-based libraries do
not form a coherent whole, in the sense that there is no place that defines the
meaning of an abstract show
operation. For example,
gtk-widget-set-state
, which can make a widget become uneditable, and
gst-element-set-state
, which can start a video player, would both map to
the generic function set-state
, even though they have nothing to do with
each other besides their name.
There is no conflict here; the methods apply on disjoint types. However there is
a problem of modularity, in that both methods must be defined on the same
generic function, so that (set-state foo bar)
picks the correct method,
depending on the types of foo and bar.
This point leads to the conclusion that generic functions in Guile-GNOME have no abstract meaning, apart from their names. Semantically, generics in Guile-GNOME are abbreviations to save typing, not abstract operations with defined meanings.
This module defines a number of “abbreviations”, in the form of generic
functions, for operations on types defined in the (gnome gobject)
modules. Generic functions for generated bindings like (gnome gtk)
are
defined in another module, (gnome gw generics)
, which re-exports the
public bindings from this module.
<gobject>
) (name <symbol>
) (value <top>
)A shorthand for
gobject-set-property
.
<gtype-instance>
) (name <symbol>
) (args <top>
)...A shorthand for
gtype-instance-signal-emit
.
<gtype-instance>
) (name <symbol>
) (func <procedure>
)A shorthand for
gtype-instance-signal-connect
.
<gtype-instance>
) (name <symbol>
) (func <procedure>
)A shorthand for
gtype-instance-signal-connect-after
.
<gtype-instance>
) (id <top>
)A shorthand for
gsignal-handler-disconnect
.
<gtype-instance>
) (id <top>
)A shorthand for
gsignal-handler-connected?
.
<gtype-class>
) (name <symbol>
) (return-type <top>
) (param-types <top>
)A shorthand for
gtype-class-create-signal
.