Liam Healy ([info]lhealy) wrote,
@ 2007-01-23 10:48:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:lisp

Conditionalizing minor system dependencies
If a system could make use of another but the usage is incidental and you don't want to break the loading of the first if the second is unavailable, it would be nicer to skip over it or provide an alternative. I have used an idiom like this:

(remove string *sf-name-mapping*
	  :key #'rest
	  :test-not
	  (if (find-package :ppcre)
	      (symbol-function (intern "ALL-MATCHES" :ppcre))
	      #'string-equal))

in a function, which says to use ppcre:all-matches if cl-ppcre is loaded, otherwise use CL's string-equal. But this is clumsy and limited in applicability. What I would like is something like #+ and #- for packages, like #+(package ppcre) which would only see the form following if that package was loaded. I don't think this is possible in portable CL, but I'm wondering if it's possible some other way. This might be done with asdf-system-connections, but it seems clumsy for the one-form case. The advantage is that the dependent code will be loaded whenever the secondary system is loaded; with a compiler conditionalization it can only happen at compile time.



(Post a new comment)


(Anonymous)
2007-01-23 07:00 pm UTC (link)
You could use the #+#./#-#. hack:

...
(defun hack:package (package-designator)
(if (find-package package-designator)
'(and)
'(or)))
...
#+#.(hack:package :ppcre) #'ppcre:all-matches
...

(Reply to this) (Thread)

Conditionalizing minor system dependencies
[info]lhealy
2007-01-23 07:30 pm UTC (link)
Indeed! Thanks. I saw this trick a while ago and forgot about it.

(Reply to this) (Parent)(Thread)

Re: Conditionalizing minor system dependencies
[info]lhealy
2007-02-03 03:32 pm UTC (link)
But there's a disadvantage to this approach: it is compile-time only. If the second package may or may not be available at run time, this way will not work. So while I am using that when appropriate, I also have defined a macro
(defmacro function-if-package
    (package-symbol function-symbol &optional otherwise)
  "Return the function in the package if the package exists, otherwise
   otherwise.  This is useful where it is desirable to take
   advantage of a function in another package if the package is loaded
   but not force the loading of it if it isn't, and to make this
   decision at run time."
  `(if (find-package ,package-symbol)
    (symbol-function (intern (string ,function-symbol) ,package-symbol))
    ',(or otherwise 'ignore-args)))

with an appropriate #'ignore-args definition. This is of course limited in its applicability (function objects only) but useful for a few cases that I have.

(Reply to this) (Parent)

testing this one...
(Anonymous)
2007-11-21 08:12 pm UTC (link)
thanks for the GREAT post! Very useful...

(Reply to this)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…