On this page:
7.6.1 Using set! to Assign to Variables Provided via provide/ contract
Version: 4.1

7.6 Gotchas

7.6.1 Using set! to Assign to Variables Provided via provide/contract

The contract library assumes that variables exported via provide/contract are not assigned to, but does not enforce it. Accordingly, if you try to set! those variables, you may be surprised. Consider the following example:

  > (module server scheme

      (define (inc-x!) (set! x (+ x 1)))

      (define x 0)

      (provide/contract [inc-x! (-> void?)]

                        [x integer?]))

  > (module client scheme

      (require 'server)

    

      (define (print-latest) (printf "x is ~s\n" x))

    

      (print-latest)

      (inc-x!)

      (print-latest))

  > (require 'client)

  x is 0

  x is 0

Both calls to print-latest print 0, even though the value of x has been incremented (and the change is visible inside the module x).

To work around this, export accessor functions, rather than exporting the variable directly, like this:

  #lang scheme

  

  (define (get-x) x)

  (define (inc-x!) (set! x (+ x 1)))

  (define x 0)

  (provide/contract [inc-x! (-> void?)]

                    [get-x (-> integer?)])

This is a bug we hope to address in a future release.