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

From: Carlos Scheidegger (carlos.scheidegger at gmail.com)
Date: Sat Nov 6 16:03:56 EDT 2010

Hi Jay,

thank you for your quick response. As you suggested, adding
'#:servlet-namespace (list "posts.rkt")' makes the problem go away -
thank you!

What I still don't understand, though, is how posts.rkt is loading
twice, since all calls to posts.rkt come from the servlet. The full
code is this:

(define (render-main-page request)
  `(html (head (title "title"))
         (body ,@(map part->xexpr (load-posts "posts")))))

(define (start request)
  (render-main-page request))

load-posts is defined in posts.rkt:

(define (load-posts path)
  (define post-list (current-post-list path))
  (parameterize ([current-load-relative-directory (normalize-path path)])
    (map (lambda (post-entry)
           (list post-entry
                 (dynamic-require (post-entry-file post-entry) 'doc)))
         post-list)))

It would make sense, in my mind, for the code to generate an error if
serve.rkt had a static define which loaded the posts. But the call to
load-posts is inside (render-main-page), which makes the error a bit
more mysterious. Also, I see this issue on v5.0.1, but offby1 on
#racket could not reproduce this on v5.0.1.900.

This is not too important to me since my code now works, but it seems
to signal a change in behavior between these two versions. I'm posting
it here in case it turns out to be important.

Thanks again,
-carlos

On Sat, Nov 6, 2010 at 2:57 PM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> On Sat, Nov 6, 2010 at 12:06 PM, Carlos Scheidegger
> <carlos.scheidegger at gmail.com> wrote:
>> 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.
>
> That's exactly what the problem is. This is what the
> #:make-servlet-namespace and #:servlet-namespace keyword arguments to
> the servlet dispatching functions are all about. Each servlet normally
> gets its own new namespace, but you can specifically share modules
> among servlets (and the server).
>
> Jay
>
>>
>> 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
>> _________________________________________________
>>  For list-related administrative tasks:
>>  http://lists.racket-lang.org/listinfo/users
>>
>
>
>
> --
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://faculty.cs.byu.edu/~jay
>
> "The glory of God is Intelligence" - D&C 93
>


Posted on the users mailing list.