-
-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: dev workflow? #19
Comments
I don't have a great answer for this, unfortunately. My workflow for modifying components and pages is I work on those modules in isolation in the racket-mode REPL, reloading them ( You could try adding The code reloading parts of koyo initially worked by leveraging |
It looks like I misremembered how the reloading used to work. It didn't build a dependency tree of the module being reloaded. It built a tree of modules that depended on the module that changed, meaning that the struct thing might not have been a problem after all and it was only the IO issue that was giving me grief. For posterity, here's the relevant code since it was never a part of this repo: (define (build-dependents-tree mod)
(define (local? mpi)
(define-values (name _)
(module-path-index-split mpi))
(string? name))
(define (find-dependencies mod)
(for*/fold ([dependencies null])
([phase (module->imports mod)]
[dependency (cdr phase)]
#:when (local? dependency))
(cons (resolved-module-path-name (module-path-index-resolve dependency)) dependencies)))
(let loop ([dependents (hash)]
[mods (list mod)]
[seen (set)])
(match mods
[(list)
dependents]
[(list (? (curry set-member? seen)) mods ...)
(loop dependents mods seen)]
[(list mod mods ...)
(parameterize ([current-load-relative-directory (simplify-path (build-path mod 'up))])
(define dependencies (find-dependencies mod))
(define dependents*
(for/fold ([dependents dependents])
([dependency dependencies])
(hash-update dependents dependency (curry cons mod) null)))
(loop dependents* (append mods dependencies) (set-add seen mod)))])))
(define (find-dependents root mod)
(define dependents-tree
(build-dependents-tree (simplify-path root)))
(let loop ([dependents null]
[modules (list (simplify-path mod))])
(match modules
[(list)
(set->list (list->set dependents))]
[(list mod mods ...)
(define dependents* (hash-ref dependents-tree mod null))
(loop (append dependents dependents*)
(append dependents* mods))])))
(define (touch-dependents root mod)
(for ([path (find-dependents root mod)])
(file-or-directory-modify-seconds path (current-seconds)))) Every time a It may be worth experimenting with this at some point again. |
After racket/racket@14f0f86 and racket/racket@60ac39b, the |
Related to #19. Significantly improves the time it takes to reload applications after a change. Technically, this is a breaking change for the runner. Apps may need to add a `before-reload` function to their "dynamic.rkt" module and instruct libraries like deta to be more lenient.
It's been over a year, but I think 0.9 addresses the two problems you brought up:
The latter is intended as an extension of the workflow I described in my first comment on this issue. You can work on a module in isolation using the racket-mode REPL, but also bring in any instantiated dependencies that it might need by calling It's still not the load-then-redefine model of Clojure and CL, but I think Racket isn't suited to that model and with these changes in place, I think the turnaround time is quick enough that I'm happy with it. Here's a quick demo of the two changes: https://www.youtube.com/watch?v=wWj7OPvXGgA |
After koyo version 0.9: |
@AiziChen yes, that is normal. If there is an error during reload, it'll stop the application process, wait for changes and then restart it, which involves an initial compilation to amortize reload times later. If that turns out to be too annoying, it can also be improved. |
Is there a way to reload but no stop the application and recompile after a code error be correted? |
@AiziChen it's not possible right now. In general, there's a complication here, too, which is that the app needs to be recompiled in certain cases in order to work with reloading (reloading does not support module constants) and that's why koyo defaults to recompiling in those cases. Can you say more about why you would like to avoid recompilation in that case? Is it just too slow for you? Or is it something else? |
no, I just seen this feature can work on npm via 'npm run dev' , so I think it maybe support for koyo, too. I don't really need it. thanks for your answer! |
Hey Bogdan.
As I've been playing with koyo I found myself at odds with the usual way I'd write Racket code. What's the dev workflow story for koyo powered apps? I suppose this is a "function" or "compiler" vs long-running process or service development question, for which Racket approach of always restarting execution afresh feels kinda icky. If you are using Emacs with racket-mode then perhaps you find yourself in the same boat and maybe settled on a nice enough workflow?
Koyo of course takes it further than even DrRacket or racket-mode - it watches the filesystem and recompiles and restarts everything. That makes REPL pretty much redundant. Delays introduced by such recompilations and restarts are significant enough to make it annoying - computers are after all quite fast but perhaps Racket expander is still not fast enough. Where does REPL powered dev cycle fit here? How do you approach programming new "components" or adding or changing functionality of the existing ones? Adding new modules etc.
Thank you
P.S.: Also briefly touched that in greghendershott/racket-mode#472 (comment)
The text was updated successfully, but these errors were encountered: