[plt-scheme] match + structs + subtyping = sad programmer

From: David A. Herman (dherman at ccs.neu.edu)
Date: Sat Dec 27 01:23:30 EST 2003

Would it make sense to have a match form for structs that allows the
programmer to name the fields, rather than relying purely on the order in
which they are defined/stored? This becomes especially bizarre in the case
of subtyping. Take the following example:

;; -- with normal selectors --

(with-handlers ([exn:application:type?
                 (lambda (e)
                  (list (exn-message e)
                        (exn-continuation-marks e)
                        (exn:application-value e)
                        (exn:application:type-expected e)))])
  (raise-type-error 'foo "something" 'bar))

=> ("foo: expects argument of type <something>; given bar"

;; -- with match.ss --

(with-handlers ([exn:application:type?
                 (lambda (e)
                  (match e [($ exn:application:type msg mrks val exp)
                            (list msg mrks val exp)]))])
  (raise-type-error 'foo "something" 'bar))

=> match: too many fields for structure in pattern in: (struct
exn:application:type (msg mrks val exp))

;; --

I could understand the error if it only accepted the single field
belonging only to exn:application:type (i.e, `expected'), but strangely,
it accepts exactly 3 fields: the two from the top type and the one from
the bottom type (i.e., remove the `val' field from the above
pattern-matching example).

Perhaps the reason you can't do field-name matching is that you can't
dereference a supertype's fields as members of a subtype, e.g.,
(exn:application:type-continuation-marks e), as you can in IBCLOOLs
(inheritance-based C-like OO languages). Is there a reason why you can't
do this? It should be possible to compile the reference statically to a
vector offset, shouldn't it? Is it to keep from polluting the namespace
with too many selector function names?

At any rate, the real issue is that the point of naming the fields of a
structure is so that you don't have to reference elements of a tuple by
index, but AFAICT this is not possible with match.

Thanks & happy new year,

Posted on the users mailing list.