1 Example
2 Usage
version<
version<=
version=
version>
version>=
3 Gotchas
4 Thanks
Version: 4.1.3

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. Thanks also to Ambjorn Elder for noticing a bug regarding the use of syntax-case within a version-case’s body.