[racket-dev] class implementation and make-primitive-class
If a function takes 28 arguments, you probably overlooked a dozen or so. -- freely paraphrasing Perlis
And you just made the best case for Typed Racket and the documentation argument :-) -- freely paraphrasing my own TR talk
On Apr 17, 2014, at 2:49 PM, dfeltey at ccs.neu.edu wrote:
> For a course project I've been working on adding generators to contracts for use with contract-random-generate, and I've been trying to construct classes and objects from simple object/c contracts. When trying to find a way to functionally create a class at runtime, I came across the `make-primitive-class` function in class-internal.rkt.
>
> This function is exported, and available at a plain racket repl, but has no documentation that I have been able to find and the comments about it in class-internal.rkt seem to be incorrect.
>
> Trying to call it from the repl has problems also, for example (ignoring for a moment that the arguments aren't of the expected types)
>
> -> (make-primitive-class #f #f 'foo object% null #f null null null null)
> ; compose-class: arity mismatch;
> ; the expected number of arguments does not match the given number
> ; expected: 28
> ; given: 27
>
> The definition is in terms of compose-class and is just missing a `null` argument for the abstract-names, but even after fixing that in my local branch there is a discrepancy with the comments regarding it's first argument `make-struct:prim`.
>
> ; The `make-struct:prim' function takes prop:object, a class,
> ; a preparer, a dispatcher function, an unwrap property,
> ; an unwrapper, and a property assoc list, and produces:
> ; * a struct constructor (must have prop:object)
> ; * a struct predicate
> ; * a struct type for derived classes (mustn't have prop:object)
> ;
> ; The supplied preparer takes a symbol and returns a num.
> ;
> ; The supplied dispatcher takes an object and a num and returns a method.
> ;
> ; The supplied unwrap property is used for adding the unwrapper
> ; as a property value on new objects.
> ;
> ; The supplied unwrapper takes an object and returns the unwrapped
> ; version (or the original object).
> ;
> ; When a primitive class has a superclass, the struct:prim maker
> ; is responsible for ensuring that the returned struct items match
> ; the supertype predicate.
>
> This suggests that make-struct:prim should take 7 arguments, but passing a function of 7 arguments to it from the repl produces:
>
> -> (make-primitive-class (lambda (a b c d e f g) (values #f #f #f)) #f 'foo object% null #f null null null null)
> ; #<procedure>: arity mismatch;
> ; the expected number of arguments does not match the given number
> ; expected: 7
> ; given: 5
>
> Also as far as I can tell `make-primitive-class` is never used in the code base, it is defined in class-internal.rkt, but can be commented out without seeming to break anything else. Does anyone know if there is a purpose for this function, or if there is documentation somewhere on the functions I need to pass it in order to construct a class. I think I'm starting to get a better idea of how it might work from reading more of class-internal.rkt and how the class* macro expands, but any guidance would be appreciated.
>
> Thanks
> Dan
>
> _________________________
> Racket Developers list:
> http://lists.racket-lang.org/dev