So is the requirement to read a list of symbols from a config file and use them as the mapping to the underlying modules? <br><br>Correct me if I am wrong, but doesn't planet already solve this problem? It helps define packages which are referred via symbols. The changes to files are localized within the package, and if you have a main.ss that require and provide the underlying modules, it acts as the config.ss for other modules requiring the package. Versioning and network download/install are built-in as well. <br>
<br>And cce/system/planet appears to solve the self referencing problem within a single package - <a href="http://blog.plt-scheme.org/2009/03/maintaining-self-references-in-planet.html">http://blog.plt-scheme.org/2009/03/maintaining-self-references-in-planet.html</a><br>
<br>The only thing lacking is that there are no private planet repositories for now. <br><br>Perhaps I misunderstood the goal here - please let me know if I missed something. <br><br>Cheers,<br>yc<br><br><div class="gmail_quote">
On Sat, Oct 3, 2009 at 1:15 PM, Eli Barzilay <span dir="ltr"><<a href="mailto:eli@barzilay.org">eli@barzilay.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
An issue that came up recently with David -- and one that comes up<br>
every once in a while, is that of some project management tools. A<br>
summary of the problem is: you have some layout of files in your<br>
project, and you want to be able to access them using in some symbolic<br>
way. Using strings as relative names works to a limited degree: it<br>
means that the hierarchy is inflexible -- changing it requires<br>
changing files too. Also, the paths depend on both the requiring<br>
module and the required one, usually you'll need a number of "../"s<br>
that depends on the requiring file, and a then the path of the<br>
required file.<br>
<br>
Now that we have require/provide forms, it is possible to solve this<br>
problem, and in typed-scheme Sam did something very similar to that,<br>
which makes it a nice use case. Here's an example from one of Sam's<br>
files:<br>
<br>
(require (except-in "../utils/utils.ss" extend))<br>
(require (types convenience utils union subtype)<br>
(rep type-rep)<br>
(utils tc-utils)<br>
"signatures.ss" "constraint-structs.ss"<br>
scheme/match)<br>
<br>
When this came up with David, I pointed at all the obvious places that<br>
can be used to make it work, and then I continued to see if I can come<br>
up with some way to provide more convenient ways to dealing with such<br>
issues. What I came up with is two require forms that I think would<br>
do this job nicely:<br>
<br>
* (file-in <expr>) -- this is close to `file', except that <expr> is<br>
an arbitrary expression (evaluated at the syntax phase, of course).<br>
It is similar to `filtered-in' (and uses the same<br>
`scheme/private/at-syntax' hack) in that you write some code. Using<br>
the typed scheme snip as an example -- it would make writing those<br>
`types' and `rep' forms easy. (With a minor point: as they are in<br>
this example, they would need to be macros, since their arguments<br>
are not quoted.)<br>
<br>
Also, it would be possible to have functions that consult some<br>
"configuration file" which defines the project layout (with the<br>
trivial case of the configuration file being some scheme module that<br>
is required for-syntax), require files relative to your home<br>
directory, the contents of an environment variable, the desktop<br>
directory, etc, and it could even do some cheap networking thing<br>
like downloading a file and then requiring it.<br>
<br>
In other words, it does a job similar to Sam's `define-requirer',<br>
except that it does so more generally, since you're using functions.<br>
It's a little more verbose since you need the `file-in' wrapper --<br>
but the advantage is that plain code is easier to write and would be<br>
readable to more people. (For example, if you're looking at some<br>
random file in typed scheme, you won't know what it's supposed to<br>
do.)<br>
<br>
This solves one side of the problem -- organizing code with such a<br>
symbolic approach is becoming much easier. But the other side of this<br>
problem is that you'd want to centralize such code, and you need to<br>
reach that central point conveniently from everywhere in your project.<br>
Going back to the typed scheme snippet, this is the<br>
"../utils/utils.ss" part. This string still depends on the location<br>
of the central configuration file wrt the project root. I'm not sure<br>
what would be the best solution -- the best thing I can think of is:<br>
<br>
* (file-up <string>) -- searches for a path in this directory, then<br>
going up. If there was some `or-in' form, then (file-up "foo/z.ss")<br>
this would be similar to:<br>
<br>
(or-in "foo/z.ss" "../foo/z.ss" "../../foo/z.ss" ...etc...)<br>
<br>
With this, Sam's code could use (file-up "utils/utils.ss").<br>
<br>
Combining these two, and assuming that they're provided by<br>
`scheme/require', a typical "project management" code chunk could look<br>
like:<br>
<br>
(require scheme/require<br>
(file-up "config.ss")<br>
(file-in the-foo-utility<br>
(subsystem1 'blah)<br>
(subsystem2 'sheep/goes/meh)))<br>
<br>
where the "config.ss" file provides (for syntax) the definitions for<br>
the subsystem functions and the first value. (One tricky bit: the<br>
order of the three require clauses is important.)<br>
<br>
One point that Matthew raised when I talked to him about this is that<br>
it can lead to a mess if the functions that you're using in `file-in'<br>
are non-deterministic. This problem is already in now, of course, the<br>
only thing that changes is how easy you can get to it. But given the<br>
utility of these forms (in contexts that make this pop up every once<br>
in a while), I think it should generally be fine -- as long as the<br>
documentation has the right warnings, as well as some boilerplate code<br>
that most people will just copy and modify.<br>
<br>
So, are there any opinions on this? Or on the specific forms?<br>
<br>
Also, I'm not sure about the names. The `file-in' vs `file' (vs<br>
`file-up') seems like it can be confusing, so maybe `path-in' and<br>
`path-up' would work better? Another alternative is to have a<br>
*function* that does the up-search, and provide it for syntax, with a<br>
use-case like:<br>
<br>
(require scheme/require<br>
(file-in (look-up "config.ss"))<br>
(file-in the-foo-utility<br>
(subsystem1 'blah)<br>
(subsystem2 'sheep/goes/meh)))<br>
<br>
but this seems like it can be much more confusing. Another option is<br>
some `file-in-up' which combines the two features (expects an<br>
expression, and does the search with the result) -- this seems to me<br>
like cramping too much functionality into a single tool.<br>
<br>
Yet another option is have `file-in' be some `#%app'-like thing, so<br>
the above code becomes:<br>
<br>
(require scheme/require<br>
(file-up "config.ss")<br>
(file-in the-foo-utility)<br>
(file-in subsystem1 'blah)<br>
(file-in subsystem2 'sheep/goes/meh))<br>
<font color="#888888"><br>
--<br>
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:<br>
<a href="http://barzilay.org/" target="_blank">http://barzilay.org/</a> Maze is Life!<br>
_________________________________________________<br>
For list-related administrative tasks:<br>
<a href="http://list.cs.brown.edu/mailman/listinfo/plt-dev" target="_blank">http://list.cs.brown.edu/mailman/listinfo/plt-dev</a><br>
</font></blockquote></div><br>