[cl-gtk2-devel] gtk_widget_add_events

Peter Keller psilord at cs.wisc.edu
Sun Jul 17 19:16:38 UTC 2011


Hello,

On Sun, Jul 17, 2011 at 12:46:38PM +0400, Valeriy Fedotov wrote:
> > This way, when people find the many GTK+ tutorials in C online, or read
> > books on GTK+ development, they aren't immediately frustrated by having
> > to decipher someone's (arbitrary, IMHO) viewpoint of what it meant to be
> > Lispy while also trying to understand the material (and its conversion
> > to CL).
> 
> Indeed, I think that currently cl-gtk2 interface is close to GTK2
> original interface, of course, if you understand certain conventions.
> Of course if you translate several examples form GTK2 to cl-gtk2, it
> will be very helpful.

I'm perfectly willing to believe, accept, and follow these
conventions. But if those certain conventions aren't documented anywhere,
they might not be obvious--especially when a particular convention is
made so explicit in the original C interface.

> > Pushing the responsibility of handling that
> > data binding to a function which doesn't care about it (and isn't even
> > called!) is awkward. But, I have no choice given the implementation
> > of cl-gtk2.
> 
> If you add :data argument you will need to pass "responsibility"
> somewhere anyway, because otherwise the data will be possibly garbage
> collected. Introducing explicit memory management to common lisp
> program is generally bad idea. And lexical closures instead of :data
> argument is the most natural way of doing garbage collection in the
> lisp way.

Ok, so let's see if I understand this:

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GTK passing style, not implemented in cl-gtk2 due to explicit memory 
;; management being dumb (and it is).
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun button-clicked (widget data)
  (format t "button would modify data ~A~%" data))

(connect-signal button "clicked" #'button-clicked some-widget-created-elsewhere)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the style cl-gtk2 promotes using lexical closures.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; some-widget-created-elsewhere is in lexical scope here. The handler
;; is defined in place.
(connect-signal button "clicked"
  (lambda (widget)
    ;; close over some-widget-created-elsewhere
    (format t "button would modify data ~A~%" some-widget-created-elsewhere)))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Suppose the function button-clicked is 200 lines long and its lambda-list is
;; (defun button-clicked (widget data) ...)
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Wrap the call to the handler into a small closure to manually propogate the
;; data. Each time I want to associate data with a slot handler, there will
;; always be this little closure here.
(connect-signal button "clicked"
  (lambda (widget)
    ;; I don't want to write a 200 line function here, but I need
    ;; a lexical closure, so this lambda function acts as a curried
    ;; function to the actual slot handler.
    (button-clicked widget some-widget-created-elsewhere)))

Would this be the convention made explcit of which you speak?

-pete




More information about the cl-gtk2-devel mailing list