I personally prefer to make the error state part of the objects: Streams can be in an error state, floats can be NaN and integers should be low(int) if they are invalid (low(int) is a pointless value anyway as it has no positive equivalent).
It's fine to pick sentinel values for errors in context, but describing 0x80000000 as "pointless" in general with such a weak justification doesn't inspire confidence. proc fib[T: Fibable](a: T): T =
if a <= 2:
result = 1
else:
result = fib(a-1) + fib(a-2)
Integer is the only possible type for T in this implementation, so what was the point of defining Fibable?I think the fib example is actually cool though. Integers are not the only possible domain. Everything that supports <=, +, and - is. Could be int, float, a vector/matrix, or even some weird custom type (providing that Nim has operator overloading, which it seems to).
May not make much sense to use anything other than int in this case, but it is just a toy example. I like the idea in general.
However, the base case being 1 does not preclude other types than integers, as cb321 pointed out.