Subject: Re: (type-of ...)
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1997/09/12
Newsgroups: comp.lang.scheme
Message-ID: <5vara1$2h5n1@fido.asd.sgi.com>

Jerry Bakin  <jbakin@bmw.autobahn.org> wrote:
+---------------
| ...no way to interrogate a scheme object about its type.
| For instance, in LISP, I would find that (type-of 3) was integer while
| (type-of "integer") was string.  How can I do this in Scheme...
+---------------

Look at R4RS section 3.4:

	"No object satisfies more than one of the following predicates..."

then code "type-of" this way (or similar):

	(define (type-of x)
	  (cond
	    ((pair? x) 'pair)
	    ((symbol? x) 'symbol)
	    ((number? x) 'number)
	    ((char? x) 'char)
	    ((boolean? x) 'boolean)
	    ((vector? x) 'vector)
	    ((string? x) 'string)
	    ((procedure? x) 'procedure)
	    ; types not listed in section 3.4!!!
	    ((null? x) 'null)
	    ((eof-object? x) 'eof-object)
	    ((input-port? x) 'input-port)
	    ((output-port? x) 'output-port)
	    (else 'unknown-type)))

If you want finer distinctions, you might replace the "number" line with:

	    ((number? x)
	     (string->symbol
	       (string-append
	         (if (exact? x) "exact-" "inexact-")
	         (cond
		   ((integer? x) "integer")
		   ((rational? x) "rational")
		   ((real? x) "real")
		   ((complex? x) "complex")
	           (else "number")))))		; (can this ever happen?)

"Whoops!", you say, "What about 'user-defined' types?"  Well, that opens
a whole *other* can of worms, and about the best you can say is one of:

1. There can't be any user types which are not one of the above; or

2. Different implementations provide different extensions (sometimes
   extremely rich, perhaps up to and including CLOS-like full object
   systems!) for defining user types... if they provide any at all; or

3. If you define your own, better make sure you adjust "type-of" to match.
   E.g., if you decide to use vectors with magic tags in slot #0 for your
   types, make sure "type-of" tests for your magic types *before* testing
   for generic "vector". Also, remember to redefine the builtin "vector",
   too, so other code won't get confused.

There are some good papers on this subject in the various Scheme repositories.


-Rob

p.s. R4RS-compliant implementations need not agree even on the limited
set of types above, e.g., with the longer version of "type-of":

	MzScheme:  (type-of (/ 234 456)) ==> exact-rational
	SCM:       (type-of (/ 234 456)) ==> inexact-rational
	libscheme: (type-of (/ 234 456)) ==> inexact-real

-----
Rob Warnock, 7L-551		rpw3@sgi.com   http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673 [New area code!]
2011 N. Shoreline Blvd.		FAX: 650-933-4392
Mountain View, CA  94043	PP-ASEL-IA