# Handling function partiality

Consider the following snippet:

```
def isqrt_option(num: Int): Option[Int] = {
num match {
case x if x >= 0 => Some(math.sqrt(x).toInt)
case _ => None
}
}
```

Conceptually, `isqrt_option`

is a partial function from natural numbers to natural numbers that returns square root of its input rounded down. It has a particular flavour of partiality as I will explain soon.

## Flavours of partiality - the callee side

There are many ways to implement a partial function. We have already seen how we can use `Option`

al return values to implement partiality. We can similarly use `Either`

:

```
final case object NegativeInputArgument(value: Int)
def isqrt_either(num: Int): Either[NegativeInputArgument, Int] = {
num match {
case x if x >= 0 => Right(math.sqrt(x).toInt)
case x => Left(NegativeInputArgument(x))
}
}
```

Sometimes you want to use an `assert`

ion instead because of some really complex type refinement (e.g. inter-dependency between multiple input data structures), that would be difficult to express in types without a dependently typed language (or even then!):

```
/**
* @param num non-negative integer
*/
def isqrt_assert(num: Int): Int = {
assert(num >= 0)
math.sqrt(x).toInt
}
```

Alternatively, we can use type refinements (using `refined`

Scala library or something similar).

```
final case class NonNegInt private (value: Int) {
assert(num.value >= 0)
}
object NonNegInt {
def refine(i: Int): Option[NonNegInt] =
if (i > 0) Some(NonNegInt(i))
else None
// A macro would allow us to specify literal non-negative integers.
implicit def literal(x: Int): NonNegInt = macro applyImpl
}
def isqrt_refined(num: NonNegInt): Int =
math.sqrt(num.value).toInt
```

## The caller side

Imagine that a caller of `isqrt`

function has already verified that num is positive:

```
val num = ...
if (num > 0) {
...
val r = isqrt_option(num)
r match {
case Some(x) => ...
case None =>
// OOPS, what do we do here?
}
}
```

We can see that using `Option`

al return values just moves partiality to the call-site. The problem is that even though we know that `num > 0`

, most modern compilers are not able to infer that the `None`

case is impossible (the only exception that I know of is Code Contracts for C#, which has some very similar functionality).

Let’s see how the same code would look like if we used `isqrt_assert`

:

```
val num = ...
if (num > 0) {
...
val r = isqrt_assert(num)
// No need to match on r, it's already an Int.
...
}
```

Notice that this coding style will necessarily result in some runtime failures due to your logical errors (which are bound to happen sooner or later!), but it is mighty convenient.

Using the refinement-based solution:

```
val num = ...
NonNegInt.refine(num) match {
case Some(num) =>
...
val r = isqrt_refined(num)
// No need to match on r, it's already an Int.
...
case None =>
...
}
```

Beautiful. But… what if we wanted to compute a square root of a square root?

We have to modify the definition of `isqrt_refined`

:

```
def isqrt_refined(num: NonNegInt): NonNegInt =
NonNegInt.make(math.sqrt(num.value).toInt) match {
case Some(n) => n
case None => ???
}
```

With a better compiler or language perhaps this could have been avoided, but sooner or later, the `assert`

s will creep back in into your code. In dependently typed languages that will happen when you are just too tired to prove some property of your code, so you invoke `believe_me`

. And no matter how good a compiler is, the halting problem will prevent it from proving *all* of potential code properties (but it could still have insanely large coverage, being able to say prove 99.999999% of all properties).

Don’t hate the `assert`

, it is your friend! You just need to learn to use it in a tasteful way.