(define (read-object binary-class in . args) (send (apply make-object binary-class args) read in))
read-object takes a class as a first arg, and additional arguments to make an object of that class. I can't make case-> because I don't know j,ject of what (user-defined) class will be created with the function by user of my library. This case is described in Racket Guide 7,3.9 http://docs.racket-lang.org/guide/contracts-general-functions.html#%28part._contracts-no-domain%29 , where recommended to use unconstrained-domain-> with procedure-arity-includes? , but it doesnt' work with make-object Thu, 5 Jun 2014 14:51:21 -0400 от Matthias Felleisen <[email protected]>: > >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 < [email protected] > 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 < [email protected] >> >: >> >> 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 < [email protected] > 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 < >> > [email protected] >: >> > >> > 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 < [email protected] > 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 > -- Roman Klochkov
____________________ Racket Users list: http://lists.racket-lang.org/users

