Hm... But reading it's sources give me some clues. Now I have working dirty hack
#lang racket/base (require racket/private/class-internal) (define (class-inits cls) (apply append (for/list ([c (in-vector (class-supers cls))]) (class-init-args c)))) It gives the list of class init arguments. Maybe someone also needs it. Thu, 5 Jun 2014 21:13:47 -0400 от Matthias Felleisen <matth...@ccs.neu.edu>: > >class/c doesn't check inits properly: > >>#lang racket >> >>(provide >> (contract-out >> [c% (class/c (init-field [x number?]))])) >> >>(define c% >> (class object% >> (field (x 10)) >> (super-new))) > >and now run > >>Welcome to Racket v6.0.1.12. >>> (require "foo.rkt") >>> (new c%) >>(object:c% ...) >Okay more thinking to do -- Matthias > > > > >On Jun 5, 2014, at 8:49 PM, Roman Klochkov wrote: >>It is maybe closer. >> >>But inside define-binary-class I also doesn't know the total number of init >>arguments. Because library user may give any superclass. And I don't know, >>how to get init arguments (or arity for of make-object for a given class) >>without calling make-object and reading the error message. >>Lake in case >>(define base% (class (super-new) (init-field param1 param2))) >>(define-binary-class db base% ((a u1) (b u2))) >> >>Maybe the problem doesn't have a solution. But I see class/c, which has init >>and init-fields clauses. Somehow it checks them... >> >>Thu, 5 Jun 2014 16:36:16 -0400 от Matthias Felleisen < matth...@ccs.neu.edu >: >>> >>>Sorry I am so slow. >>> >>>Contracts are first-class values. >>> >>>You could modify define-binary-class so that it also creates and defines >>>a contract P that can be passed along to read-object. Then read-object >>>can use P like this: >>> >>>> #lang racket >>>> >>>> (provide >>>> a% a? >>>> b% b? >>>> (contract-out >>>> (read-object (->i ((c? contract?) (c% any/c)) >>>> #:rest [l (c?) (lambda (x) (apply c? x))] >>>> (_ (c%) (is-a?/c c%)))))) >>>> >>>> (define a% (class object% [init-field x] (super-new))) >>>> (define b% (class object% [init-field x y] (super-new))) >>>> >>>> (define a? (lambda x (and (= (length x) 1) (andmap number? x)))) >>>> (define b? (lambda x (and (= (length x) 2) (andmap number? x)))) >>>> >>>> (define (read-object __c c% . x) >>>> (apply make-object c% x)) >>> >>>Then you get exactly what you want and pretty precise checking: >>> >>>> % !! >>>> racket >>>> Welcome to Racket v6.0.1.11. >>>> > (require "foo.rkt") >>>> foo.rkt:9:23: is-a/c?: unbound identifier in module >>>> in: is-a/c? >>>> context...: >>>> standard-module-name-resolver >>>> /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7 >>>> > (require "foo.rkt") >>>> foo.rkt:9:31: c%: unbound identifier in module >>>> in: c% >>>> context...: >>>> standard-module-name-resolver >>>> /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7 >>>> > (require "foo.rkt") >>>> > ( read-object b? b% 10 20 ) >>>> (object:b% ...) >>>> > ( read-object b? b% 10 ) >>>> read-object: contract violation >>>> expected: ...vn/2HtDP/foo.rkt:8:34 >>>> given: '(10) >>>> in: the l argument of >>>> (->i >>>> ((c? contract?) (c% any/c)) >>>> #:rest >>>> (l (c?) (lambda (x) (apply c? x))) >>>> (_ (c%) (is-a?/c c%))) >>>> contract from: >>>> /Users/matthias/svn/2HtDP/foo.rkt >>>> blaming: top-level >>>> at: /Users/matthias/svn/2HtDP/foo.rkt:7.5 >>>> context...: >>>> >>>> /Users/matthias/plt/racket/collects/racket/contract/private/blame.rkt:143:0: >>>> raise-blame-error16 >>>> arg-checker >>>> /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7 >>>> > ( read-object a? a% 10 ) >>>> (object:a% ...) >>>> > ( read-object a? a% 10 20) >>>> read-object: contract violation >>>> expected: ...vn/2HtDP/foo.rkt:8:34 >>>> given: '(10 20) >>>> in: the l argument of >>>> (->i >>>> ((c? contract?) (c% any/c)) >>>> #:rest >>>> (l (c?) (lambda (x) (apply c? x))) >>>> (_ (c%) (is-a?/c c%))) >>>> contract from: >>>> /Users/matthias/svn/2HtDP/foo.rkt >>>> blaming: top-level >>>> at: /Users/matthias/svn/2HtDP/foo.rkt:7.5 >>>> context...: >>>> >>>> /Users/matthias/plt/racket/collects/racket/contract/private/blame.rkt:143:0: >>>> raise-blame-error16 >>>> arg-checker >>>> /Users/matthias/plt/racket/collects/racket/private/misc.rkt:87:7 >>> >>> >>> >>>If you want to make sure that a? and a% come together, you can package them >>>up in structs. >>> >>>If you just want to make sure that these contracts come from your binary >>>class module, you can hide them in applicable structs or something like >>>that. >>> >>>Am I getting closer? -- Matthias >>> >>> >>> >>> >>>On Jun 5, 2014, at 4:15 PM, Roman Klochkov < kalimeh...@mail.ru > wrote: >>> >>>> I don't create classes. I provide a function read-object, so user can do >>>> >>>> (require binary-class) >>>> (define base% (class (super-new) (init-field param1 param2))) >>>> (define-binary-class db base% ((a u1) (b u2))) >>>> >>>> (define data (read-object db my-file data-param1 data-param2) >>>> >>>> And I try to make a contract, so when he made an error in last call and >>>> wrote >>>> >>>> (define data (read-object db my-file data-param1)), then error message >>>> whould blame read-object, not `instantiate' >>>> >>>> Thu, 5 Jun 2014 16:08:39 -0400 от Matthias Felleisen < >>>> matth...@ccs.neu.edu >: >>>> >>>> Can't you use is-a?/c like this: >>>> >>>> > #lang racket >>>> > >>>> > (provide >>>> > a% >>>> > b% >>>> > (contract-out >>>> > (read-object (case-> >>>> > [-> (is-a?/c a%) number? number?] >>>> > [-> (is-a?/c b%) number? number? number?])))) >>>> > >>>> > (define a% (class object% (super-new))) >>>> > (define b% (class object% (super-new))) >>>> > >>>> > (define read-object >>>> > (case-lambda >>>> > [(a x) x] >>>> > [(b x y) (+ x y)])) >>>> >>>> >>>> and use this module like this: >>>> >>>> > % racket >>>> > Welcome to Racket v6.0.1.11. >>>> > > (require "foo.rkt") >>>> > > (read-object (new a%) 10) >>>> > 10 >>>> > > (read-object (new a%) 10 20) >>>> > read-object: contract violation >>>> > expected: (is-a?/c b%) >>>> > given: (object:a% ...) >>>> > in: the domain of >>>> > the 2nd case of >>>> > (case-> >>>> > (-> (is-a?/c a%) number? number?) >>>> > (-> (is-a?/c b%) number? number? number?)) >>>> > contract from: >>>> > /Users/matthias/svn/2HtDP/foo.rkt >>>> > blaming: top-level >>>> > at: /Users/matthias/svn/2HtDP/foo.rkt:7.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 (new b%) 10 20) >>>> > 30 >>>> > > (read-object (new b%) 10) >>>> > read-object: contract violation >>>> > expected: (is-a?/c a%) >>>> > given: (object:b% ...) >>>> > in: the domain of >>>> > the 1st case of >>>> > (case-> >>>> > (-> (is-a?/c a%) number? number?) >>>> > (-> (is-a?/c b%) number? number? number?)) >>>> > contract from: >>>> > /Users/matthias/svn/2HtDP/foo.rkt >>>> > blaming: top-level >>>> > at: /Users/matthias/svn/2HtDP/foo.rkt:7.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 >>>> >>>> >>>> >>>> On Jun 5, 2014, at 3:19 PM, Roman Klochkov < kalimeh...@mail.ru > wrote: >>>> >>>> > (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 < >>>> > matth...@ccs.neu.edu >: >>>> > >>>> > 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 >>>> > >>>> > >>>> > >>>> > >>>> > > > >>>> > > > >>>> > > > -- >>>> > > > Roman Klochkov >>>> > > >>>> > > >>>> > > >>>> > > -- >>>> > > Roman Klochkov >>>> > >>>> > >>>> > >>>> > -- >>>> > Roman Klochkov >>>> >>>> >>>> >>>> -- >>>> Roman Klochkov >>> >> >> >>-- >>Roman Klochkov > -- Roman Klochkov
____________________ Racket Users list: http://lists.racket-lang.org/users