chibi-scheme
chibi-scheme copied to clipboard
Search path for included files
If a top-level program includes a file "folder/A.scm" and "A.scm" itself
includes "B.scm", Chibi Scheme currently searches for "B.scm" in the same paths
where "folder/A.scm" was searched. It does not necessarily search for "B.scm"
in "folder/".
The Scheme report says in 4.1.7 that "implementations are encouraged to search
for files in the directory which contains the including file", so I propose
that Chibi Scheme adds the folder of the including file to the search path for
included files. This is very helpful when includes are used to modularize
source code (instead of library declarations).
An edge case could be the following: File A includes file B containing a macro.
In its macro expansion file B inserts code like (include "C.scm") and some code
provided by the caller. Assume A uses this macro and provides the code (include
"D.scm").
Where should "C.scm" and "D.scm" be searched for? I'd say, "C.scm" should be
searched relative to the folder containing B and "D.scm" relative to the folder
containing A.
Original issue reported on code.google.com by [email protected]
on 5 Mar 2015 at 1:23
You're not the first to request this. The problem is, that typically you want
to install top-level programs, and if you use include then you need to
remember to install the included files along with and relative to the program,
even though they aren't themselves binaries. This is both ugly and prone
to error, so I discourage it, and thus deliberately leave program-level
include semantics broken.
I'll think about this some more though.
Original comment by [email protected]
on 9 Mar 2015 at 4:19
- Changed state: Accepted
Excuse me for resurrecting this issue, but I have run into it again. You write that program-level includes should be discouraged and so it is possibly not a bad thing that the include semantics is left broken.
This is reasonable (as long as there is no mechanism to install included files reliably). However, include is also broken for libraries: When a library x.sld includes its implementation x,scm, everything is fine, but when x.scm further wants to include y.scm it does not look in x.scm's (and x.sld's) current directory for y.scm.
I see no reasons why include should be left broken for this scenario (and quite a few reasons why this scenario is reasonable).
@ashinn
You don't need this at all for libraries - you can (and should) just include y.scm directly from x.sld. I could imagine a scenario where you want to include y.scm from multiple libraries. In this case they'd each include it. If you really wanted to "bundle" x.scm and y.scm, keeping y.scm separate, you could make x.scm a library declarations file and x.sld would (include-library-declarations "x.scm"). This is guaranteed to statically resolve the search path correctly.
Because we have include-library-declarations the only real use case is for programs, which as explained is discouraged. However, this idiom happens to be very convenient for things like file inclusion in the .stub files expanded by chibi-ffi. Mostly for that sake I'll reconsider changing this.
I don't see how include-library-declaration covers all use cases. Let me describe two use cases:
- Say, we are going to write an interpreter for a programming language, e.g. Scheme's
eval
. The interpretereval
will first create a dynamic environmentenvironment
and this environment will have to be passed down to the functions actually implementing the semantics of the programming language, e.g.eval-reference
oreval-application
, and so on.
If there are a lot of these functions, the program may become more readable if one does not have to pass environment
explicitly when these functions mutually call each other. This can be achieved in two ways: by dynamically binding environment
using parameter objects or by lexically binding environment
using closures. The former solution has the disadvantage that parameter objects likely have a runtime overhead in implementations. The latter solution has the disadvantage that all helper functions like eval-reference
and eval-application
have to be lexically nested in the eval
function that defines environment
. If there are many of them, a large continuous chunk of the program will be indented and the body of eval
will be separated from the header of eval
by that large chunk.
Obviously, if one could reliably include files, all the functions eval-reference
, eval-application
and so on could simply be included in the right nested lexical context.
- Assume we want to have a way for statically including the implementations of libraries. One way would be to replace the
<body>
of a library by(library <name> . <body>)
. Depending on the library declarations,(library <name> . <body>)
could then either expand simply into<body>
or into code that somehow stores the datum<body>
under the name<name>
. So by switching the definition oflibrary
, we can either access the actual library or its implementation (as a datum). This poses no problem as two library declarations (differing in the implementation oflibrary
they import) can reliably include the same library file. However, the actual body of the library has to be wrapped in thelibrary
form. This causes unwanted indentation of the whole library body and doesn't make the library body portable without providing an implementation oflibrary
.