version-case: conditionally compile code based on current version number
Danny Yoo <dyoo@hashcollision.org>
Source code can be found at: https://github.com/dyoo/version-case.
This library provides support for conditionally compiling code based on the version of Racket. One common application of this module is to write compatibility bindings.
1 Example
The following example shows how one can write unit code that works with both the old and new unit libraries.
(module some-sample-unit-code mzscheme (require (planet "version-case.ss" ("dyoo" "version-case.plt" 1)) (lib "mred.ss" "mred")) (version-case [(version<= (version) "360") (printf "old unit code~n") (require (lib "tool.ss" "drscheme") (lib "unitsig.ss")) (define tool@ (unit/sig drscheme:tool-exports^ (import drscheme:tool^) (define (phase1) (message-box "phase1")) (define (phase2) (message-box "phase2"))))] [else (printf "new unit code~n") (require (lib "tool.ss" "drscheme") (lib "unit.ss")) (define-unit tool@ (import drscheme:tool^) (export drscheme:tool-exports^) (define (phase1) (message-box "phase1")) (define (phase2) (message-box "phase2")))]))
#lang racket/base (require (planet dyoo/version-case) (for-syntax racket/base)) (printf "~a~n" (version-case [(version<= (version) "4") 'huh?] [else 'ok]))
2 Usage
|
3 Gotchas
The tests are done at compile time. If the language of your module doesn’t include compile-time bindings for function application, you may see funny error messages. For example, scheme/base doesn’t automatically provide the necessary compile-time bindings, so if you use version-case with it, you also need to do a (require (for-syntax scheme/base)).
4 Thanks
Special thanks to Carl Eastlund providing the implementation that doesn’t use eval, and for feedback. Thanks also to Ambjorn Elder for noticing a bug regarding the use of syntax-case within a version-case’s body.