9.3.4 Method dispatch and limited integers

When a type is a limited-integer type, Dylan uses the following rules:

1. An object is an instance of a limited-integer type if it is an instance of <integer> and if it is (inclusively) within the specified range.

2. A limited-integer type is a proper subtype of <integer>, as long as it is not equivalent to <integer>.

One limited-integer type is a proper subtype of another limited-integer type if the range of the first type is entirely within the range of the second type, and if the two types are not equivalent.

For example, suppose that we have these definitions:

define constant <nonnegative-integer> = limited(<integer>, min: 0);
// Method 1
define method say (x :: <integer>) ... end method say;
// Method 2
define method say (x :: <nonnegative-integer>) ... end method say;

Now, if say is called with an argument of 1, both methods are applicable, and method 2 is more specific than method 1. If say is called with an argument of -1, only method 1 is applicable.

Now suppose that, instead, we have the following definitions:

define constant <limited-integer-1> = limited(<integer>, min: -2, max: 2);
define constant <limited-integer-2> = limited(<integer>, min: 0, max: 4);
// Method 1
define method say (x :: <limited-integer-1>) ... end method say;
// Method 2
define method say (x :: <limited-integer-2>) ... end method say;

Now, if say is called with an argument of 1, both methods are applicable, and neither method is more specific than the other; the two methods are ambiguous. If no more specific method exists, Dylan signals an error when we call say with an argument of 1.