From what I understand now, you want a contract for a function that creates 
objects from a variable number of arguments. If you write your module interface 
like this, 

> #lang racket
> 
> (provide
>   (contract-out
>     (read-object (case->
>                  [-> 'a number? number?]
>                  [-> 'b number? number? number?]))))
> 
> (define read-object
>   (case-lambda
>     [(a x) x]
>     [(b x y) (+ x y)]))

you can get checked variable-arity behavior: 

> Welcome to Racket v6.0.1.11.
> > (require "foo.rkt")
> > (read-object 'a 10)
> 10
> > (read-object 'b 10 20)
> 30
> > (read-object 'b 10)
> read-object: contract violation
>   expected: (quote a)
>   given: 'b
>   in: the domain of
>       the 1st case of
>       (case->
>        (-> 'a number? number?)
>        (-> 'b number? number? number?))
>   contract from: 
>       /Users/matthias/svn/2HtDP/foo.rkt
>   blaming: top-level
>   at: /Users/matthias/svn/2HtDP/foo.rkt:5.5
>   context...:
>    
> /Users/matthias/plt/racket/collects/racket/contract/private/blame.rkt:143:0: 
> raise-blame-error16
>    /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7
> > (read-object 'a 10 20)
> read-object: contract violation
>   expected: (quote b)
>   given: 'a
>   in: the domain of
>       the 2nd case of
>       (case->
>        (-> 'a number? number?)
>        (-> 'b number? number? number?))
>   contract from: 
>       /Users/matthias/svn/2HtDP/foo.rkt
>   blaming: top-level
>   at: /Users/matthias/svn/2HtDP/foo.rkt:5.5
>   context...:
>    
> /Users/matthias/plt/racket/collects/racket/contract/private/blame.rkt:143:0: 
> raise-blame-error16
>    /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7


I think you can use ->i contracts inside of the case-> clauses if you need more 
precision. 

If I am still misunderstanding your question, sorry. 

-- Matthias


 


On Jun 5, 2014, at 1:41 PM, Roman Klochkov <kalimeh...@mail.ru> wrote:

> It is not writing, but reading. I'm making uinversal library for binary data 
> (like dbf, mp3 id3 tags, and so on)  mapping to objects
> https://github.com/Kalimehtar/binary-class
> 
> read-object simply
> 
> (define (read-object binary-class in . args)
>     (send (apply make-object binary-class args) read in))
> 
> But I don't like, that contract may not give correct error message for wrong 
> nomber of items in args.
> 
> 
> Thu, 5 Jun 2014 12:31:49 -0400 от Matthias Felleisen <matth...@ccs.neu.edu>:
> 
> Do you control the writing of objects to a port? If so, check out 
> 'serialization.' If not, I don't think I can help you. Sorry -- Matthias
> 
> 
> 
> On Jun 5, 2014, at 12:29 PM, Roman Klochkov <kalimeh...@mail.ru> wrote:
> 
> > I don't control class creation.
> > I need to make a wrapper around make-object and attach contract to the 
> > wrapper.
> > 
> > Now I have
> > (provide/contract
> > [read-object (->i ([binary-class (implementation?/c binary<%>)]
> > [port input-port?])
> > #:rest [args list?]
> > [result (binary-class) (is-a?/c binary-class)])])
> > 
> > I cannot control number of args. Now, when error encountered I have 
> > confusing error message mentioning "instantiate".
> > 
> > Thu, 5 Jun 2014 12:13:26 -0400 от Matthias Felleisen <matth...@ccs.neu.edu>:
> > 
> > Here is the pattern I recommend: 
> > 
> > Welcome to Racket v6.0.1.11.
> > > (define (create-c #:x [x 0]) (new c% [x x]))
> > > (define c% (class object% (init-field x) (super-new)))
> > 
> > That is, a class comes with a 'factory' definition, a function that creates 
> > instances and uses keywords similar to those used by the class initializer. 
> > If you then export these factories, you can enforce invariants and also 
> > probe the factory for the information you want: 
> > 
> > > (create-c)
> > (object:c% ...)
> > > (create-c #:x 10)
> > (object:c% ...)
> > > (procedure-arity create-c)
> > 0
> > > (procedure-keywords create-c)
> > '()
> > '(#:x)
> > 
> > 
> > Yes, one could argue that this is a poor man's substitute for missing class 
> > reflection. -- Matthias
> > 
> > 
> > 
> > 
> > 
> > 
> > On Jun 5, 2014, at 11:32 AM, Roman Klochkov <kalimeh...@mail.ru> wrote:
> > 
> > > For any procedure I can use procedure-arity. But how to get the number of 
> > > init arguments for a class?
> > > 
> > > Or maybe there are any other way to make a contract, like in Guide 7.3.9, 
> > > where one can compare number of arguments and arity of the function, but 
> > > when using (make-object someclass ...)
> > > instead of the function.
> > > 
> > > 
> > > -- 
> > > Roman Klochkov
> > > ____________________
> > > Racket Users list:
> > > http://lists.racket-lang.org/users
> > 
> > 
> > 
> > -- 
> > Roman Klochkov
> 
> 
> 
> -- 
> Roman Klochkov


____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to