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
>> 
>> 
>> 
>> 
>> 
>> 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
>> 
>> 
>> 
>> -- 
>> Roman Klochkov
>


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

Reply via email to