[Openmcl-devel] Import Question
gb at clozure.com
Fri Dec 15 02:30:20 EST 2006
IIRC, CCL::MAKE-NS-POINT is just a magic pseudofunction that can only
appear inside an SLET. It's not a real function or macro, though
it might be possible to have SLET macroexpand into something that
defined it via MACROLET or FLET or something.
This all has to do with C "structure return and assignement"
conventions. A C function that "returns a structure" doesn't
really do so in the sense that Lisp functions return values.
In C or ObjC, you might see a code fragment like:
NSPoint p; /* reserve space for a point on the stack */
p = NSMakePoint(x,y); /* Initialize the fields of .. the result */
If NSMakePoint was a real function - I think that it's actually defined
as an inline function in the Cocoa header files and doesn't exist in
any library - it would be implemented as if it took an invisible first
argument of type "pointer to NSPoint", something like:
NSMakePoint(NSPoint *result,float x, float y)
result->x = x;
result->y = y;
and the "assignment" to p compiles to something like:
This is extremely concise, extremely convenient, and extremely
SLET is an attempt to lispify this a little; it tries to combine the
allocation of a foreign structure instance with "assignment" to that
foreign structure. It magically recognizes a few "structure-returning"
forms and can recognize message sends that (pretend to) "return"
structures. It works, and has essentially the same characteristices
(all three of 'em) as the C conventions it's trying to mirror.
Randall Beer and I were (and I think still are) generally interested
in the general idea of "making Cocoa easier to use by hiding ObjC
ugliness", and I think that we convinced ourselves that part of
that would be to bury the C structure-returning stuff at some
level that people would hopefully rarely have to deal with. A
message or function that was defined to "return a structure"
would in fact return a (lisp) structure, messages/functions that
accepted a structure argument would accept a lisp structure, and
the bridge would handle mapping between lisp structures and foreign
structures according to an extensible set of rules. We were also
talking (in the same timeframe) about the notion of replacing
SEND with generic functions and replacing DEFINE-OBJC-METHOD
with DEFMETHOD, and Randall was able to get some of this working.
We both ran out of time/funding around that time, and the other
problems that the ObjC bridge was experiencing at that time
(extreme sensitivity to minor changes in library versions,
slow/imprecise parsing of encoded ObjC type information, a few
other related things) also needed to be addressed. When I got
around to trying to address them, I managed to break Randall's
generic-function and structure-coercion code. It's still there -
conditionalized out in objc-clos.lisp - and the conditionalizd-out
code includes the definition of NS-MAKE-POINT that you're seeing.
I still think that moving away from SEND and SLET towards generic
functions and lisp structures is the right thing and have been
planning on un-breaking Randall's code - which was basically
working or very close to it - for over a year now.
On Thu, 14 Dec 2006, Brent Fulgham wrote:
> I've done a "(require 'cocoa)" in a program, which I can see loads
> the "examples/objc-clos" file. But when I attempt to use anything
> from the file I get an error:
> ;;; From ccl/examples/objc-clos.lisp:
> (defstruct (ns-point (:constructor make-ns-point (x y)))
> (defun ns-make-point (x y)
> (make-ns-point (coerce x 'single-float) (coerce y 'single-float)))
> If I load the routines:
> ;Loading #P"openmcl/compat.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/cocoa.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/fake-cfbundle-
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-support.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/bridge.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-runtime.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/library/splay-tree.lisp"...
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/name-
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/process-objc-
> ;Loading #P"/opt/local/share/openmcl/1.1/examples/objc-clos.lisp"...
> [ ... ]
> Welcome to OpenMCL Version 1.1-pre-061110 (DarwinPPC32)!
> ? (ccl::ns-make-point 0.1 0.2)
> > Error: Undefined function CCL::NS-MAKE-POINT called with arguments
> (0.1 0.2) .
> > While executing: CCL::TOPLEVEL-EVAL, in process Listener(4).
> > Type :GO to continue, :POP to abort, :R for a list of available
> > If continued: Retry applying CCL::NS-MAKE-POINT to (0.1 0.2).
> > Type :? for other options.
> I don't see any 'package declarations that would help me figure out
> if these things are exported. I'm sure this has an obvious answer,
> but I'm not seeing what I'm doing wrong...
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
More information about the Openmcl-devel