chibi-scheme icon indicating copy to clipboard operation
chibi-scheme copied to clipboard

Search path for included files

Open GoogleCodeExporter opened this issue 9 years ago • 5 comments

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

GoogleCodeExporter avatar Mar 16 '15 12:03 GoogleCodeExporter

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

GoogleCodeExporter avatar Mar 16 '15 12:03 GoogleCodeExporter

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).

mnieper avatar Jan 05 '16 21:01 mnieper

@ashinn

mnieper avatar Jan 06 '16 08:01 mnieper

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.

ashinn avatar Jan 06 '16 15:01 ashinn

I don't see how include-library-declaration covers all use cases. Let me describe two use cases:

  1. Say, we are going to write an interpreter for a programming language, e.g. Scheme's eval. The interpreter eval will first create a dynamic environment environment and this environment will have to be passed down to the functions actually implementing the semantics of the programming language, e.g. eval-reference or eval-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.

  1. 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 of library, 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 of library they import) can reliably include the same library file. However, the actual body of the library has to be wrapped in the library form. This causes unwanted indentation of the whole library body and doesn't make the library body portable without providing an implementation of library.

mnieper avatar Jan 06 '16 16:01 mnieper