
it’s when you make a module that imports everything from some other module and reprovides it. This lets you add information to the bindings. You do have to change code to import your wrapper module instead of the original module though.

FYI - I discovered a sizable performance penalty (~ 7x) when using curry
For example: (define is-empty? (curry char=? empty-loc))
vs. (define (is-empty? seat) (char=? empty-loc seat))
I knew curry
created a function, but I didn’t realize the runtime dispatch had such an impact. I probably stumbled upon an extreme example accidentally since the 3 functions are in an inner loop.

I guess I should look at the source for curry
because (define-syntax-rule (curry1 f a) (λ (b) (f a b)))
seems to have practically zero overhead.

Darn. I’ve been using curry
a lot (in Advent of Code) in map
s to avoid the line noise of (lambda (seat) (char=? empty-loc)
.

Racket BC or CS?

I’m on BC 7.5

@badkins You might want to use Sam’s fancy-app
for that instead

@badkins (check for contracts…)

no contracts! - said in the voice of Edna Mode

On this test: #lang racket/base
(require fancy-app
(only-in racket/function curry)
data/enumerate
data/enumerate/lib)
(define empty-loc #\L)
(define is-empty1? (curry char=? empty-loc))
(define is-empty2? (char=? empty-loc _))
(define (is-empty3? c) (char=? empty-loc c))
(define (gc!)
(collect-garbage)
(collect-garbage)
(collect-garbage))
(define chars
(for/list ([i (in-range 1000000)])
(from-nat char/e i)))
(gc!)
(displayln "w/ curry")
(time
(for ([c (in-list chars)])
(is-empty1? c)))
(gc!)
(displayln "w/ fancy-app")
(time
(for ([c (in-list chars)])
(is-empty2? c)))
(gc!)
(displayln "plain")
(time
(for ([c (in-list chars)])
(is-empty3? c)))
I get the following: w/ curry
cpu time: 95 real time: 95 gc time: 1
w/ fancy-app
cpu time: 8 real time: 9 gc time: 0
plain
cpu time: 7 real time: 8 gc time: 0

That’s on 7.9 BC. On CS (I don’t have 7.9 CS, but I imagine the numbers for other recent versions are representative anyway), the curry version is considerably faster than under BC but still much slower than the others.

Cool - thx!

Does anyone have a good way of building a Racket app in Docker without pulling in a ton of extra stuff?

I think a combination of manual installation of dependencies and —force may work…

ah like, making an app that has only the result of raco distribute
instead of the whole compiler toolchain?

Yeah. I guess I could do a raco distribute
build and then do a multistage doohickey.

One thing brings in racket-doc
and then everything gets explodey

That’s what I tend to do:
https://github.com/MarcKaufmann/congame/blob/90bc0402729626ea7e32eb5b1d36769f7b28f76f/Dockerfile
(raco koyo dist
is just raco exe
+ raco distribute
)

Yep. I just ended up trying that and it looks much better.


Edna would have said: “No no contracts!”

@sorawee I noticed that you had some PR’s in lispyville; might I ask whether you’re all in on lispy, or just using the lispyville hooks?

Honestly, I forget already what lispy & lispyville do lolol. I also think I use them incorrectly and very inefficiently (mostly for paren balancing and comment edit)

This is my lispy(ville) config: https://github.com/sorawee/.doom.d/blob/master/lispy.el

I do use lispyville-like movement a lot, but the one provided by lispyville is buggy, so I create my own.


It didn’t occur to me that it’d be a bit tricky to generate immutable bindings when using match
patterns for all binding forms…

sorry about that spam

Today I learned that primitive forms (e.g. module
, begin-for-syntax
, &c.) do not count as being bound to syntax.

What do you mean by that?

The result of (syntax-local-value #'module)
is an error that says that module
is not bound to syntax.