# Trouble handling constraints for the input of a method

I'm looking for advice on how to handle constraints on the input of a method. I have a method that only works if the input argument(s) fulfill certain constraints. If the method is called on input that does not fulfill the constraint(s), the method does something harmful.

The concrete problem is this. I have a class `Interval` which represents closed 1-dimensional intervals:

``````// code in C# or pseudo-code
class Interval
{
private double lb, ub; // lower bound and upper bound of the interval

public Interval(double lb, double ub)
{
if (lb > ub)
throw new ArgumentException("Lower bound cannot be larger than upper bound!");

this.lb = lb; this.ub = ub;
}

public bool Disjoint(Interval i)
{
return (ub < i.lb || i.ub < lb);
}

public void UniteWith(collection of Intervals)
{
...
}
}
``````

The method `UniteWith` should take a collection of disjoint `Interval`s as input and modify it such that, when thinking of the collection as a union of sets, the current `Interval` is joined to that set. Also, the collection should be modified such that after joining, it consists of disjoint `Interval`s again.

Example:

``````collection is: [-3, 0], [2, 4], [5, 18], [21, 22]
current interval is: [3, 6]
resulting modified collection is: [-3, 0], [2, 18], [21, 22]
``````

Methods I definitely need for the collection are `Add` and `Remove`, so `ICollection` seems to be a reasonable choice for the input type (thinking in C# again, but probably applies to Java and other OOP languages, too).

For the algorithm to work correctly, I need the input to be sorted. If it is not sorted, the input will be modified unpredictably. And this is the point where I don't know what to do:

• I could take `ICollection` as argument, but then I would need to check by myself if the input is sorted. If it is not sorted, I throw an exception to tell the programmer using my code that his input is bad. I believe I can do this by using the enumerator that every `ICollection` has.

``````public void UniteWith(ICollection<Interval> coll)
{
IEnumerator enumerator = coll.GetEnumerator();
enumerator.MoveNext();
Interval fst = enumerator.Current;

while (enumerator.MoveNext())
{
Interval snd = enumerator.Current;
if (fst.ub >= snd.lb)
throw new ArgumentException("coll must be sorted ascendingly!");
fst = snd;
}

// if we get here, we can start the actual algorithm
...
}
``````
• I could make `coll` a `SortedList` or `SortedSet` in the method signature instead of `ICollection`. Then I would be sure it is sorted, but now a user cannot input his `IList` even if he sorted it already, and since his `IList` provides all methods the algorithm is going to need (`Add` and `Remove` and iterating over it), he might be disappointed he cannot use it. Also, I don't know a way to tell the compiler "this input can be either `SortedSet` or `SortedList`", and if there is no such way, it is even more restrictive. Okay, I could write two methods for that. Then I had to take care of two documentation comments (I'm commenting EVERY method I have) and copy-paste changes all the time. It is possible, but doesn't sound very appealing to me.

• I could keep the input type `ICollection`, do not run any checks on whether the input is sorted, and advise in the documentation comment not to put any unsorted collection in there and explain the consequences of doing so. So I hand over the responsiblity to the user of my code. This does not seem very clean to me either, because this is exactly what C/C++ do (and what I don't like): They let you ignite the computer; they say they let you because they cannot be sure you did not want to, but in fact you did not want to - you just made a mistake.

Looking forward to any suggestions, not just for this concrete scenario, but also for the general case - if there is such a thing as a "general case". (Might as well be that it always depends.)

EDIT:

I just noticed that for the first and third option it might be better to only allow inputs that have a concept of order. Even though a `HashSet` has an enumerator and as such an order, it is more an internal feature. From its concept, it has no order (it can change when adding / removing elements). So what interface can I put in there? Is there something like `IOrderable`?

## 2 Answers

1. `ICollection` with errors: I think the `ICollection` is the best option. However, it should be your responsibility to use the input properly, not the responsibility user of your code to give proper input. Avoid throwing errors unless there is no reasonable way to use the given input.

2. `SortedSet` or `SortedList`: As you said, this is even more restrictive. If, for whatever reason, the input to the function is in a different form, you, again, should be responsible for properly using the input.

3. `ICollection` without checks: While documentation is good, there are plenty of people that don't always read it. This approach could lead to errors that would take a long time to identify and solve.

Basically, it should be the programmer's responsibility that his/her code works, preferably with minimal restrictions. I'm not overly familiar with C#, but when I'm writing Java, I prefer to make my parameters `Collection`s or `List`s rather than `SortedSet`s or `Stack`s. If I do need a `SortedSet`, I'll still ask for a `Collection` and then copy and sort it by converting it to a `SortedSet` or using built-in sort methods. In C# the `List<T>` class has a `Sort` method, and converting between Collection types doesn't seem too difficult, even if you need to use a for-each loop. If you care a lot about performance, and doing this conversion is too resource-intensive, I would use your second option (a `SortedList` or `SortedSet`). If writing each twice is too much work for you, you can pick one, and have the other one be converted and passed into the method, warning users that it would be less efficient.

Hope this helps!

The line `if (fst.ub >= snd.lb)`, where you check if they are in order gives a clue to your solution. You know whether they are in order, so you know how to sort them. So have `Interval` implement `IComparable<Interval>` and add the following code:

``````public void UniteWith(IEnumerable<Interval> intervals)
{
var sortedIntervals = intervals.OrderBy(i => i);
...
// do stuff with your ordered set of intervals
}

public int CompareTo(Interval other)
{
if (ub < other.lb) return -1;
if (lb > other.ub) return 1;
return 0;
}
``````

Also, I'd question your use of `void` here. Would it not be better to create a new `Interval` and return that, leaving the current one unchanged?

• Internally, I do create a new interval and leave the current one unchanged. Since the method is about modifying the collection, I don't see a reason for returning the new interval. Maybe I should return the modified collection instead, or a bool saying if the collection changed. So thanks for the hint! – Kjara Jul 28 '16 at 5:37