Just getting into Common Lisp and was wondering if there is a way to set the
search path for load? Specifically I want to be able to search multible
directories with a single call to load.
Thanks in Advance
In article <····················@newssvr12.news.prodigy.net>,
sj <·······@swbell.net> wrote:
> Just getting into Common Lisp and was wondering if there is a way to set the
> search path for load? Specifically I want to be able to search multible
> directories with a single call to load.
>
> Thanks in Advance
LOAD takes a pathname not a 'search path'.
Your implementation might support something like that
together with REQUIRE or a system facility.
Other than that write it yourself. In the great tradition of untested
and unfinished code on c.l.l ;-) :
(defparameter *directories-to-search* (list ... ))
(defun my-load-using-directories (name &optional (dirs *directories-to-search*))
(loop for dir in dirs
for file = (merge-pathname name dir)
for file-exists = (probe-file file)
when file-exists do (load file)
unless file-exists))
--
http://lispm.dyndns.org
Rainer Joswig <······@lisp.de> wrote:
+---------------
| Other than that write it yourself. In the great tradition of untested
| and unfinished code on c.l.l ;-) :
| (defparameter *directories-to-search* (list ... ))
| (defun my-load-using-directories (name
| &optional (dirs *directories-to-search*))
| (loop for dir in dirs
| for file = (merge-pathname name dir)
| for file-exists = (probe-file file)
| when file-exists do (load file)
| unless file-exists))
+--------------
Minor correctness & style quibbles[1]:
0. MERGE-PATHNAMES, not MERGE-PATHNAME.
1. The final UNLESS clause is missing a "selectable-clause" after
the test form. You probably meant to use UNTIL instead.
2. UNTIL would be correct, but that style of LOOP termination might
be a bit obscure. I would suggest this instead, which also has
the advantage of returning a potentially-useful value from LOAD:
(defun my-load-using-directories (name
&optional (dirs *directories-to-search*))
(loop for dir in dirs
for file = (merge-pathnames name dir)
for file-exists = (probe-file file)
when file-exists
do (return (load file))))
And that version, now *very* lightly tested, does seem to work:
> *directories-to-search*
("home:" "home:tmp/" "home:src/try/")
> (my-load-using-directories "foo")
; Loading #P"/u/rpw3/tmp/foo".
hello, world!
T
>
-Rob
[1] In the great tradition of quibbling about untested and
unfinished code on c.l.lisp. ;-)
[2] And in the equally great tradition of generalizing tiny CL examples
to their maximal -- dare I say, overblown?!? -- generality, I offer
this additional version: ;-} ;-}
> (defun my-load-using-directories (name
&rest rest
&key (directory-list
*directories-to-search*)
&allow-other-keys)
(loop for dir in directory-list
for file = (merge-pathnames name dir)
for file-exists = (probe-file file)
when file-exists
do (return (apply #'load file :allow-other-keys t rest))))
MY-LOAD-USING-DIRECTORIES
> (my-load-using-directories "foo" :verbose nil :print t)
hello, world!
; NIL
; (EXPT 2 100)
; =
; 1267650600228229401496703205376
T
>
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
····@rpw3.org (Rob Warnock) writes:
> for file-exists = (probe-file file)
> when file-exists
> do (return (apply #'load file :allow-other-keys t rest))))
And why not get rid of "file-exists"? Just write
when (probe-file file)
unless you think the meaning of probe-file is lost in the contraction.
--
Steven E. Harris
Steven E. Harris <···@panix.com> wrote:
+---------------
| ····@rpw3.org (Rob Warnock) writes:
| > for file-exists = (probe-file file)
| > when file-exists
| > do (return (apply #'load file :allow-other-keys t rest))))
|
| And why not get rid of "file-exists"? Just write
| when (probe-file file)
| unless you think the meaning of probe-file is lost in the contraction.
+---------------
Nope, just didn't think of it. [It wasn't "wrong", like
some of my other corrections, so I just left it alone.]
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
Thanks for all the replies. I ended up taking a slightly different approach
factoring out load from the directory search code. I also added a list of
possible file extensions so the algorithm will match "foo" to both "foo"
and "foo.lisp" or whatever extension is desired.
(defvar *load-directory-list* '())
(defun add-load-directory (dir)
(pushnew dir *load-directory-list* :test #'equal))
(add-load-directory "home/sj/src/lisp")
(add-load-directory "home/sj/src/lisp/sjutil")
(add-load-directory "home/sj/src/lisp/sjutil/foo")
(defvar *load-type-list* '())
(defun add-load-type (ext)
(pushnew ext *load-type-list* :test #'equal))
(add-load-type nil)
(add-load-type "lisp")
;; Return pathname of first matching file on search directory
;; list. If no match return nil.
;;
(defun which-file (name &key (dirs *load-directory-list*)
(extension-list *load-type-list*))
(loop for dir in (reverse dirs) do
(loop for e in (reverse extension-list)
for pathname = (make-pathname :directory dir
:name name
:type e)
for file-exist = (probe-file pathname)
when file-exist do
(return-from which-file pathname)))
nil)
-- Steven Jones
sj <·······@swbell.net> wrote:
+---------------
| Thanks for all the replies. I ended up taking a slightly different
| approach factoring out load from the directory search code. I also
| added a list of possible file extensions so the algorithm will match
| "foo" to both "foo" and "foo.lisp" or whatever extension is desired.
+---------------
I think you need to make it be a tiny bit smarter than this.
For example, on an x86 platform when you ask CMUCL to (LOAD "foo"),
it first tries "foo", then "foo.x86f" [its extension for hard-
ompiled code on x86], then "foo.lbytef" [its extension for
byte-compiled code on LittleEndian machines], then "foo.fasl"
[the generic extension for compiled code], then finally "foo.lisp",
"foo.l", "foo.cl", and "foo.lsp", in that order.
Plus, by default, if you have both a compiled version [e.g.,
"foo.x86f"] and a source version [e.g., "foo.lisp"] and the
latter is newer than the former, it will warn you [but load
the older binary version anyway]:
cmu> (load "foo")
Warning: Loading object file /u/rpw3/foo.x86f,
which is older than the presumed source:
/u/rpw3/foo.lisp.
; Loading #P"/u/rpw3/foo.x86f".
Hi! My name is #P"/u/rpw3/foo.x86f".
T
cmu>
You can override this and get very useful behavior by specifying
the non-standard :IF-SOURCE-NEWER keyword with the :COMPILE option,
like this:
cmu> (load "foo" :if-source-newer :compile)
; Python version 1.1, VM version Intel x86 on 14 AUG 07 12:47:55 am.
; Compiling: /u/rpw3/foo.lisp 14 AUG 07 12:47:51 am
; Byte Compiling Top-Level Form:
; foo.x86f written.
; Compilation finished in 0:00:00.
; Loading #P"/u/rpw3/foo.x86f".
Hi! My name is #P"/u/rpw3/foo.x86f".
T
cmu>
Do it again, and it doesn't recompile, of course:
cmu> (load "foo" :if-source-newer :compile)
; Loading #P"/u/rpw3/foo.x86f".
Hi! My name is #P"/u/rpw3/foo.x86f".
T
cmu>
Whichever implementation of CL you're using will likely have
similar behavior regarding defaulting file types and possibly
similar extensions builtin, so you want to make sure your
WHICH-FILE is at *least* as smart as your implementation's
builtins w.r.t. source vs. binary, and also modification dates.
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
In article <·····················@newssvr14.news.prodigy.net>,
sj <·······@swbell.net> wrote:
> Thanks for all the replies. I ended up taking a slightly different approach
> factoring out load from the directory search code. I also added a list of
> possible file extensions so the algorithm will match "foo" to both "foo"
> and "foo.lisp" or whatever extension is desired.
>
>
> (defvar *load-directory-list* '())
>
> (defun add-load-directory (dir)
> (pushnew dir *load-directory-list* :test #'equal))
>
>
> (add-load-directory "home/sj/src/lisp")
> (add-load-directory "home/sj/src/lisp/sjutil")
> (add-load-directory "home/sj/src/lisp/sjutil/foo")
>
>
>
> (defvar *load-type-list* '())
>
> (defun add-load-type (ext)
> (pushnew ext *load-type-list* :test #'equal))
>
>
> (add-load-type nil)
> (add-load-type "lisp")
>
>
>
> ;; Return pathname of first matching file on search directory
> ;; list. If no match return nil.
> ;;
> (defun which-file (name &key (dirs *load-directory-list*)
> (extension-list *load-type-list*))
> (loop for dir in (reverse dirs) do
> (loop for e in (reverse extension-list)
> for pathname = (make-pathname :directory dir
> :name name
> :type e)
> for file-exist = (probe-file pathname)
> when file-exist do
> (return-from which-file pathname)))
> nil)
>
>
> -- Steven Jones
>
>
Just a minor note. Common Lisp supports comments
in functions. Any self-respecting IDE will use those.
LispWorks: m-c-sh-a on a symbol shows the function documentation.
Zmacs: c-sh-d.
SLIME seems to have no command?
SLIME and LispWorks highlights them as strings, which is definitely
better than nothing - it should highlight them
as comments, though.
(defun which-file (name &key (dirs *load-directory-list*)
(extension-list *load-type-list*))
"Return pathname of first matching file on search directory
list. If no match return nil."
;; gdfgdf
(loop for dir in (reverse dirs) do
(loop for e in (reverse extension-list)
for pathname = (make-pathname :directory dir
:name name
:type e)
for file-exist = (probe-file pathname)
for foo = "dfkghdfkghdkf"
when file-exist do
(return-from which-file pathname))))
In article <································@speakeasy.net>,
····@rpw3.org (Rob Warnock) wrote:
> Rainer Joswig <······@lisp.de> wrote:
> +---------------
> | Other than that write it yourself. In the great tradition of untested
> | and unfinished code on c.l.l ;-) :
> | (defparameter *directories-to-search* (list ... ))
> | (defun my-load-using-directories (name
> | &optional (dirs *directories-to-search*))
> | (loop for dir in dirs
> | for file = (merge-pathname name dir)
> | for file-exists = (probe-file file)
> | when file-exists do (load file)
> | unless file-exists))
> +--------------
>
> Minor correctness & style quibbles[1]:
>
> 0. MERGE-PATHNAMES, not MERGE-PATHNAME.
>
> 1. The final UNLESS clause is missing a "selectable-clause" after
> the test form. You probably meant to use UNTIL instead.
>
> 2. UNTIL would be correct, but that style of LOOP termination might
> be a bit obscure. I would suggest this instead, which also has
> the advantage of returning a potentially-useful value from LOAD:
>
> (defun my-load-using-directories (name
> &optional (dirs *directories-to-search*))
> (loop for dir in dirs
> for file = (merge-pathnames name dir)
> for file-exists = (probe-file file)
> when file-exists
> do (return (load file))))
>
> And that version, now *very* lightly tested, does seem to work:
>
> > *directories-to-search*
>
> ("home:" "home:tmp/" "home:src/try/")
> > (my-load-using-directories "foo")
>
> ; Loading #P"/u/rpw3/tmp/foo".
> hello, world!
> T
> >
>
> -Rob
>
> [1] In the great tradition of quibbling about untested and
> unfinished code on c.l.lisp. ;-)
Thanks, Rob!
>
> [2] And in the equally great tradition of generalizing tiny CL examples
> to their maximal -- dare I say, overblown?!? -- generality, I offer
> this additional version: ;-} ;-}
>
> > (defun my-load-using-directories (name
> &rest rest
> &key (directory-list
> *directories-to-search*)
> &allow-other-keys)
> (loop for dir in directory-list
> for file = (merge-pathnames name dir)
> for file-exists = (probe-file file)
> when file-exists
> do (return (apply #'load file :allow-other-keys t rest))))
>
> MY-LOAD-USING-DIRECTORIES
> > (my-load-using-directories "foo" :verbose nil :print t)
>
> hello, world!
> ; NIL
> ; (EXPT 2 100)
> ; =
> ; 1267650600228229401496703205376
> T
> >
>
> -----
> Rob Warnock <····@rpw3.org>
> 627 26th Avenue <URL:http://rpw3.org/>
> San Mateo, CA 94403 (650)572-2607
--
http://lispm.dyndns.org