version-case: conditionally compile code based on current version number
This library provides support for conditionally compiling code based on the version of PLT Scheme. 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")))])) |
Another simple example:
(module another-example scheme/base |
(require (planet dyoo/version-case) |
(for-syntax scheme/base)) |
(printf "~a~n" (version-case [(version<= (version) "4") |
'huh?] |
[else |
'ok]))) |
2 Usage
(version-case [test code ...] |
... |
[else code ...]) |
version-case is a macro that expands out to one of the code blocks, depending on which test succeeds first. The test expression is evaluated at compile-time. Some version-comparing functions are available for convenience.
(version< v1 v2) → boolean? |
v1 : string? |
v2 : string? |
Returns true if v1 is less than v2.
(version<= v1 v2) → boolean? |
v1 : string? |
v2 : string? |
Returns true if v1 is less than or equal to v2.
(version= v1 v2) → boolean? |
v1 : string? |
v2 : string? |
Returns true if v1 is equal to v2.
(version> v1 v2) → boolean? |
v1 : string? |
v2 : string? |
Returns true if v1 is greater than v2.
(version>= v1 v2) → boolean? |
v1 : string? |
v2 : string? |
Returns true if v1 is greater than or equal to v2.
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.