[Openmcl-devel] Using Cocoa with MCL

Gary Byers gb at clozure.com
Thu May 15 09:21:30 PDT 2003

On Fri, 9 May 2003, Randall Beer wrote:

> >> As you
> >> suggest, the latter may be implemented in former.  I guess that I'm
> >> struggling to clearly envision what the final goal should look like,
> >> at
> >> least in broad terms.  Then we can decide what the right intermediate
> >> layers of abstraction might be.  Is the goal (1) Lisp sugar for ObjC,
> >> (2) CLOSified Cocoa, (3) an MCL-like CLOS system, (4) something like
> >> CLIM (or (5), something I haven't thought of)?
> >

Sorry not to have responded to this (and a few other recent messages)

I vote against (3), for reasons that others have mentioned.  I think
that it's really hard to design (and implement!) something like this
and harder still to do so in a way that keeps up with changes in the
underlying window system.

I've heard people (myself included) express interest in seeing a
Cocoa-based McCLIM (mcclim.cliki.net) backend.  Tim Moore (one of the
McCLIM developers) has also expressed interest in this; we poked
around a few months ago and found that the fact that Cocoa really
wants to handle events and drawing in a single, distinguished thread
is at odds with McCLIM's current window/thread model.  Unless I'm
misquoting him, Tim's indicated a willingness to change things (or at
least decouple things) so that McCLIM is less sensitive to the
backend's threading model; unless I'm misquoting him again, he's also
indicated that he thought that something higher-level than the
FFI/reader macros would make development of a Cocoa backend for McCLIM
a lot easier.

Having CLIM running natively in OpenMCL (AFAIK, McCLIM runs at least fairly
well under CLX) would be interesting to and fill a need for many people.

Many other people would probably prefer something closer to (2) or (1)
on your list: they don't want or need CLIM functionality, but do want
the ability to deliver GUI-based OpenMCL applications.  It's worth
noting that the two goals (improving OpenMCL's development environment
and making it easier to develop and deliver GUI-based applications)
don't necessarily have the same solution: one might find oneself using
CLIM-based development tools to develop (CLIM-less) Cocoa applications,
or vice versa.

I want to try to keep this reply high-level and abstract, but can't
resist the temptation to sink into the gutter (or at least some lower-
level details) for a moment.  I don't know if anyone's ever looked at
the function OBCJ-OBJECT-P (in "ccl:examples;apple-objc.lisp"); it
does a very, very good job of heuristically determining whether or not
a given MACPTR is an ObjC object (and if so, whether it's an instance,
class, or metaclass object and what its class is.)  One might be able
to artificially construct a MACPTR that passed these heuristic tests,
but such a MACPTR would have to look so much like an ObjC object that
the ObjC runtime would be fooled as well; for the sake of argument,
anything that OBJC-OBJECT-P says is an ObjC object pretty much -is-
an ObjC object.  (If anyone's skeptical about this, note that it's
also possible to make OBJC-OBJECT-P more paranoid than it currently
is.  If we don't want to make this (as) heuristic, we can also modify
the FFI to -really- distinguish between :ADDRESS (arbitrary pointer)
and :ID (pointer to ObjC object, or - perhaps more generally - "pointer
to runtime-typed foreign object", which might also provide a way to
deal with CFObjects.)

Suppose that CLASS-OF and TYPE-OF (and a few other things) knew (via
OBJC-OBJECT-P) that the result of calling

 [[(@class "NSWindow") "alloc"] "initWithContentRect:..."]

was an instance of the NSWINDOW class (in the CLOS sense as well as
the ObjC sense.)  In such a world, the result of doing:

 (make-instance 'nswindow :content-rect ...)

would be the same type of object (and interchangably recognizable as
an NSWINDOW/:<NSW>indow instance to both ObjC and CLOS.)

The astute reader will note that OpenMCL only supports bits and pieces
of the AMOP, and at first glance it seems like making ObjC objects
"be" CLOS objects is a job for the AMOP.  It's easy to see how some
AMOP features would come in handy (SLOT-VALUE-USING-CLASS, implemented
in terms of PREF); on the other hand, this kind of integration of
ObjC and CLOS objects may require stuff that isn't in the AMOP: the
AHMOP ("Ad-Hoc MOP") may be necessary.

To crawl back out of the gutter and try to address high-level questions
again: if we had the ability to treat ObjC objects as CLOS objects,
would that be a better way of integrating CLOS and ObjC than approaches
that involve STANDARD-OBJECTs that encapsulate MACPTRs to foreign objects ?

I have to admit that I find the unified approach attractive, if only
because in every book or movie I've ever read or seen that involves
Parallel Universes, something bad invariably happens.  I can think
of a few negative aspects of the unified objects scheme:

  - in Apple's ObjC runtime, it's not possible to redefine classes.
    If ObjC classes are CLOS classes, that means that it may be
    necessary to quit and restart the lisp during development whenver
    it's necessary to add/remove an instance variable or two.

    This limitation affects the Parallel Universes approach as well,
    but it only affects the ObjC side of the universe.

  - It may be hard to support arbitrary lisp objects as slots/instance

    In the parallel scheme, the lisp object can refer to lists, symbols,
    STANDARD-OBJECTs, and other things that don't have a foreign

  - The unified scheme depends on AMOP/AHMOP functionality that doesn't
    exist and may be difficult to implement (and even harder to implement
    correctly ...);  I've thought about this some, but would want to
    think about it harder (and play around with some things) before I
    had a stronger sense of what's involved.  It's -possible- that it
    wouldn't work at all for some unanticipated reason; it'd be good
    to know whether or not the unified scheme is "tentatively Plan A" -
    on general grounds - before evaluating its feasability more carefully.

I can also think of a lot of positive aspects of the unified approach,

  - I think that schemes that people may have considered (where
    state - instance variables/slots - is maintained in parallel) are
    impractical.  Such schemes might depend migrating "dirty" objects
    to the other universe whenever the ObjC/Lisp boundary is crossed.
    If multiple threads are on different sides of that boundary,
    concurrently modifying unrelated instance variables of (different
    representations of) the "same" object, it's not clear how or when
    these modifications would ever be accurately synchonized.

    That sort of suggests that The One True Representation Of An
    Instance's State is the ObjC object, and that accessors/setters
    are used to manipulate that state (and/or that SLOT-VALUE-USING-CLASS
    needs to make an appearance, anyway.)

    (If I'm the only one who'd even considered such a scheme, please
    forgive me for pointing out the obvious.)

  - There seem to be obvious benefits in integrating foreign objects
    into the type system.

  - Perhaps it's merely a lack of vision on my part, but I'm concerned
    about the viability of schemes where CLOS starts doing more of the
    heavy lifting.  There's some handwaving involved here, but it -may-
    be possible to use the AHMOP to keep CLOS constrained at this level:
    there's no multiple inheritence where ObjC objects are involved,
    there's only a certain kind of method combination (involving an
    ObjC message send), etc.

This possibility doesn't really address some of the issues Randy raised
(what do we want a non-CLIM, higher-level CLOS interface to look like,
if indeed we want such a thing ?)  It -might- suggest what a so-called
middle layer would look like (and address issues of how ObjC objects
are represented at that level).  There are certainly other issues (even
if this unified scheme is doable, one might still want some sort of
consistent syntactic sugaring at this level to hide the gory FFI details),
but large parts of the design of this proposed middle-level are done
for us.

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

More information about the Openmcl-devel mailing list