Compiling with raco make makes it impossible to implement an interface in a different source file than where the interface is defined. In particular, objects of a class C that implements an interface I imported from another source file are not actually considered to implement interface I by the I? and I! contracts.
How to reproduce
Create a file lib.rkt containing:
#lang dssl2
interface I: pass
Create a file client.rkt containing:
#lang dssl2
import 'lib.rkt'
class C (I):
def __init__(self): pass
# This should succeed because C implements I, but it fails if you run
# `raco make` first. (It also fails in DrRacket.)
let o: I! = C()
Run client.rkt:
$ racket client.rkt
$
Compile client.rkt and run it again:
$ raco make client.rkt
$ racket client.rkt
o: broke its own contract;
class C does not implement interface I
in: I!
contract from: (definition o)
blaming: (definition o)
(assuming the contract is correct)
at: /Users/tov/Desktop/raco-make-weirdness/client.rkt:10.4
context...:
/Applications/Racket v7.4/collects/racket/contract/private/blame.rkt:347:0: raise-blame-error16
"/Users/tov/Desktop/raco-make-weirdness/client.rkt": [running body]
temp37_0
for-loop
run-module-instance!125
perform-require!78
$
Delete the compilation artifacts and run it again:
Compiling with
raco make
makes it impossible to implement an interface in a different source file than where the interface is defined. In particular, objects of a classC
that implements an interfaceI
imported from another source file are not actually considered to implement interfaceI
by theI?
andI!
contracts.How to reproduce
Create a file
lib.rkt
containing:Create a file
client.rkt
containing:Run
client.rkt
:Compile
client.rkt
and run it again:Delete the compilation artifacts and run it again: