Skip to content
jckarter edited this page Nov 14, 2010 · 2 revisions

Motivation

Related library functions often share a set of common type variables. A common example is overloads for new parameterized types:

   record Foo[T, U, V] (/* ... */);

   [T, U, V | Fooable?(T, U, V)] overload Foo[T, U, V]() { /*...*/ }
   [T, U, V | Fooable?(T, U, V)] overload Foo[T, U, V](x: Foo[T, U, V]) { /*...*/ }
   [T, U, V | Fooable?(T, U, V)] overload destroy(x: Foo[T, U, V]) { /*...*/ }

To cut down on boilerplate, it should be possible to share a common set of type variables and pattern rules among a set of definitions.

Proposed implementation

If a type pattern is followed by { }, each definition within the braces should all act as if it has been preceded by that type pattern. The motivating example would thus look as follows:

  [T, U, V | Fooable?(T, U, V)] {
      overload Foo[T, U, V]() { /*...*/ }
      overload Foo[T, U, V](x: Foo[T, U, V]) { /*...*/ }
      overload destroy(x: Foo[T, U, V]) { /*...*/ }
  }

Definitions or nested pattern blocks within a pattern block may add additional pattern variables and rules, which will be anded with the outer block's rules. So this:

  [A, B | Bar?(B)] {
      [C | Pub?(B, C)] foo(x: A, y: B, z: C) { /*...*/ }
  }

should be equivalent to:

  [A, B, C | Bar?(B) and Pub?(B, C)] foo(x: A, y: B, z: C) { /*...*/ }

Discussion