[racket] Dynamic module loading

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Fri Jan 31 07:35:09 EST 2014

Hi Evan,

Your alias file is like a function with the type (-> Void) because it
is run only for its effect and its effect is only to "add", which
makes it impossible to "subtract". One way to solve this is to change
its type to (-> Hash) so that it returns what the hash should be. For
instance,

(define alias-ht (make-hash)) ;; common.rkt
(for (...) (hash-set! alias-ht ...)) ;; user-input.rkt
(dynamic-rerequire "user-input.rkt") ;; server.rkt
(hash-ref alias-ht ...) ;; server.rkt

is like what you have. But you could change it to

(define alias-ht (for/hash (...) ...)) ;; user-input.rkt
(define alias-ht (make-hash)) ;; server.rkt
 ;; server.rkt
(begin (dynamic-rerequire "user-input.rkt")
           (set! alias-ht (dynamic-require "user-input.rkt" 'alias-ht)))
(hash-ref alias-ht ...) ;; server.rkt

so that after you attempt to reload, then you pull out the 'alias-ht
value from either the new or old version of the module

Jay


On Fri, Jan 31, 2014 at 3:37 AM, Evan Donahue <emdonahu at gmail.com> wrote:
> Hello. I've been trying to get a particular use case for module loading to
> work, and, while I have a mostly functional solution, I am unsure whether I
> am using the best infrastructure for the task. The explanation is a bit
> involved, but the basic question is what is the right way to update a
> running system using values generated by racket code (update as in feed new
> data to, not reload the module bindings of).
>
> I have a text-based game client that needs to be able to dynamically load
> user-defined aliases while running. Ordinarily this could be solved by
> simply reading a file of alias definitions and updating the structure in
> memory. However, as the alias system may potentially be quite complex, I was
> hoping to use both the racket language and module system to define these
> aliases. Ie, I might have inventory-aliases.rkt, which requires
> item-aliases.rkt in order to reuse helper code defined in the latter in the
> former.
>
> My current solution involves having all alias code as well as the main
> program require a common base.rkt that provides a single aliases #hash. Each
> alias file, when loaded, destructively sets all its aliases into the hash,
> which are in turn usable by the main program.
>
> When a user updates an alias file, I dynamic-rerequire the file, which,
> since the hash set!s are idempotent, mostly works. The trouble is that if a
> user deletes an alias, I do not know to get rid of it in my hash structure.
> Moreover, I cannot throw out the hash because dynamic-rerequire only reruns
> changed modules.
>
> Before I continue on down this rabbit hole and start adjusting timestamps to
> have dynamic-rerequire do what I need it to do, I wanted to ask whether
> there was a more canonical way to achieve my ends. I get the impression that
> I am somewhat hijacking the module system since I am mostly using it to
> structure the alias code, but then am trying to extract something that is
> not quite an exported set of values from it. Would it make sense perhaps to
> construct an evaluator out of the alias definitions and evaluate user inputs
> in that language? I am not intimately familiar with the module system, and
> so am doing a bit of a random walk around its infrastructure as I learn more
> about it.
>
> I sense this question may be a bit obscure, so thank you in advance to
> anyone who has any insights to share on the matter.
>
> Evan
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.