Re: Adjust + and - reader macros
HI lispworks HUG,
Apologies if this is more of a general Lisp question, but I’m having a hard time Googling for it, and at the moment the project I’ve inherited only runs in lispworks.
It is indeed a general Common Lisp questions. #+ and #- are dispatching reader macros explained in Chapter 2 of the Hyperspec.
The expression following the #+ or #- dispatching reader macros are called feature expressions.
Feature expressions are evaluated by #+ or #- using a special rule, and the contents of the list bound to the *features* variable.
The code is full of read time includes such as:
#+lispworks (do-stuff)
#+win32 (windows stuff)
#+macosx (mac stuff)
#-(or win32 macosx) (linux amiga os400 stuff stuff stuff)
For the sake of testing and debugging some stuff I’m wondering how I adjust the items that will show up or not show up from the list of items that are tested for these macros.
You can mutate the *features* variable, binding it to a new list of symbols.
However, I wouldn’t advise to remove symbols provided by the implementation.
I would expect a lot of code to break if you removed :lispworks from the *features* when running on lispworks.
That said, *features* is normally only used at read-time by #+ and #-, so the code that has already been read (either by load or compile-file), should not break if you mutate *features*.
However, it is possible that some function explicitely tests at run-time *features*…
For instance if I wanted to add “opengl” from the list of positives, or maybe even remove “lispworks”. Is there some type of global variable that holds all the environment items for these?
You wouldn’t add symbols to *features* gratuituously. The code that will test those features will expect that corresponding systems have been loaded and packages exist.
Notably, keywords being global resources, putting them on *features* should follow some global convention. Unfortunately, there’s no registry or such global convention existing.
But this list only collects the symbols put there by implementations. (and it’s incomplete and probably outdated).
A more complete list would include the feature symbols used by the various libraries, with their specific meaning in each case.
For example, ASDF version 3 puts :asdf3 there…
When I add features for my own usage, I use symbols interned in my own packages, so there’s no risk of collision.
(eval-when (:compile-toplevel :load-toplevel :execute)
(pushnew 'com.informatimago.pjb:testing *features*))
#+com.informatimago.pjb:testing (print ‘(hi! starting tests))
Alternatively, if I have to use a keyword, I would name it with a unique prefix:
(eval-when (:compile-toplevel :load-toplevel :execute)
(pushnew :com.informatimago.pjb.testing *features*))
#+com.informatimago.pjb.testing (print ‘(hi! starting tests))
Another example, would be patchwork, in which I use features to select compilation-time options, including debugging options.
This should be prominently documented in the build instructions, which is not exactly the case unfornately,
(setf *features* (set-difference *features*
'(:debug-application
:debug-event
:debug-focused-view
:debug-graphics
:debug-objc
:debug-streams
:debug-text
:debug-trace
:debug-views
:debug-views-colors
:debug-views-instance
:debug-wrapper
patchwork.builder::no-cocoa
patchwork.builder::use-apple-events
patchwork.builder::cocoa-midi-player
patchwork.builder::use-midishare
patchwork.builder::use-cl-midi)))
;; (pushnew :debug-application *features*)
;; (pushnew :debug-event *features*)
;; (pushnew :debug-focused-view *features*)
;; (pushnew :debug-graphics *features*)
;; (pushnew :debug-objc *features*)
;; (pushnew :debug-streams *features*)
;; (pushnew :debug-text *features*)
;; (pushnew :debug-trace *features*)
;; (pushnew :debug-views *features*)
;; (pushnew :debug-views-colors *features*)
;; (pushnew :debug-views-instance *features*)
;; (pushnew :debug-wrapper *features*)
;; (pushnew 'patchwork.builder::no-cocoa *features*)
;; (pushnew 'patchwork.builder::use-apple-events *features*)
;; (pushnew 'patchwork.builder::cocoa-midi-player *features*)
;; (pushnew 'patchwork.builder::use-midishare *features*)
(pushnew 'patchwork.builder::use-cl-midi *features*)
--
__Pascal J. Bourguignon__