On Wed, 2009-04-22 at 05:42 -0700, Ramana wrote: > Can the record printer in Ikarus be customized (e.g. only print a > certain field, or print field names)?
IIRC, no. There's an existing request for this: https://bugs.launchpad.net/ikarus/+bug/301441 > Can we extend equal? to new records (like "deriving Eq" in Haskell)? equal? cannot be extended in any way. eqv?, which equal? is specified to use for records, is specified to compare records according to their location in the store. I'm guessing you want equal? to treat records as it does pairs and vectors. I.e., compare records' structural equality rather than eqv? equality. > What about in R6RS (i.e. without any Ikarus-specific features) (for > both questions)? If you want R6RS portability, you have to make these things yourself and use them where needed. You can make your own printer which recognizes records and prints them as you want. You can make your own equivalence predicate which treats records as you want. Scheme is intended to be a small base platform upon which you build your own systems. If you use a generics or type classes framework with a printer and a structural equivalence predicate and build your software on it, you could extend those things as desired and they'd work with other software components built on the framework (I imagine). If you only need a more limited solution, you could do something like this: (define (printer port obj) (if (record? obj) (print-record-my-way port obj) (put-datum port obj))) To get the record data to print, use the records introspection facilities described throughout R6RS Libraries Chapter 6. You may find useful what my (xitomatl records) library does to help with record inheritance. You could define print-record-my-way as: (import (xitomatl records) (only (xitomatl common) fprintf)) (define (print-record-my-way port r) (let ((rtd (record-rtd r))) (fprintf port "#[~s" (record-type-name rtd)) (for-each (lambda (f a) (fprintf port " ~s: ~s" f (a r))) (record-type-fields rtd) (record-type-accessors rtd)) (put-string port "]"))) For a predicate to test structural equality of records, you could do something like: (define (record-equal? x y) (let ((x-rtd (record-rtd x)) (y-rtd (record-rtd y))) (and (eqv? x-rtd y-rtd) (andmap (lambda (a) (equal? (a x) (a y))) (record-type-accessors x-rtd))))) But this does not handle the case when records' fields transitively contain records. To handle that, you'd need something like equal? which works that way. If you need that, you could adapt an existing implementation of equal?, such as the cycle-safe one in: ikarus.dev/scheme/ikarus.equal.ss And remember: other components which do not use your printer and predicate do not use them. -- : Derick ----------------------------------------------------------------
