Re: [racket-users] Re: #lang languages and cyclic dependencies

2017-11-28 Thread Jack Firth
Huh, I must have missed this the first time around. I've run into this sort 
of thing multiple times before and it usually brings me to this question:

What if the configuration file was the main module of your app, instead of 
something imported by your app?

Think about it. The "my-project/config/local" and 
"my-project/config/production" modules are essentially saying "to run the 
app locally, set the project config to these values". What module could 
possibly have a use for that information other than the main "app startup" 
module? It seems like all other code should only depend on modules that 
define the *schema *of configuration, rather than any modules that set that 
configuration to specific values. It seems odd for the schema definition 
module (my-project/config) to depend on modules that actually use that 
schema to set config values (my-project/config/local). The reverse sounds 
more sensible.

If you make a module written in `#lang my-project/config` expand to a 
`main` submodule that starts up your app you get some other neat Rackety 
things to show off to your colleagues: not only will they get an IDE with 
syntax highlighting and good error messages "for free",  pressing the Run 
button with a config file open will launch the app automatically! This 
might not work if launching your app is especially complicated, but I'm 
curious if you've explored this direction and what your thoughts are.

On Tuesday, November 28, 2017 at 1:28:06 PM UTC-8, Philip McGrath wrote:
>
> 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
>

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


Re: [racket-users] Re: #lang languages and cyclic dependencies

2017-11-28 Thread Philip McGrath
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 
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 
> 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, se

Re: [racket-users] Re: #lang languages and cyclic dependencies

2017-05-01 Thread Philip McGrath
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 
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.


[racket-users] Re: #lang languages and cyclic dependencies

2017-05-01 Thread Alex Harsanyi
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.