What is the difference betwen these two usage of parameterize: 1. #lang racket
(define p (make-parameter #f))
(parameterize ([p 3])
(printf "p=~a\n" (p)))
;; p=3
2. #lang racket
(define p (make-parameter #f))
(p 2)
(printf "p=~a\n" (p))
;; p=2
Is the 2nd one just a convenient way of 1st one for module scope?
Guide seems only mentioned the 1st one.
So (parameterize ([p 3]) ...)
is “temporarily set p to 3”. And (p 3)
“set p to 3” [and keep using that value for p].
Thanks @soegaard2!
A racket-mode question: I found that racket-mode [f5] - racket-run launches large codebases very slow. I have set (setq racket-error-context 'low)
, but no help. However, DrRacket can launch very fast, because I set the Dyanmic Properties “No debugging or profiling”. Is there the same settings in racket-mode?
@greg
The default run is similar to “No debugging or profiling”.
But I have set (setq racket-error-context 'low)
.
That I don’t know about.
Note: try raco setup large-project
in the terminal to make sure everything is compiled.
Is there way to inspect the setting “No debugging or profiling” in REPL?
To see the current setting in the repl?
Yes.
I don’t think so.
raco setup large-project
What does it do? I cant search this command in racket docs.
It compiles all files in large-project
.
I found that racket-mode never creates compiled
folder in my project, but DrRacket creates it.
Yes. racket-mode works differently. Only DrRacket creates compiled
.
Oh… i guess that is why racket-mode is slow. BTW, even if I use DrRacket to create the compiled folder, racket-mode won’t be aware of it.
No, it just don’t use a "compiled’ subfolder.
When you start racket-mode a “backend” (a racket program) is started. I believe the backend keeps track of modules it has seen.
If racket-mode isn’t aware of the compiled
folder, each time it will recompile in other temporary folder? Or just interpret mode?
Ask Greg for details.
“Only DrRacket creates compiled
” is not true, I think: raco setup
and/or racket
do too, I believe (based on ad-hoc observations)
Doesn’t DrRacket use a different compiled subdirectory name than the one used by command-line Racket and other things like Racket Mode?
Yes. DrRacket uses compiled/drracket
I think DrRacket does this because it automatically populates it — the checkbox a few lines down from the one circled in that screen cap — and wants to avoid interfering with people doing the normal thing of running raco make
(directly or via raco setup
) if/when they choose to do so.
Racket Mode isn’t trying to be as automatic as DrRacket in this regard. However, if you manually raco make
, which puts compiled files in the the standard compiled
subdirectory, Racket Mode will use those to load faster. (Because the standard Racket loader looks there, and Racket Mode (like command-line Racket) just uses the standard loader.)
TL;DR in this regard Racket Mode works like command-line Racket, not DrRacket.
@greg You are right. After using raco make
, racket-mode run as fast as DrRacket with “No debugging or profiling”. raco make
also create compiled
folders, but it seems a bit different from what DrRacket created, i.e. racket-mode is only aware of the compiled
folders created by raco make
, but not DrRacket, although they are both called complied
.
Maybe racket-mode could add a new command something like racket-run-with-compile
.
I opened compiled
folder. Yes, DrRacket only creates .dep and .zo in the drracket
subfolder, so they are different.
A quick impl: (defun racket-run-module-at-point-with-compile ()
(interactive)
(let* ((racket (executable-find racket-program))
(rkt (racket--buffer-file-name) )
(command (format "%s -l raco make -v %s"
(shell-quote-wildcard-pattern racket)
(shell-quote-wildcard-pattern rkt))))
(shell-command command)
(racket-run-module-at-point)))
Stolen from racket-mode-start-faster
in racket-mode.el
.
That’s a possibility.
My assumption so far has been: When people have quite large projects, they already have some strategy for byte-compiling if/as/when they want to. If the project is a package, maybe they raco setup <pkg>
. Maybe they have a Makefile
and run raco make
on certain *.rkt
files. Or some other strategy.
So mostly I’ve just tried to stay out of the way, with Racket Mode.
Based on issues and feature requests (or lack thereof) to-date, I think that’s been mostly what people have wanted, so far?
Note that raco make
-ing an individual .rkt
file that you’re able to run doesn’t really save any time. It gets compiled on-demand, in memory, automatically by the Racket loader, anyway.
The benefits come from byte-compiling other files that the .rkt
file require
s.
So if you’re heavily editing one specific .rkt
file, and running it, repeatedly, that file probably need not be byte compiled.
I updated shell-quote-wildcard-pattern
, it is still need shell-quote-wildcard-pattern
, otherwise in windows Emacs will complain c:/Program
problem. I think the racket-run-module-at-point-with-compile
is suitable for debugging large codebase (but no makefile). For small program, it is not necessary.
> Note that raco make-ing an individual .rkt file that you’re able to run doesn’t really save any time. @greg It definitely can save time (I have tried). Because if you only modify individual files, raco will only compile those modified files without recompiling all the files.
I mean including the time spent raco make
-ing the file. :slightly_smiling_face:
raco make a-individual.rkt
can automatically compile all the files which a-individual.rkt
depends on.
raco make
only spend time in first time.
Then you have decompiled
folder, so if you only modify small piece of code, the 2nd time compiling will be fast.
If you don’t use raco make
, the 2nd time will spend as much time as the first (because it re-compiles in memory, maybe…).
If you’re not editing the file, and the .zo
file isn’t outdated, you’re right it could save time.
compiled
(or also compiled/drracket
) is a cache, with the usual pros and cons of caches
Slightly off-topic, and you probably already know this, but: Most of the time is the equivalent of raco expand
.
Even if I editing some individual files, it could still save a lot of time. Because I found that Racket seemly supports separate compilation. It only compiles those outdated files.
In Racket BC, the .zo
is byte code, not even machine code, that’s JITed quite quickly.
For CS it’s native code.
But either way, the time really depends on how long expansion takes, and that usually means how “macro heavy” the code and it’s dependents are.
So e.g. a large project using Typed Racket, you’ll feel the pain more.
But even a pretty large project that doesn’t heavily use macros, you might not even byte compiling at all and it’s just fine.
It really depends.
Yes. My codebase heavily uses macros.
The Racket back end part of Racket Mode? I routinely use that all the time with zero .zo
files and it’s fine. I don’t bother raco make
-ing. In fact doing so is a drawback when I’m switching among various versions of Racket while testing. I don’t want .zo file mismatch errors.
Whereas your project it’s definitely a must-have, it sounds like.
So again that’s why I’ve just tried to stay out of the way with Racket Mode and let people handle the raco make/setup
aspect however they need/want.
By the way, I think you can get the effect of this: https://racket.slack.com/archives/C09L257PY/p1647789026350859?thread_ts=1647771384.054519&cid=C09L257PY
By adding a function to racket-before-run-hook
.
The edit buffer is current when this is called, you can use racket--buffer-file-name
there.
And this will work for all flavors of the run command.
(Someone could also add a hook to do e.g. make compile
if they have a Makefile
set up to compile certain files, or whatever else.)
So I think that’s the existing self-service option for this, today, if that works for you @chansey97?
@greg Thanks. I use your solution because it is more flexible.
We can use var
directly in template? #lang racket
(require syntax/parse (for-syntax syntax/parse racket))
(define-syntax (define-var stx)
(syntax-parse stx
[(_ var:id x)
#'(define var x)])) ; <---- only var? not var:id?
(define-var foo 1)
What is difference from #lang racket
(require syntax/parse (for-syntax syntax/parse racket))
(define-syntax (define-var stx)
(syntax-parse stx
[(_ var:id x)
#'(define var:id x)])) ; <---- var:id
(define-var foo 1)
What is the id
mean? The https://docs.racket-lang.org/syntax/Parsing_Syntax.html\|docs doesn’t say anything about :id
.
See syntax classes in the syntax-parse documentations
Read https://docs.racket-lang.org/syntax/stxparse-intro.html in particular.
The pattern var:id
means match only identifiers - and bind to var
.
Thanks!
var:id
is essentially a shorthand of {~var var id}
BTW, I think it is better to rename compiled
to _compiled
. The compiled
folder looks a little weird, because it is on the same level as normal source folders. (Just a suggestion).
I guess it’s one of these things where if you have ever written the formal definition you realise the generality of the concept. In my mind flatten
was only about flattening trees, i realised only recently that it flattens pairs too— even though the docs are pretty explicit on this matter actually.
At that point it could be hidden on *nix (.compiled
)
It’s not just pattern-matching, right? The order matters when passing arguments to the constructor. Personally, in order to reserve the ability to change details like the order of the fields, I don’t export the constructor; I define another function (and match expander) that looks like the constructor without technically being a struct-constructor-procedure?
, and I export that.