Christopher William Bowron <········@tarsal.cse.msu.edu> writes:
> (cond
> ((string-equal "CMU Common Lisp" (lisp-implementation-type))
> (defun getenv (var)
> (cdr (assoc (intern var :keyword) *environment-list*))))
> ((string-equal "CLISP" (lisp-implementation-type))
> (defun getenv (var)
> (system::getenv var)))
> (t
> (error "Unknown LISP Implementation")))
The above code is not portable. Especially if you try to introduce
other implementations. The above works only because both CMUCL and
CLISP have a "SYSTEM" package, which is not mandated by the standard,
*and* you are USE(ing)-PACKAGE the "EXTENSION" package in CMUCL. The
following is portable, thanks to the read time conditionals.
#+cmu
(defun getenv (var)
(cdr (assoc (intern var :keyword) *environment-list*))))
#+clisp
(defun getenv (var)
(system::getenv var)))
In alternative you can separate these functions in separate files like
impl-dependent/cmucl.lisp
impl-dependent/clisp.lisp
With each function in each file. If you want a rather general
machinery to achieve these effects (always using the "separate files approach")
you can look at CL-ENVIRONMENT in the CLOCC (the CVS version is more
up to date.)
Cheers
--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.
Marco Antoniotti <·······@cs.nyu.edu> writes:
> Christopher William Bowron <········@tarsal.cse.msu.edu> writes:
>
> > (cond
> > ((string-equal "CMU Common Lisp" (lisp-implementation-type))
> > (defun getenv (var)
> > (cdr (assoc (intern var :keyword) *environment-list*))))
> > ((string-equal "CLISP" (lisp-implementation-type))
> > (defun getenv (var)
> > (system::getenv var)))
> > (t
> > (error "Unknown LISP Implementation")))
>
> The above code is not portable. Especially if you try to introduce
> other implementations. The above works only because both CMUCL and
> CLISP have a "SYSTEM" package, which is not mandated by the standard,
> *and* you are USE(ing)-PACKAGE the "EXTENSION" package in CMUCL.
Yeah, you could repair it with (funcall (intern "GETENV" "SYSTEM") var),
of course, but that would be slow. ;-)
> The
> following is portable, thanks to the read time conditionals.
>
> #+cmu
> (defun getenv (var)
> (cdr (assoc (intern var :keyword) *environment-list*))))
>
> #+clisp
> (defun getenv (var)
> (system::getenv var)))
Yes, this is better.
>
> In alternative you can separate these functions in separate files like [...]
Yes, this is also better.
Yet another alternative is:
(defun getenv (var)
(funcall (or #+cmu #'(lambda (var)
(cdr (assoc (intern var :keyword)
*environment-list*)))
#+clisp #'(lambda (var) (system::getenv var))
#'(lambda (var)
(declare (ignore var))
(error "~S is not implemented." 'getenv)))))
This has the advantage of making a sort of "else" clause for feature
fallthrough for a common bug: Doing
(defun getenv (var)
#+cmu (cdr (assoc (intern var :keyword) *environment-list*))
#+clisp (system::getenv var)
#-(or cmu clisp)
(progn var ;ignored
(error "~S is not implemented." 'getenv)))
also works but risks that if you add more features, you'll forget to update
the #-(or cmu clisp) pattern to match and get things out of line.