Version 0.2.1 released
It’s friday, it’s five to five and it’s Crackerjack Urn update time. Well, only one of those are true but you
should still be excited. There are a couple of exciting things in this update, so let’s get cracking.
Top-level unquote
If you’ve been following the tutorials you’ll recall
that syntax-quote
and unquote
allow you to step up and down the “compilation ladder”, syntax-quote
moving from
code to data and unquote
moving back up to code. With this update, you can unquote
even further up the ladder,
allowing you to execute arbitrary code at compile time without the use of macros.
For example, say you want to have a list of the first 10 square numbers. Previously, you could define it as
(define squares (map (cut ^ <> 2) (range 1 10)))
However, this means it’ll be executed every time you run your program. This could slow it down. Instead, let’s generate these at compile time:
(define squares ,(cons `list (map (cut ^ <> 2) (range 1 10))))
This compiles to
(define squares (list 1 4 9 16 25 36 49 64 81 100))
Of course, there are far more powerful applications of this which we won’t go into here.
Property checking
Property checking is a form of testing where you can write some form of assertion and it will generate random inputs, trying to break it. For instance:
(check [(list x)]
(eq? x (reverse (reverse x))))
Will check if reversing a list twice always results in the same list. This means you can write general assertions for all inputs, rather than specific test cases. For more information, see the documentation.
Lambda-binding syntax
let
and friends (let*
, letrec
, etc…) now allow creating functions just by specifying the arguments and function
body - no lambda required!
(letrec [(factorial (x accum)
(if (= x 0)
accum
(factorial (- x 1) (* accum x))))]
(print! (factorial 3 1)))