Posts tagged Racket
Yesterday a couple people asked me, “How and why do you use macros in a Lisp like Racket or Clojure?”.
I gave answers like:
Although all true, I wasn’t sure I was getting the full idea across.
This is an overview of things I’ve created using Racket. Two motivations for writing this now:
Over the last week I was at three conferences (whew!) where, when meeting or catching up with someone, I had to explain what I’ve been doing. I mentioned my current projects or projects I guessed they’d relate to. But that’s not necessarily representative of all that I’ve been able to do with Racket. I wish I’d been able to give a better overview. I have quite a few repos on GitHub, but that’s just a big list with no structure.
In about a week I start my batch at Hacker School. I’ll likely spend less time with Racket, because the whole point is to learn new things. Now is a good time to take inventory. And I’ll be better prepared to talk about Racket there.
As a result, here’s an inventory, grouped into categories.
Let’s say you need to destructure a list with
match, using a pattern that specifies a “rest” or “more” element. Be careful. You probably want to use
Most of my Racket projects don’t use a makefile. Why would they?
raco setup suffices.
But a makefile can consistently define some common project tasks. And it can really help when you want to generate HTML documentation from Scribble sources, and publish it to GitHub Pages using the automagical
Many languages have a variable (or preprocessor macro) called
__file__ whose value is the pathname of the current source file. Likewise
__LINE__ for the the source line number.
You probably need this less in Racket than you imagine. For example:
We wouldn’t test that
__FILE__ ends in
main.rkt; instead we’d use a
(module+ main <your code here>).
To get a data file
foo.dat located in the same directory as a source file we’d use
(define-runtime-path foo.dat "foo.dat"). If we’re a package or executable this works regardless of where our files happen to get installed.
But if you really did need a
__FILE__ in Racket, how would you do it?
Let’s say we want to use
find-collects-dir, which was added in Racket 6.0. We get a bug report from someone using Racket 5.3.6.
To fix this, we can
dynamic-require the desired function; when it doesn’t exist, we can use our own fallback implementation.1
Two parallel thoughts:
I haven’t blogged in awhile. I’ve been heads-down on a few projects. Plus I haven’t had ideas I feel are “big” or unique enough to merit a post.
It’s occurred to me that a “Racket Cookbook” might be a useful resource. Because examples. Because real-life, practical examples.1
Although I haven’t created a cookbook, my working assumption is that it would be better to write one recipe at a time. As they arise. As I think, “Ah right, this wasn’t obvious to me when I was learning Racket.”
So I plan to experiment with releasing the things one at a time, as short blog posts. Thereby terminating two avian organisms with one geologic projectile.
Not sure if I’ll keep it up. Definitely not sure if I’ll ever collect and polish them into a “book” of some form. They might only ever live as a
racket-cookbook tag on this blog.
In my previous post, I wrote about a nuance with
syntax/loc, using the example of a macro that both
provides a function. But why don’t I back up, and look at a simpler example of why you’d want to use
syntax/loc. The example is a simple macro you might often find yourself wanting, to reduce the tedium of writing unit test cases.
There’s a nuance to
syntax/loc. The documentation says, emphasis mine:
syntax, except that the immediate resulting syntax object takes its source-location information from the result of stx-expr (which must produce a syntax object), unless the template is just a pattern variable, or both the source and position of stx-expr are
What does “immediate” mean here?
Racket’s new package manager is great. It debuted with Racket 5.3.5. Although officially still in beta, it was already good enough to use for real projects. Racket developers wanted people to use it for real projects, to get the experience needed to make it even better.
Over many months, the Git
HEAD version of Racket — what would become Racket 6 — gradually introduced a few new and changed features for package management.
However, you might not want to use the newer features, yet. Not if you want your package to be usable by people still using Racket 5.3.5 or 5.3.6 — or usable by other packages that wish to support such people.
Fortunately, the older features are still supported in Racket 6, and it’s not very difficult or inconvenient to use them. You just need to know what they are.