[plt-scheme] Describe Function

From: Doug Williams (m.douglas.williams at gmail.com)
Date: Mon Nov 9 20:19:31 EST 2009

I've written a describe function for PLT Scheme - because I always liked it
in Common Lisp. I'll put it on PLaneT eventually, but was wondering if
anyone had suggestions for what to include. Data types that are there now
that I'm pretty comfortable with are: Booleans, numbers, strings, byte
strings, characters, symbols, regular expressions, byte regular expressions,
keywords, lists, pairs (improper lists), mutable lists, mutable pairs
(improper mpairs), vectors, boxes, hashes, procedures, and void.

I may have gone a bit overboard with giving the names of integers (up to
10^102), but the Symbolics Common Lisp describe function did it and I always
liked showing it off. So, I included it. But, it might make sense to limit
it to fixums just to keep the name from getting so long.

I'm pretty happy with procedure descriptions with the number of positional
arguments and required and optional keywords. (I still need to handle the
case of the optional keywords list being #f - that is, allow any keyword.)
I'm curious about whether a primitive closure is different from a primitive
procedure - for example, can you get the result arity for a primitive
closure like you can for a primitive procedure. And, what is a example of a
primitive closure so I can include a test for it?

I've included recursively describing boxes and hashes. It shouldn't be a
problem for boxes, but hash descriptions could get rather long when I
include descriptions of the key values. Would it make sense to have a
recursive? arguments to control this? If recursive? is implemented should it
also apply to lists, vectors, etc? I'm concerned about inundating the user
with detail where it isn't needed. [Maybe the best thing is to limit
recursive descriptions to boxes.]

Structs and objects are somewhat more problematic. If a struct responds to
struct?, I can get some details with struct->vector. So, I am currently
recursively describing the field details (by field number) for these. As far
as I can tell, completely opaque structured (i.e., those that return #f for
struct?) will give me the 'name' of the structure type by using object-name.
Any suggestions for describing structs and objects (and classes) would be
welcome.

What other first-class data object would be useful to include (parameters,
which get described as procedures now, modules, units, signatures,
processes, ...)?

Thoughts, suggestions, comments, etc are welcome.

The message with describe.ss attached was too big to post (I can send it
separately if anyone wants to play with it), but here is some spew of the
describe-test.ss file:

--- Booleans ---
#t is the Boolean true
#f is the Boolean false

--- Numbers ---
+inf.0 is positive infinity
-inf.0 is negative infinity
+nan.0 is an inexact positive real number
0 is the exact integer fixnum zero
3628800 is the exact positive integer fixnum three million six hundred
twenty-eight thousand eight hundred
815915283247897734345611269596
115894272000000000 is an exact positive integer eight hundred fifteen
quattuordecillion nine hundred fifteen tredecillion two hundred eighty-three
duodecillion two hundred forty-seven undecillion eight hundred ninety-seven
decillion seven hundred thirty-four nonillion three hundred forty-five
octillion six hundred eleven septillion two hundred sixty-nine sextillion
five hundred ninety-six quintillion one hundred fifteen quadrillion eight
hundred ninety-four trillion two hundred seventy-two billion
-32636611329915909373824450783844635770880000000000 is an exact negative
integer minus thirty-two quindecillion six hundred thirty-six
quattuordecillion six hundred eleven tredecillion three hundred twenty-nine
duodecillion nine hundred fifteen undecillion nine hundred nine decillion
three hundred seventy-three nonillion eight hundred twenty-four octillion
four hundred fifty septillion seven hundred eighty-three sextillion eight
hundred forty-four quintillion six hundred thirty-five quadrillion seven
hundred seventy trillion eight hundred eighty billion
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
is an exact positive integer value whose absolute value is >= 10^102
3628800/39916801 is an exact positive rational number with a numerator of
3628800 and a denominator of 39916801
-1+3i is an exact complex number whose magnitude is 3.1622776601683795
0.0 is an inexact integer zero
3628800.0 is an inexact positive integer
8.159152832478977e+047 is an inexact positive integer
3.1622776601683795 is an inexact positive real number
0+3.1622776601683795i is an inexact positive imaginary number
3.1622776601683795+3.1622776601683795i is an inexact complex number whose
magnitude is 4.47213595499958

--- Strings ---
"abc" is an immutable string of length 3
"123" is a mutable string of length 3

--- Byte Strings ---
#"abc" is an immutable byte string of length 3
#"012" is a mutable byte string of length 3

--- Characters ---
#\a is the character whose code-point number is 97(#x61) and general
category is 'll (letter, lowercase)
#\A is the character whose code-point number is 65(#x41) and general
category is 'lu (letter, uppercase)
#\0 is the character whose code-point number is 48(#x30) and general
category is 'nd (number, decimal digit)
#\( is the character whose code-point number is 40(#x28) and general
category is 'ps (punctuation, open)

--- Symbols ---
abc is the interned symbol
|(a + b)| is the interned symbol
g1121 is an uninterned symbol

--- Regular Expressions ---
#rx"Ap*le" is a regular expression in regexp format
#px"Ap*le" is a regular expression in pregexp format

--- Byte Regular Expressions ---
#rx#"Ap*le" is a byte regular expression in regexp format
#px#"Ap*le" is a byte regular expression in pregexp format

--- Keywords ---
#:key is the keyword

--- Lists and Pairs ---
(this is a proper list) is a proper immutable list of length 5
(this is an improper . list) is an improper immutable list
((this . is) (also . a) (proper . list)) is a proper immutable list of
length 3

--- Mutable Lists and Pairs ---
{this is a proper list} is a proper mutable list of length 5
{this is an improper . list} is an improper mutable list
{(this . is) (also . a) (proper . list)} is a proper mutable list of length
3

--- Vectors ---
#(1 2 3) is an immutable vector of length 3

--- Boxes ---
#&12 is a box containing 12, 12 is the exact positive integer fixnum twelve
#&#&a is a box containing #&a, #&a is a box containing a, a is the interned
symbol
#&3.1622776601683795 is a box containing 3.1622776601683795,
3.1622776601683795 is an inexact positive real number

--- Hashes ---
#hash((c . 16) (b . 14) (a . 12)) is an immutable hash table and that uses
equal? to compare keys
  c : 16, 16 is the exact positive integer fixnum sixteen
  b : 14, 14 is the exact positive integer fixnum fourteen
  a : 12, 12 is the exact positive integer fixnum twelve
#hasheq((c . c) (b . b) (a . a)) is an immutable hash table and that uses
eq? to compare keys
  c : c, c is the interned symbol
  b : b, b is the interned symbol
  a : a, a is the interned symbol
#hasheqv((c . #\c) (b . #\b) (a . #\a)) is an immutable hash table and that
uses eqv? to compare keys
  c : #\c, #\c is the character whose code-point number is 99(#x63) and
general category is 'll (letter, lowercase)
  b : #\b, #\b is the character whose code-point number is 98(#x62) and
general category is 'll (letter, lowercase)
  a : #\a, #\a is the character whose code-point number is 97(#x61) and
general category is 'll (letter, lowercase)
#hash((b . 14) (a . 12) (c . 16)) is a mutable hash table and that uses
equal? to compare keys
  b : 14, 14 is the exact positive integer fixnum fourteen
  a : 12, 12 is the exact positive integer fixnum twelve
  c : 16, 16 is the exact positive integer fixnum sixteen
#<hash> is a mutable hash table that holds its keys weakly and that uses
equal? to compare keys
  c : 16, 16 is the exact positive integer fixnum sixteen
  b : 14, 14 is the exact positive integer fixnum fourteen
  a : 12, 12 is the exact positive integer fixnum twelve

--- Procedures ---
#<procedure:car> is a primitive procedure named car that accepts 1 argument
and returns 1 result
#<procedure:open-output-file> is a procedure named open-output-file that
accepts 1 argument plus optional keyword arguments #:exists and #:mode
#<procedure:current-input-port> is a primitive procedure named
current-input-port that accepts 0 or 1 arguments and returns 1 result
#<procedure:...describe-test.ss:133:10> is a procedure named
...describe-test.ss:133:10 that accepts 1 argument

--- Void ---
#<void> is void

--- Structures ---
#(struct:transparent-struct a b c) is a structure of type transparent-struct
  1 : a, a is the interned symbol
  2 : b, b is the interned symbol
  3 : c, c is the interned symbol

--- Other Named Things ---
#<opaque-struct> is an object of type opaque-struct

Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20091109/4e18e8af/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: describe-test.ss
Type: application/octet-stream
Size: 3070 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20091109/4e18e8af/attachment.obj>

Posted on the users mailing list.