17.3 A Better Type System

The type system in A Weak Type System requires all of the arguments to r^or to have the same type, which is a severe restriction. As a way around this, let’s extend the language of regular expressions so we can adjust the result of a regular expression and then expect the programmer to adjust the results so the types match up.

Here is the extended language:

The r^arrange form expects its first argument to be a regular expression that produces a tuple; it then binds the components of the tuple to the given variables and uses the result of the third expression as the result of the match.

And here is the typing rule:

It uses the auxiliary metafunction typeof to extract the type from the newly arranged expression relative to a typing context that pairs each variable with the respective type from the derived type of the tuple expression. If the newly arranged expression is a character, the type is Char; if it is a sequence of expressions, the type is a Tuple of the types of the elements of the sequence, and if it is a variable, the type is the type of the variable as specified in the typing context.

Here is how we can use arrange to write a regular expression that matches either “chick” or “calf”:
> (r^define r-or-t
            (r^seq (r^range #\c #\c)
                   (r^or (r^arrange
                          (r^seq (r^range #\h #\h)
                                 (r^range #\i #\i)
                                 (r^range #\c #\c)
                                 (r^range #\k #\k))
                          (h i c k)
                          h)
                         (r^arrange
                          (r^seq (r^range #\a #\a)
                                 (r^range #\l #\l)
                                 (r^range #\f #\f))
                          (a l f)
                          a))))
> (r^match r-or-t "chick")

'#(#\c #\h)

> '#(#\c #\h)

'#(#\c #\h)

> (r^match r-or-t "calf")

'#(#\c #\a)

> '#(#\c #\a)

'#(#\c #\a)

Here is an extended set of test cases.

Solution