<div dir="ltr">It just struck me that my alias lang is structured a lot like #lang datalog (accumulating assertions into a hidden theory). Sure enough, datalog seems, on first glance, to handle some of the issues I'm facing. At the risk of jynxing it, I think datalog can probably show me the rest of the way.<br>
<br>Thanks.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 4, 2014 at 11:22 PM, Evan Donahue <span dir="ltr"><<a href="mailto:emdonahu@gmail.com" target="_blank">emdonahu@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div>Thanks for the response. The dynamic-require + rerequire seems to handle that issue, and with the addition of some module-begin code I have successfully hidden the construction of the hash from the end user. There is just one more item on my desiderata that seems to be stumping me, the general statement of which is: how do I preserve provide/require functionality when defining a new #lang<br>

<br></div>I have structured my module-begin after the fashion of fudging up a racket. Specifically, in my lang file:<br><br></div><div>(provide alias)<br><br></div><div>(define aliases (make-parameter #f))<br></div><div>
<br>
</div><div>(define-syntax-rules (alias a b)<br></div><div>   (hash-set! (aliases/param) 'a 'b)))<br></div><div><br>#`(#%plain-module-begin <br>        (provide aliases)<br>        (define aliases (make-hash))<br>
        (parameterize ([aliases/param aliases])<br>
          body ...))<br><br><br></div><div>This works great for one module, but should I like to require additional modules in my alias file to help with alias construction (or provide things defined in one alias file to another), I end up with an expansion like<br>

<br></div><div>(parameterize ([...])<br></div><div>   (require ...<br><br>and receive the error "require not at module level"<br><br></div><div>My question, then, is what might be a better way to structure a lang ifle + module-begin to preserve require/provide functionality while also achieving the encapsulation of state achieved in the fudging up a racket tutorial?<br>

<br>Thank you,<br>Evan<br></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jan 31, 2014 at 4:35 AM, Jay McCarthy <span dir="ltr"><<a href="mailto:jay.mccarthy@gmail.com" target="_blank">jay.mccarthy@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Evan,<br>
<br>
Your alias file is like a function with the type (-> Void) because it<br>
is run only for its effect and its effect is only to "add", which<br>
makes it impossible to "subtract". One way to solve this is to change<br>
its type to (-> Hash) so that it returns what the hash should be. For<br>
instance,<br>
<br>
(define alias-ht (make-hash)) ;; common.rkt<br>
(for (...) (hash-set! alias-ht ...)) ;; user-input.rkt<br>
(dynamic-rerequire "user-input.rkt") ;; server.rkt<br>
(hash-ref alias-ht ...) ;; server.rkt<br>
<br>
is like what you have. But you could change it to<br>
<br>
(define alias-ht (for/hash (...) ...)) ;; user-input.rkt<br>
(define alias-ht (make-hash)) ;; server.rkt<br>
 ;; server.rkt<br>
(begin (dynamic-rerequire "user-input.rkt")<br>
           (set! alias-ht (dynamic-require "user-input.rkt" 'alias-ht)))<br>
(hash-ref alias-ht ...) ;; server.rkt<br>
<br>
so that after you attempt to reload, then you pull out the 'alias-ht<br>
value from either the new or old version of the module<br>
<br>
Jay<br>
<div><div><br>
<br>
On Fri, Jan 31, 2014 at 3:37 AM, Evan Donahue <<a href="mailto:emdonahu@gmail.com" target="_blank">emdonahu@gmail.com</a>> wrote:<br>
> Hello. I've been trying to get a particular use case for module loading to<br>
> work, and, while I have a mostly functional solution, I am unsure whether I<br>
> am using the best infrastructure for the task. The explanation is a bit<br>
> involved, but the basic question is what is the right way to update a<br>
> running system using values generated by racket code (update as in feed new<br>
> data to, not reload the module bindings of).<br>
><br>
> I have a text-based game client that needs to be able to dynamically load<br>
> user-defined aliases while running. Ordinarily this could be solved by<br>
> simply reading a file of alias definitions and updating the structure in<br>
> memory. However, as the alias system may potentially be quite complex, I was<br>
> hoping to use both the racket language and module system to define these<br>
> aliases. Ie, I might have inventory-aliases.rkt, which requires<br>
> item-aliases.rkt in order to reuse helper code defined in the latter in the<br>
> former.<br>
><br>
> My current solution involves having all alias code as well as the main<br>
> program require a common base.rkt that provides a single aliases #hash. Each<br>
> alias file, when loaded, destructively sets all its aliases into the hash,<br>
> which are in turn usable by the main program.<br>
><br>
> When a user updates an alias file, I dynamic-rerequire the file, which,<br>
> since the hash set!s are idempotent, mostly works. The trouble is that if a<br>
> user deletes an alias, I do not know to get rid of it in my hash structure.<br>
> Moreover, I cannot throw out the hash because dynamic-rerequire only reruns<br>
> changed modules.<br>
><br>
> Before I continue on down this rabbit hole and start adjusting timestamps to<br>
> have dynamic-rerequire do what I need it to do, I wanted to ask whether<br>
> there was a more canonical way to achieve my ends. I get the impression that<br>
> I am somewhat hijacking the module system since I am mostly using it to<br>
> structure the alias code, but then am trying to extract something that is<br>
> not quite an exported set of values from it. Would it make sense perhaps to<br>
> construct an evaluator out of the alias definitions and evaluate user inputs<br>
> in that language? I am not intimately familiar with the module system, and<br>
> so am doing a bit of a random walk around its infrastructure as I learn more<br>
> about it.<br>
><br>
> I sense this question may be a bit obscure, so thank you in advance to<br>
> anyone who has any insights to share on the matter.<br>
><br>
> Evan<br>
><br>
</div></div>> ____________________<br>
>   Racket Users list:<br>
>   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
><br>
<span><font color="#888888"><br>
<br>
<br>
--<br>
Jay McCarthy <<a href="mailto:jay@cs.byu.edu" target="_blank">jay@cs.byu.edu</a>><br>
Assistant Professor / Brigham Young University<br>
<a href="http://faculty.cs.byu.edu/~jay" target="_blank">http://faculty.cs.byu.edu/~jay</a><br>
<br>
"The glory of God is Intelligence" - D&C 93<br>
</font></span></blockquote></div><br></div>
</div></div></blockquote></div><br></div>