For the benefit of posterity, while I haven't actually solved the
cycle-in-loading error, I was able to get the results that I wanted in this
case by:

   1. Implementing the language as a `module` (not `module*` or `module+`)
   submodule of "my-project/config.rkt", including a
   (module reader syntax/module-reader
     #:language '(submod my-project/config lang))
   2. In the body of the outer `my-project/config` module, instead of
   requiring the values from "my-project/config/local.rkt" etc. as usual,
   getting them lazily/dynamically, which I am doing with a little wrapper on
   top of `define-runtime-module-path-index`, though `racket/lazy-require`
   would probably also work well.

Evaluating the configuration files lazily was particularly good for me
because it lets me write, say, "production.rkt" assuming that various
things from the production server exist and just raising an error if not,
rather than having to make everything in every configuration file run on
every machine.

-Philip

On Mon, May 1, 2017 at 7:01 AM, Philip McGrath <phi...@philipmcgrath.com>
wrote:

> I have often done it that way, too. In this case I decided to use a #lang
> for a few reasons:
>
>    - The values for some of the parameters are not readable.
>    - In some cases I want to do a little bit of work to calculate the
>    value. For instance, "production.rkt" reads in the values of some API keys
>    from a file not tracked in the git repository.
>    - I have more than just two different configurations, e.g. for local
>    automated testing vs. interactive local use.
>    - I have some colleagues working on other aspects of the project who
>    have little to no Racket experience, but who may need to edit the
>    configuration files. Especially with syntax-parse, making a small #lang
>    gets some free IDE support and good, early error messages if e.g. they
>    enter a string where there should have been a number. (Plus, it does show
>    off how wonderful Racket is.)
>
> The #lang essentially just redefines #%module-begin so that the module
> defines and exports a function "config" (actually a struct with
> prop:procedure) that calls a thunk with the intended parameterization.
>
> Ultimately I actually found that writing a #lang was fairly comparable to
> the amount of code I would have needed to get good error reporting with the
> read-based option, so I'm pretty happy with it.
>
> Philip
>
>
>
> On Mon, May 1, 2017 at 2:59 AM, Alex Harsanyi <alexharsa...@gmail.com>
> wrote:
>
>> Hi Philip,
>>
>> I don't have an answer to your problem, but I'm curious as to what do you
>> store in "local.rkt" and "production.rkt" to justify such a complicated
>> solution.
>>
>> In the projects that I worked on (Racket or otherwise), local vs
>> production differ in the values for different parameters, which are just
>> key => value mappings.  In Racket, I would just store these as association
>> lists in "local.rktd" and "production.rktd" than in the code just to a:
>>
>>     (define config-file (if (prodution?) "production.rktd" "local.rktd"))
>>     (define config (call-with-input-file config-file read))
>>
>> Than just use `assoc` to find the values for the parameters.
>>
>> Best Regards,
>> Alex.
>>
>> On Monday, May 1, 2017 at 9:03:45 AM UTC+8, Philip McGrath wrote:
>> > I'm working on a #lang for configuration files for a larger project I'm
>> working on, and I'm trying to find a setup that meets my (largely cosmetic)
>> goals without producing a "standard-module-name-resolver: cycle in
>> loading" error.
>> >
>> >
>> > Given the following directory structure:
>> > my-project/config.rktconfig/local.rktproduction.rkt
>> > I would like both to write "local.rkt" and "production.rkt" in "#lang
>> my-project/config" and to have "(require my-project/config)" provide
>> bindings re-exported from "local.rkt" and "production.rkt" and some extra
>> bindings for working with those values.
>> >
>> >
>> > This seems like it should be doable, because there aren't any logical
>> cyclic dependencies, but I haven't found a way to convince Racket of that.
>> >
>> >
>> > I initially tried making a "my-project/config/lang/" directory with a
>> "module-lang.rkt" and a "reader.rkt" consisting of "(module reader
>> syntax/module-reader my-project/config/lang/module-language)", then
>> having "config.rkt" require and re-export "local.rkt", "production.rkt",
>> and the appropriate exports of "module-lang.rkt", but this gave me a "cycle
>> in loading" error.
>> >
>> >
>> > My first guess was that the problem might be that Racket was looking
>> for a reader submodule of "config.rkt", so I re-wrote "module-lang.rkt" and
>> "reader.rkt" as submodules of "config.rkt" (with "module", not "module*" or
>> "module+"), but this didn't solve the problem.
>> >
>> >
>> > Is there a way to do what I want?
>> >
>> >
>> > -Philip
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to