[gambit-list] Type checking

Marc Feeley feeley at iro.umontreal.ca
Thu Jan 10 21:15:05 EST 2008


Your message prompted me to do some extensions to the FFI's foreign  
type implementation I was meaning to do for a while.

On 10-Jan-08, at 10:56 AM, Joel J. Adamson wrote:

> Dear Gambit List,
>
> I have a set of datatypes defined with c-define-type based on the GNU
> Scientific Library.  The Gambit-C manual says "For type checking
> on the Scheme side..." to use the TAG function of the  type definition
> as in
>
> (c-define-type gsl-matrix* (pointer gsl-matrix "gsl-matrix*"))

Note that your code is incorrect.  It should read

   (c-define-type gsl-matrix* (pointer gsl-matrix gsl-matrix*))

>
>
> What is the best way to use this to define a boolean test
> (e.g. gsl-matrix*?) for this type?

The new implementation of foreign types (now in the Gambit repository)  
allows assigning multiple tags to a given foreign type and allows the  
extraction of the tags from a foreign object:

   (c-define-type char* (pointer char (foo bar)))
   (define f (c-lambda () char* "___result = \"hello\";"))
   (define x (f))
   (foreign? x) ==> #t
   (foreign-tags x) ==> (foo bar)

So for your code you could do this:

   (c-define-type gsl-matrix* (pointer gsl-matrix gsl-matrix*))

   (define (gsl-matrix*? obj)
     (and (foreign? obj)
          (equal? (foreign-tags obj) '(gsl-matrix*))))

The ability to specify multiple tags is useful for implementing type  
hierarchies.  For the classical 2D and 3D point example we have:

   (c-define-type p2d (pointer point2d (point2d* point3d*)))
   (define make-point2d (c-lambda (int int) p2d "make_point2d"))
   (define show-point2d (c-lambda (p2d) void "show_point2d"))

   (c-define-type p3d (pointer point3d (point3d*)))
   (define make-point3d (c-lambda (int int int) p3d "make_point3d"))

   (show-point2d (make-point2d 11 22))
   (show-point2d (make-point3d 11 22 33))

Note that the definition

   (c-define-type p2d (pointer point2d (point2d* point3d*)))

is saying that wherever the type "p2d" is expected, foreign objects  
with a primary tag of point2d* or point3d* are allowed (the primary  
tag of a foreign type is the first tag in its list of tags, and is the  
tag used in the external representation of the foreign object).

Marc




More information about the Gambit-list mailing list