[Openmcl-devel] #$ equivalent?

Gary Byers gb at clozure.com
Tue Dec 28 03:59:26 UTC 2004

On Sun, 26 Dec 2004, John Wiseman wrote:

> What would be the functional equivalent of the #$ reader macro?
> Something like (ccl::load-os-constant sym)?  (Of course this would
> only be equivalent for symbols, not for short string constants).
> The reason I'm wondering is because LispWorks seems to have trouble
> even reading forms protected by #+openmcl:
>    CL-USER 2 > (read-from-string "#+openmcl (defun foo () #$EINTR)")
>    Error: Subcharacter #\$ not defined for dispatch char #\#.
>  From the description of *read-suppress* in the CLHS, it seems that
> LispWorks' behavior should not be surprising (right?).
> If LispWorks can't be blamed, I suppose it would be nice if all the
> reader macros had exported functional equivalents.  Or should I just
> be using #.(read-from-string "#$EINTR")?
> Thanks,
> John Wiseman

What #$ does (and, more-or-less, what  #_ and #?, do) is:

a) read a token from the input stream with READTABLE-CASE set to
   :preserve and *PACKAGE* bound to the value of (FIND-PACKAGE "OS").

b) generally, get upset if (a) didn't produce a symbol (#$ allows strings).

   CCL::%LOAD-VAR) with the symbol as an argument.  Just to make
   things more confusing, CCL::LOAD-OS-CONSTANT accepts and ignores
   an optional second argument, CCL::LOAD-EXTERNAL-FUNCTION requires
   and ignores a second argument, and CCL::%LOAD-VAR accepts only
   the symbol argument.  (I would say "hey, I didn't write this",
   but I did, I think ...)

d) returns the symbol (which may have been given a constant, macro,
   or symbol-macro definition in step (c)).

Procedurally, that'd be something like:

(progn (ccl::load-os-constant 'os::|EINTR|) ; escaping not required here,
        os::|EINTR|)                        ;  but may be required in general

but you probably don't want to do that in a loop.

The least-ugly way that I can think of doing this is to do something like:

;;; Near the top of a file
(eval-when (:compile-toplevel :execute)	; at least
  (ccl::load-os-constant 'os::|EINTR|)
  ;;; Maybe load other constants, vars, functions here


(defun do-something (x y)
  (if (= (foo x y) #+openmcl os:|EINTR| #-openmcl ...)
     (error "System call was interrupted!  Why doesn't the OS
             restart it ?")))

Whether that's more or less ugly than the alternatives is probably in
the eye of the beholder.

More information about the Openmcl-devel mailing list