Good morning.
If string.lisp requires a function in util.lisp,
and util.lisp requires a function in string.lisp,
what's a lad supposed to do? The mutually recursive
loads blow up the computer.
I lifted a trick from C. In pseudo-code:
FUNCTION smart-load "loadee"
IF we-have-already-loaded "loadee"
THEN dont-load
ELSE load "loadee".
In Lisp-code:
(defun smart-load (loadee)
(unless (gethash loadee *loaded*)
(setf (gethash loadee *loaded*) t)
(load loadee)))
My question: Anything wrong with that? Is this
the way real Lispniks do this?
--
Lisp kann nicht kratzen, denn Lisp ist fluessig
Uhm, I'd say it depends on what you mean by "requires a function
in...". If the function is not called during load-time (e.g. it is only
used in the bodies of functions and/or macro expansions) then the order
in which you load the files doesn't matter, since Lisp is able to deal
with forward-referenced functions. Just load them both one after the
other.
If, instead, the function is actually used when the file is loaded
(e.g. the function is called to expand a macro) then your solution has
more sense, but I think the best way is just to put the incriminated
functions in a third file and load that before the other 2. Maybe with
the help of some system definition library such as ASDF... Somebody
else might give you a better answer, though.
Madhu <·······@meer.net> writes:
> (require 'strings #p"/path/to/strings.lisp")
> ;; utilities
>
>
> With the caveat, of course, that this portable use of PROVIDE and
> REQUIRE with physical pathnames will make this non-portable...
Couldn't you get portability by using logical pathnames?
--
Thomas A. Russ, USC/Information Sciences Institute
>>>>> "Madhu" == Madhu <·······@meer.net> writes:
Madhu> * Tin Gherdanarra <···············@mid.individual.net> :
Madhu> | If string.lisp requires a function in util.lisp,
Madhu> | and util.lisp requires a function in string.lisp,
Madhu> | what's a lad supposed to do? The mutually recursive
Madhu> | loads blow up the computer.
Madhu> No such thing happens if you PROVIDE the module-name at the top of
Madhu> each file. Assuming you have taken care that functions required at
Madhu> load/compile time are available, the following should produce no
Madhu> problems.
Madhu> ;;; strings.lisp
Madhu> (provide 'strings)
Madhu> (require 'utils #p"/path/to/util.lisp")
Madhu> ;; string functions
Madhu> ;;; utils.lisp
Madhu> (provide 'utils)
Madhu> (require 'strings #p"/path/to/strings.lisp")
Madhu> ;; utilities
Madhu> With the caveat, of course, that this portable use of PROVIDE and
Madhu> REQUIRE with physical pathnames will make this non-portable...
Chris Riesback said it best [1]:
I recommend putting the provide at the end, because
* if the file fails to load completely, a provide at the front
will fool Lisp into thinking that the module has been loaded
* circular dependencies should be fixed, not supported
[1] http://www.cs.northwestern.edu/academics/courses/325/readings/require.html
regards
Roland
<···············@space.at> schrieb im Newsbeitrag ··················@space.at...
>>>>>> "Madhu" == Madhu <·······@meer.net> writes:
>
> Chris Riesback said it best [1]:
> I recommend putting the provide at the end, because
>
> * if the file fails to load completely, a provide at the front
> will fool Lisp into thinking that the module has been loaded
> * circular dependencies should be fixed, not supported
>
> [1] http://www.cs.northwestern.edu/academics/courses/325/readings/require.html
> ...
Chris Riesback seems to prefer provide/require over defsystem(/asdf). Interesting point.
What do other people think?
Andreas
>>>>> "Andreas" == Andreas Thiele <······@nospam.com> writes:
Andreas> <···············@space.at> schrieb im Newsbeitrag ··················@space.at...
>>>>>>> "Madhu" == Madhu <·······@meer.net> writes:
>>
>> Chris Riesback said it best [1]:
>> I recommend putting the provide at the end, because
>>
>> * if the file fails to load completely, a provide at the front
>> will fool Lisp into thinking that the module has been loaded
>> * circular dependencies should be fixed, not supported
>>
>> [1] http://www.cs.northwestern.edu/academics/courses/325/readings/require.html
>> ...
Andreas> Chris Riesback seems to prefer provide/require over
Andreas> defsystem(/asdf). Interesting point.
That's what I thought as well.
Andreas> What do other people think?
To some extent it is a matter of preference, but I believe that
asdf/defsystem is more powerful than provide/require, at least
I do not know how to distinguish between compiling, loading source and
loading compiled code with (ANSI) require.
Comments from the wizards would be very welcome!
regards
Roland
Madhu wrote:
> * Tin Gherdanarra <···············@mid.individual.net> :
> | If string.lisp requires a function in util.lisp,
> | and util.lisp requires a function in string.lisp,
> | what's a lad supposed to do? The mutually recursive
> | loads blow up the computer.
>
> No such thing happens if you PROVIDE the module-name at the top of
> each file. Assuming you have taken care that functions required at
> load/compile time are available, the following should produce no
> problems.
>
> ;;; strings.lisp
> (provide 'strings)
> (require 'utils #p"/path/to/util.lisp")
> ;; string functions
>
> ;;; utils.lisp
> (provide 'utils)
> (require 'strings #p"/path/to/strings.lisp")
> ;; utilities
>
>
> With the caveat, of course, that this portable use of PROVIDE and
> REQUIRE with physical pathnames will make this non-portable...
>
> -- Madhu
Thanks, this advice is infinitely excellent.
I also liked the link to Jens Riesbeck's explanation
of this, and how to handle search paths.
For the record: Putting PROVIDE last does not work
for circular references, because /before/ the provide
has opportunity to update *MODULES*, the recursion
is entered and re-entered, and PROVIDE is never
reached. Anyways, it /does/ work very well if we
put PROVIDE first. Thanks.
--
Lisp kann nicht kratzen, denn Lisp ist fluessig
"Tin Gherdanarra" <···········@gmail.com> schrieb im Newsbeitrag ····················@mid.individual.net...
> ... the recursion
> is entered and re-entered, and PROVIDE is never
> reached. Anyways, it /does/ work very well if we
> put PROVIDE first. Thanks.
> ...
I think Chris explicitely mentionend that putting provide at the end will result in an endless loop:
"Some authors recommend putting provide at the front of the file, in order to
a.. advertise up front what module the file provides, and
b.. avoid endless loops if there be any circularities (file A requires file B which requires file A) "
Andreas
Madhu <·······@meer.net> writes:
> * Tin Gherdanarra <···············@mid.individual.net> :
> | If string.lisp requires a function in util.lisp,
> | and util.lisp requires a function in string.lisp,
> | what's a lad supposed to do? The mutually recursive
> | loads blow up the computer.
>
> No such thing happens if you PROVIDE the module-name at the top of
> each file. Assuming you have taken care that functions required at
> load/compile time are available, the following should produce no
> problems.
>
> ;;; strings.lisp
> (provide 'strings)
> (require 'utils #p"/path/to/util.lisp")
> ;; string functions
>
> ;;; utils.lisp
> (provide 'utils)
> (require 'strings #p"/path/to/strings.lisp")
> ;; utilities
>
I think this can be quite dangerous. If you put the provide at the top of the
file and for some reason, the file doesn't complete loading correctly, the
system will be under the wrong assumption that the functionality has been
provided when it hasn't or has only partial functionality. This can cause
subtle problems that waste time tracking down. I also think it is hiding the
symptom of a problem rather than addressing the cause of the problem (i.e.
circular dependency).
IMO the 'provide' should be the last line in the file.
Tim
--
tcross (at) rapttech dot com dot au