Reputation: 379
the module: test-define.rkt
#lang racket
(provide test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
the main program:act.rkt
#lang racket
(require "test-define.rkt")
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test)
run the act.rkt, I get:
0
1
this is what I want.
But if I change the contract in test-define.rkt:
(provide test)
change to
(provide (contract-out [test integer?]))
then I run the act.rkt again, I get:
0
0
Why? I can't change the test value.
If I provide a get func, it turns normal again.
(provide (contract-out [get-test (-> integer?)]))
(define (get-test)
test)
If test's type change to hash map, it's always normal.
What I missed?
Upvotes: 3
Views: 245
Reputation: 31147
I notice that in test-define.rkt you have this line
(set! test3 (add1 test))
Should test3
be test
?
This might explain why you saw that two zeros (test never changed).
EDIT 2
For convenience I put your two modules in the same file and changed the contract of test:
#lang racket
(module test-define racket
(provide test)
; (provide (contract-out [test integer?]))
(provide get-test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
(define (get-test)
test))
(module ack racket
(require (submod ".." test-define))
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test))
(require (submod "." ack))
Now I see the 0 1 vs 0 0 output as you do.
Hmmm. Why?
Well. If we change the provide forms to use no contracts at all, the output is 0 1.
Adding a contract shouldn't change this behaviour (I think). Maybe a bug?
http://pre.racket-lang.org/docs/html/guide/contracts-gotchas.html?q=contract&q=ignore
Says:
The contract library assumes that variables exported via contract-out are not assigned to, but does not enforce it. Accordingly, if you try to set! those variables, you may be surprised. ...snip... Moral: This is a bug that we will address in a future release.
Upvotes: 4