Thank you both for the detailed and informative replies.

I've been able to get away with writing my-record-equal? and
my-record-printer and using them wherever required. I could say it's a
pity I have to rewrite standard functions like member (although at
least I can use memp), but I guess it's not really that hard, and your
point about using Scheme as a base platform is well taken.

On Thu, Apr 23, 2009 at 5:28 PM, Derick Eddington
<[email protected]> wrote:
> 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
> ----------------------------------------------------------------
>
>

Reply via email to