[racket] Contract weirdness: "broke contract [...]; expected <part?>, given: #<part>"

From: Carlos Scheidegger (carlos.scheidegger at gmail.com)
Date: Sat Nov 6 14:06:28 EDT 2010

Hi,

This must be a simple question, but I'm having some trouble convincing
Racket that one of my procedure calls respects the required contract,
and I'm not quite sure how to solve it. I only experience the problem
when running the code with serve/servlet, so I have a hunch that some
interaction with dynamic loading might be to blame here.

Specifically, there's a part? procedure (from scribble/core) which
returns true when I run the code from the interactive racket prompt,
but returns false when I run the same code via a procedure passed to
serve/servlet. I end up getting a servlet error claiming I "broke the
contract (-> part? (or/c #f content?)) on part-title-content; expected
<part?>, given: #<part>".

The full servlet trace is here:

Exception

The application raised an exception with the message:

<collects>/scribble/core.rkt:
  (file
   /home/cscheid/code/racket/cscheid.net/src/generate-xexpr.rkt)
 broke the contract (-> part? (or/c #f content?)) on
part-title-content; expected <part?>, given: #<part>

Stack trace:

raise-blame-error at:
  line 54, column 0, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/blame.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
part->xexpr at:
  line 82, column 0, in file
/home/cscheid/code/racket/cscheid.net/src/generate-xexpr.rkt
map at:
  line 18, column 11, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/private/map.rkt
render-main-page at:
  line 8, column 0, in file /home/cscheid/code/racket/cscheid.net/src/serve.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 57, column 2, in file
/home/cscheid/code/racket/plt-5.0.1/collects/web-server/dispatchers/dispatch-servlets.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
select-handler/no-breaks at:
  line 173, column 2, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/private/more-scheme.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
<unknown procedure> at:
  line 1445, column 3, in file
/home/cscheid/code/racket/plt-5.0.1/collects/racket/contract/private/arrow.rkt
connection-loop at:
  line 62, column 2, in file
/home/cscheid/code/racket/plt-5.0.1/collects/web-server/private/dispatch-server-unit.rkt

I'm sure I'm doing some things which are not exactly kosher - I'm
dynamically loading Scribble files and converting them to xexprs. My
wild guess is that scribble/core is somehow loading twice, and that
the contract is checking a structure built with one of the
instantiations against the predicate of the other instantiation. That
the setup works in an interactive Racket prompt gives me hope for a
solution. It's been about 6 years since I've done anything with
Racket, so there's a good chance I'm being terribly dense.

Is there a simpler way to achieve what I'm going for? That is, I have
a list of scribble files, all in the same directory, and I want to
load each of them. Right now, I'm doing this roughly via:

; path denotes the path to the list of files,
; scribble-file-list holds a list of filenames which I want to load
(parameterize ([current-load-relative-directory (normalize-path path)])
  (map (lambda (filename) (dynamic-require filename 'doc)) scribble-file-list))

Thank you very much in advance,
-carlos


Posted on the users mailing list.