I've been exploring Racket macros and have a question regarding performance and types.
Is there a way in Racket to achieve zero-overhead type dispatch similar to C++ templates? Specifically, I want the macro to generate different code paths based on the types of the arguments at compile-time, avoiding runtime overhead.
For example, I want to write a macro my-add that behaves like this:
;; Pseudo-code expectation
(define x : Integer 1)
(my-add x x) ;; -> expands to (fx+ x x) for performance
(define y : Float 1.0)
(my-add y y) ;; -> expands to (fl+ y y)
Can this be achieved using typed/racket alone, or do I need to dig deeper into other mechanisms?
I am aware of Turnstile , but I find its heavy reliance on Unicode symbols to be a significant engineering drawback for my workflow. I am looking for a more idiomatic or standard approach.
My understanding is that this isn’t currently something possible in Typed Racket, because Typed Racket typechecks fully-expanded programs, while type-directed dispatch requires more careful control of expansion vs. typechecking. You would need a separate #lang that implements such feature, but then the interop with Racket wouldn’t be as smooth as Typed Racket–Racket.
For some cases, TR can perform such optimizations for you.
Example: Vincent St-Amour pushed an FFT really hard in this
direction so that the standard formulation using Complex
numbers achieved the performance of a hand-rolled optimization.
He implemented an ‘optimization coach’ that provides feedback
to a programmer when an optimization got almost triggered.
In some cases, the programmer can then take corrective action
meaning a code rewrite that triggers the optimization.
As @usao points out, you cannot use macros for this purpose.
TR expands all macros before it checks types.
[[ Note though that anyone who says "zero overhead" in computing
isn't telling you the whole truth. There's no free lunch. ]]