[Openmcl-devel] More confusion about cocoa constants

Gary Byers gb at clozure.com
Fri Jul 10 10:52:26 PDT 2009


As a very general rule of thumb, NSStrings (and possibly other
kinds of NSObjects) are "variables", even if their value is
never intended to change (they may be declared with the "const"
attribute in ObjC): they're references to particular, unique
instances of some ObjC class.  Numbers and (possibly) C strings -
where object identity (EQness) either doesn't apply or doesn't
matter - are generally "constants", and it's confusing that 
the ObjC documentation refers to both types of things as "constants".

I haven't thought this through too carefully and there may be
problems that I'm not thinking of, but it's not clear that 
we couldn't make at least one of #$ or #& handle both kinds
of constructs and hide those confusing details.  The #$ reader
macro currently does something like:

  1) read a symbol from the input stream, preserving case and interning
     the symbol in the "OS" package.

  2) try to find a constant value associated with that (C) symbol in
     the open "constants.cdb" interface files.  If unsuccessful, complain;
     if successful, do something like

(defconstant OS::foo 17)

     and if no constant value can be found, complain.

  3) return the symbol

The #& reader macro does some similar things, only in step 2 it looks
in the the "vars.cdb" files for information about the variable's type;
if that information's found, then DEFINE-SYMBOL-MACRO is used to give
the variable a global symbol-macro definition, something like:

(define-symbol-macro OS::FOO (some-expression-which-does-a-typed-memory-reference))

It's not clear why we don't change #$'s behavior (for instance) to look
for variable type info if the search for a constant value failed, which
would mean that one could say:

#$kCAGravityCenter  even though "kCAGravityCenter" is a particular NSString
and not constant in exactly the same way that #$SEEK_SET (= 0) is.

When #$ an #& were first introduced, the distinction between "constants"
and "variables" in most uses was (or at least seemed) clearer, so it seemed
reasonable to use different reader macros.  This whole issue is confusing
enough to have a FAQ entry, and the best solutions so far are "try to 
find the header file" or "if #$ doesn't work, try #&, or vice versa", neither
of which is ideal.

On Fri, 10 Jul 2009, R. Matthew Emerson wrote:

>
> On Jul 10, 2009, at 12:47 PM, Neil Baylis wrote:
>



>> In addition to the problem I previously mentioned re #
>> $kCAGravityCenter at compile time, I'm running into other difficulties
>> with constants. Is there something more I need to do other than
>> loading the framework?
>>
>> This is a session from the IDE listener window:
>>
>> Welcome to Clozure Common Lisp Version 1.4-dev-r12363M-trunk
>> (DarwinX8664)!
>> CL-USER> (objc:load-framework "QuartzCore" :quartzcore)
>> NIL
>> CL-USER> #$kCAGravityCenter
>>> Error: Constant not found: X86-DARWIN64::|kCAGravityCenter|
>>> While executing: CCL::LOAD-OS-CONSTANT, in process Listener(6).
>>> Type cmd-. to abort, cmd-\ for a list of available restarts.
>>> Type :? for other options.
>> CL-USER> #&kCAGravityCenter
>> #<NS-MUTABLE-STRING "center" (#x7FFF704F3AC0)>
>> CL-USER> #$kCAConstraintMidx
>>> Error: Constant not found: X86-DARWIN64::|kCAConstraintMidx|
>>> While executing: CCL::LOAD-OS-CONSTANT, in process Listener(6).
>>> Type cmd-. to abort, cmd-\ for a list of available restarts.
>>> Type :? for other options.
>> CL-USER> #&kCAConstraintMidx
>>> Error: Foreign variable "kCAConstraintMidx" not found
>>> While executing: CCL::%LOAD-VAR, in process Listener(6).
>>> Type cmd-. to abort, cmd-\ for a list of available restarts.
>>> Type :? for other options.
>> CL-USER>  #$NSBackingStoreBuffered
>> 2
>> CL-USER>
>>
>> It's very confusing trying to find the correct syntax for init forms.
>> How do I know beforehand whether to use the #$ or #& prefix for a
>> constant? It seems very unintuitive.
>
> Unfortunately, you just have to look it up in the documentation or
> header files.  Sometimes the "constants" are real numeric constants,
> and sometimes they're NSString instances.
>
> http://trac.clozure.com/openmcl/wiki/FrequentlyAskedQuestions#Objective-CBridge
>
>
>> Why is kCAGravityCenter defined,
>> but kCAConstraintMidx is not, when they are both from the same
>> framework? (They are defined in different header files).
>
> You used a lower-case "x" in kCAConstraintMidX.
>
> Welcome to Clozure Common Lisp Version 1.4-dev-r12394M-trunk
> (DarwinX8664)!
> ? (objc:load-framework "Quartz" :quartz)
> NIL
> ? #$kCAConstraintMidX
> 1
>
> As for compiling your file, you want an eval-when in there instead of
> a bare top-level form:
>
> (eval-when (:compile-toplevel :load-toplevel :execute)
>   (objc:load-framework "QuartzCore" :quartzcore))
>
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>



More information about the Openmcl-devel mailing list