Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
120 lines (88 sloc) 3.52 KB
#lang scribble/manual
@(require planet/scribble
(for-label racket)
(for-label (this-package-in main)))
@title{version-case: conditionally compile code based on current version number}
@author+email["Danny Yoo" "dyoo@hashcollision.org"]
@centered{@smaller{Source code can be found at:
@url{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.
@section{Example}
The following example shows how one can write unit code that works
with both the old and new @racket[unit] libraries.
@racketblock[
(module some-sample-unit-code mzscheme
(require (planet "version-case.ss" ("dyoo" "version-case.plt" 1))
(lib "mred.ss" "mred"))
;; Small test code to see that we can write unit-dependent code
;; that still runs under both 360 and 369.
(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:
@codeblock|{
#lang racket/base
(require (planet dyoo/version-case)
(for-syntax racket/base))
(printf "~a~n" (version-case [(version<= (version) "4")
'huh?]
[else
'ok]))}|
@section{Usage}
@defmodule/this-package[main]
@defform[(version-case [test code ...]
...
[else code ...])]
@racket[version-case] is a macro that expands out to one of the
@racket[code] blocks, depending on which test succeeds first. The
@racket[test] expression is evaluated at compile-time. Some
version-comparing functions are available for convenience.
@defproc[(version< [v1 string?] [v2 string?]) boolean?]{
Returns true if @racket[v1] is less than @racket[v2].
}
@defproc[(version<= [v1 string?] [v2 string?]) boolean?]{
Returns true if @racket[v1] is less than or equal to @racket[v2].
}
@defproc[(version= [v1 string?] [v2 string?]) boolean?]{
Returns true if @racket[v1] is equal to @racket[v2].
}
@defproc[(version> [v1 string?] [v2 string?]) boolean?]{
Returns true if @racket[v1] is greater than @racket[v2].
}
@defproc[(version>= [v1 string?] [v2 string?]) boolean?]{
Returns true if @racket[v1] is greater than or equal to @racket[v2].
}
@section{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, @racket[scheme/base]
doesn't automatically provide the necessary compile-time bindings, so
if you use @racket[version-case] with it, you also need to do a
@racket[(require (for-syntax scheme/base))].
@section{Thanks}
Special thanks to Carl Eastlund providing the implementation that
doesn't use @racket[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.
Something went wrong with that request. Please try again.