Fallback when required function not available
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
The basic recipe:
1 2 3 4 5 6 |
(define (our-fallback ....) ....) (define desired-function (dynamic-require 'collection/path 'desired-function (thunk our-fallback))) |
Here (thunk x)
is just shorthand for (lambda () x)
.
A simple but full example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#lang racket/base ;; find-collects-dir was added in Racket 6.0. (provide find-collects-dir) (require racket/list racket/function racket/path) (define (our-find-collects-dir) (apply build-path (reverse (cdr (reverse (explode-path (collection-path "racket"))))))) (define find-collects-dir (dynamic-require 'setup/dirs 'find-collects-dir (thunk our-find-collects-dir))) |
Let’s say this is in a file find-collects-dir.rkt
. Then elsewhere in our program instead of (require setup/dirs)
we do (require
"find-collects-dir.rkt")
.
Now our program uses Racket’s find-collects-dir
when running on Racket 6.0 or newer, otherwise it falls back to using our own implementation.
Season with parsley. Serves many.
-
Of course another approach is to only use our own implementation, even in newer versions of Racket. Sometimes that would be simpler. However the “official” function might someday change in beneficial ways. Also, someday we might decide to stop supporting an older Racket version, in which case it’s cleaner to discard this scaffolding and adjust the
require
s to use the “official” function directly. ↩