[Openmcl-devel] Using Cocoa with MCL

Hamilton Link helink at sandia.gov
Thu May 8 13:09:32 PDT 2003

I think the following will continue to be most practical for the 
low-level thin wrapping of ObjC code. It has the advantage that it's 
pretty clear (to someone familiar with ObjC) what it does, and issues 
of case sensitivity, FFI mapped constants, etc. are all taken care of. 
This IMHO can then be used to implement a higher-level OO lisp wrapper, 
which I am inclined to agree with Sven and others is highly preferable. 
It would require documentation of a lisp library for interfacing with 
Cocoa, but programming GUI functionality would be largely homogeneous.

> (essentially Gary's current code)
> [[(@class "NSWindow") "alloc"]  
> "initWithContentRect:styleMask:backing:defer:"
>      graphicsRect
>      (bit-ior $NSTitledWindowMask
>                   $NSClosableWindowMask
>                   $NSMiniaturizableWindowMask)
>      $NSBackingStoreBuffered
>     $No]]
> [w "setTitle:" @"My Window"]

That said, is writing code like that below feasible? I think so, but it 
will require some fancy dancing. For one thing, if you want to write 
*lisp* code when you want to specialize widget behavior and manage 
callbacks you're going to have to extend the ObjC widget world 
(everything in it, all at once) to make well-known calls into lisp with 
enough information that a lisp analog of the Cocoa framework can grab 
the appropriate lisp object(s) and make the appropriate mapped method 
calls. Seems like I was drawing pictures of this for my own amusement 
the other day... I'll see about scanning them in and have Gary post 
them in the Wiki web site (as a strawman for people to discuss, not to 
propose as a solution, obviously).

The premise is that we have, for example, an LispMappedNSBrowser class 
that is a subclass of NSBrowser and overrides all specializable 
functions to call back into lisp with the appropriate information. If 
lisp wants to interfere, great, otherwise the default is to call back 
out into ObjC and invoke the super's method (the original NSBrowser's 
functionality). Possibly we could optimize unspecialized calls to not 
do this, but that's an implementation detail -- if it acts this way but 
doesn't work this way at all, who am I to care?

In any case, when you make instances of ns-browser in lisp (or in fact 
any subclass of the lisp ns-browser class), you're making an object 
that in turn makes a LispMappedNSBrowser in the ObjC run time, keeps a 
reference to it and, in some global lisp hash table, maps the ObjC 
instance back to the new lisp object. When the ObjC object is 
manipulated via known Cocoa framework functions defined on NSBrowser, 
these are specialized, call back into lisp, map from the ObjC world to 
the lisp world, invoke a method on the lisp object, which delegates or 
propagates all of it's changes back into the ObjC world using the 
super's methods (the real methods on NSBrowser itself).

To me this approach seems a little heavyweight, but it provides all the 
flexibility we'd need, and should be implementable in terms of lisp and 
the existing FFI ObjC syntax in a straightforward if somewhat extensive 
way. Does it pass other people's sanity checks? Perhaps someone in the 
group can think of a smoother way of doing what I'm trying to do here.

Oh, and by the way, since the only objects referring to ObjC objects 
should be their lisp counterparts, we can set ns-browser, etc. to be 
subclasses of ObjC-mapped-object. When we make an ObjC counterpart, we 
bump it's reference count up one for the sake of it's lisp equivalent, 
and have a finalization function for the lisp objects that decrement 
the reference count of the ObjC counterpart. All mutual references 
between widgets (such as are plentiful in the Inspector window, and 
presumably is common enough in general) can be managed by the lisp 
world instead, giving us most of the memory management we want.


On Thursday, May 8, 2003, at 01:32 PM, Sven Van Caekenberghe wrote:

> On Thursday, May 8, 2003, at 08:56 PM, Randall Beer wrote:
>> or (a fairly direct Lispification of the ObjC names and method 
>> structure)
>> (make-instance 'ns-window
>>     :init-with-content-rect graphicsRect
>>     :styleMask
>>     (bit-ior *ns-titled-window-mask*
>>                  *ns-closable-window-mask*
>>                  *ns-miniaturizable-window-mask*)
>>     :backing *ns-backing-store-buffered*
>>     :defer nil)
>> (send w :set-title "My Window")
> I think this style would be best. Doesn't it resemble how you approach 
> cocoa programming from java ? If I remember it correctly, the 
> objc-java bridge is automatically (automagically?) generated from the 
> original header files.
> This style strikes me as a nice compromise: if it could be auto 
> generated, you can track the libraries much better, maybe it would 
> even be possible to autogenerate documentation... On the other hand, 
> it feels almost like lisp, and it would still be possible to convert 
> objc or java code to lisp.
> A point that I missed in this discussion is how to map the cocoa 
> memory management to a full gc'ed world. I always wondered how they do 
> it in the objc-java bridge. What I hate about objc/cocoa is this 
> stupied retain/release stuff - could we make it go away ?
> Sven
> --
> Sven Van Caekenberghe - mailto:sven at beta9.be
> Beta Nine - software engineering - http://www.beta9.be
> .Mac - svc at mac.com - http://homepage.mac.com/svc
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/cgi-bin/mailman/listinfo/openmcl-devel

Openmcl-devel mailing list
Openmcl-devel at clozure.com

More information about the Openmcl-devel mailing list