# Implicit conversions in Scala help with DRY

Are you tired of hearing about how verbose Java is? Semicolons are mostly optional in Kotlin (and in Scala, too). Big deal. Slightly more significant are type declarations. For example:

`CopyOnWriteArrayList<File> recentFiles = new`

CopyOnWriteArrayList<File>();

Oracle has taken steps to cut down on that sort of verbosity in Java. Also, IntelliJ’s auto-complete makes it a breeze to put in declarations like that (NetBeans not so much).

In Scala, there are much more significant ways in which the language helps you cut down on repetition.

One of those ways is that Scala allows you to define implicit type conversions. Another way is with default parameters, which I will briefly address later on.

I think I first read about implicit type conversions in C++ a couple of decades ago, if I recall correctly. Or it could have been about implicit type conversions in C#, but much more recently.

The concept didn’t really make sense to me until I read Cay Horstmann’s *Scala for the Impatient*, First Edition (the Second Edition is available now a couple of different ways, each through the author’s website).

For several concepts, Horstmann uses fractions as examples. Fractions make for much better examples than most toy examples he or I or anyone else can think of.

I suppose for some people fractions might seem like a toy example, but even so, they are easy to understand and I think they make it very easy to see how the concept could be applied to an actual program that you’re working on.

And unlike complex numbers, there is no need to stop to explain a simple mathematical concept that most people are unfamiliar with. Though I have seen complex numbers used to explain implicit conversions.

An integer is a fraction that happens to have 1 for a denominator (likewise, a real number is a complex number that happens to have 0 for an imaginary part).

If we have a `Fraction`

class in our program, we naturally want to be able to do arithmetic with fractions and integers. We want to be able to do things like subtract 8 from 73/4 (that should be 41/4).

Here’s an excerpt from a `Fraction`

implementation in Java:

public Fraction plus(Fraction addend) {

long interNumerA = this.fractNumer * addend.fractDenom;

long interNumerB = addend.fractNumer * this.fractDenom;

long newNumer = interNumerA + interNumerB;

long newDenom = this.fractDenom * addend.fractDenom;

return new Fraction(newNumer, newDenom);

} public Fraction plus(int addend) {

Fraction tempAddend = new Fraction(addend, 1);

return this.plus(tempAddend);

}

Actually, I did come up with a slightly more elegant solution for my own Java program, but this is adequate for the example.

It’s a similar situation with `Fraction.minus(int)`

: we create a temporary instance of `Fraction`

for the `int`

and then call `Fraction.minus(Fraction)`

. And likewise for `Fraction.times(int)`

and `Fraction.divides(int)`

.

The conversion is a bit repetitious. As you know, DRY means Don’t Repeat Yourself. How do we cut down on the repetitions of the `int`

to `Fraction`

conversion?

In Scala, we can define an implicit type conversion. Now follows an almost complete source listing for a Scala implementation of `Fraction`

:

package fractionsobject Fraction { import scala.language.implicitConversionsimplicit def IntToFraction(n: Int) = {

// This next line is for educational purposes only

System.out.println("Implicit conversion invoked")

// This next line does the actual conversion

new Fraction(n, 1)}class Fraction(numerator: Long, denominator: Long = 1L) {

}

// TODO: Throw exception if denominator is 0

// TODO: Make sure denominator is positive

// TODO: Put fraction in lowest terms with gcdNumDen =

gcd(numerator, denominator)

val fractNumer = numerator / gcdNumDen

val fractDenom = denominator / gcdNumDen // TODO: Override toString def +(addend: Fraction): Fraction = {

val interNumerA = this.fractNumer * addend.fractDenom

val interNumerB = addend.fractNumer * this.fractDenom

val newNumer = interNumerA + interNumerB

val newDenom = this.fractDenom * addend.fractDenom

new Fraction(newNumer, newDenom)

} def unary_- = new Fraction(-this.fractNumer, this.fractDenom) def -(subtrahend: Fraction): Fraction = {

this + (-subtrahend)

} def *(multiplicand: Fraction): Fraction = {

val newNumer = this.fractNumer * multiplicand.fractNumer

val newDenom = this.fractDenom * multiplicand.fractDenom

new Fraction(newNumer, newDenom)

} def /(divisor: Fraction): Fraction = {

if (divisor.fractNumer == 0) {

val exceptionMessage = "Dividing " + this.toString

+ " by 0 results in an indeterminate number."

throw new IllegalArgumentException(exceptionMessage)

}

val newNumer = this.fractNumer * divisor.fractDenom

val newDenom = this.fractDenom * divisor.fractNumer

new Fraction(newNumer, newDenom);

} def reciprocal: Fraction = {

if (this.fractNumer == 0) {

val exceptionMessage = "Reciprocal of 0 is indeterminate"

throw new IllegalArgumentException(exceptionMessage)

}

new Fraction(this.fractDenom, this.fractNumer)

}}

During refactoring, we might ponder whether it would be a good idea to rewrite the division function to a one-liner with `this * divisor.reciprocal`

, and thus throw a division by zero exception in only one place instead of two.

In Java, I like to put all the constructors at the end of a class. Can’t do that in Scala, because the primary constructor is “fused” with the class declaration.

Notice that in the Scala version I renamed `plus()`

, `negate()`

, `minus()`

, `times()`

and `divides()`

as `+`

, `unary_-`

, `-`

, `*`

and `/`

, enabling us to operate on instances of `Fraction`

as if they were built-in numeric primitives.

This is one of those features of Scala that we’re trusted to use in good taste when it is appropriate to do so. Meaning, for example, that we’re not going to define `+`

to mean something counter-intuitive, like `removeAll()`

.

Just in case you’re wondering, the `Fraction`

object and the `Fraction`

class could be placed in the same source file even if they didn’t have the same name.

That’s another feature we’re trusted to use appropriately. Notice also that `scala.language.implicitConversions`

gets imported for use only within the scope of the `Fraction`

object, since the `Fraction`

class doesn’t need it.

If you want to follow along on your computer, make sure to take care of the TODO’s. You might also have to tweak one or two line breaks.

I typed the above source listing for `Fraction.scala`

into Notepad, compiled it on the command line with `scalac`

and then loaded `Fraction.class`

into the Scala REPL that I have locally on my computer.

You might notice that `scalac`

creates two `*.class`

files from `Fraction.scala`

: `Fraction$.class`

and `Fraction.class`

. Given that the former is barely a kilobyte and the latter is slightly more than four kilobytes, I would venture to guess the former is the object and the latter is the class.

You can also follow along in Scastie (which I wrote about last week), though I recommend omitting the line `package fractions`

and instantiating fractions as `new Fraction`

rather than `new fractions.Fraction`

, as you’ll see in the quotes from the local Scala REPL below.

On the local Scala REPL, I obtained the following results:

scala> var numberA = true.hashCode

numberA: Int = 1231scala> var numberB = new fractions.Fraction(7, 12)

numberB: fractions.Fraction = 7/12scala> numberA + numberB

Implicit conversion invoked

res0: fractions.Fraction = 14779/12scala> numberA - numberB

Implicit conversion invoked

res1: fractions.Fraction = 14765/12

The words “Implicit conversion invoked” appear because I included that `println`

in `IntToFraction`

. They’re there only for the sake of this article; there would otherwise be no `println`

there.

In Scastie, you can put these lines at the end in the main Editor area:

`var numberA = true.hashCode`

var numberB = new Fraction(7, 12)

numberA + numberB

numberA - numberB

Once you hit Run, assuming there are no compilation errors to deal with, you will see something like this, but a bit more colorful:

`numberA + numberB 14779/12: Playground$Fraction`

numberA - numberB 14765/12: Playground$Fraction

The implicit conversion messages will appear in Scastie’s Console area, which is less colorful than the Editor area.

Of course we can bypass implicit conversion for some functions, if we want to. For example, for the multiplication of a fraction by an integer:

` def *(multiplicand: Int): Fraction = new Fraction(this.fractNumer`

* multiplicand, this.fractDenom)

The implicit conversion will still occur if the first multiplicand is an `Int`

rather than a `Fraction`

. The result should be the same regardless of whether or not implicit conversion occurs.

scala> numberA * numberB

Implicit conversion invoked

res2: fractions.Fraction = 8617/12scala> numberB * numberA

res3: fractions.Fraction = 8617/12

This could have implications for programs involving non-commutative algebra, but that’s outside the scope of this article.

I seriously doubt implicit conversions cause any kind of measurable performance penalty, even with more involved types.

And in a more involved type, making changes to the “primary” functions would probably require us to also make changes to the functions with repeated conversions.

In such a case, the benefits of implicit conversion would include reduced redundancy leading to a greater facility for making changes. There are downsides to implicit conversion, but noticeably slower program performance would most likely not be one of them.

For the sake of completeness, we should check division…

`scala> numberA / numberB`

Implicit conversion invoked

res4: fractions.Fraction = 14772/7

This means we should also check division by zero:

`scala> numberB / 0`

Implicit conversion invoked

java.lang.IllegalArgumentException: Dividing 7/12 by 0 results in an indeterminate number.

at fractions.Fraction.$div(Fraction.scala:62)

... 28 elided

Depending on your system, you might notice a little delay between the implicit conversion message and the exception message. I think this says more about the REPL than the compiler or the Java Virtual Machine.

If we changed the division function as discussed earlier, our exception message would probably have to be a lot less specific, something like “Division by zero encountered.”

At least on the REPL it would be very easy to distinguish between division by an instance of `Fraction`

that is arithmetically equal to 0, division by an `Int`

equal to 0 that was implicitly converted to `Fraction`

, and trying to take the reciprocal of an instance of `Fraction`

that is arithmetically equal to 0.

Hmm… I wonder if I can now use the implicit conversion to get the reciprocal of an `Int`

?

scala> numberB.reciprocal

res7: fractions.Fraction = 12/7scala> numberA.reciprocal

<console>:13: error: value reciprocal is not a member of Int

numberA.reciprocal

^

Oh well, it was worth a try. Or maybe someone in the comments will let me know of an elegant way to accomplish this.

Default parameters in constructors are somewhat related to implicit conversions, but they are different concepts. You might have noticed this tidbit in the Scala implementation of `Fraction`

shown earlier:

`class Fraction(numerator: Long, `**denominator: Long = 1L**) {

...

}

It’s a convenience that allows us to define instances of `Fraction`

that are arithmetically equal to 64-bit signed integers as `new Fraction(numerator)`

rather than `new Fraction(numerator, 1)`

, saving us two or three keystrokes.

`scala> var numberC = new fractions.Fraction(47)`

numberC: fractions.Fraction = 47

No implicit conversion here, at least none that we defined; `numberC`

was initialized with a default parameter in the primary constructor. In Java we could have this same convenience with a chained constructor.

` public Fraction(long numerator) {`

this(numerator, 1);

}

It is worth noting that Java does have a few implicit conversions, like `int`

to `long`

. I believe this is what allowed us to use `true.hashCode`

as the numerator parameter for the `Fraction`

constructor even though it’s an `Int`

rather than a `Long`

.

Also, in Scala it’s not necessary to explicitly call `toString()`

when concatenating into a `String`

, and it’s not necessary in Java either. I think it’s good form anyway, though I expect some disagreement in the comments.

In summary, implicit conversions in Scala can help us avoid repeating the same type conversion in several functions that are expected to be able to handle two or more specific types.

Also, default parameters in primary constructors can help reduce the need for chained constructors.

In the Java version of `Fraction`

, the chained constructor and the `int`

overloads for the arithmetic functions account for just a few lines in the source.

However, it doesn’t take a stretch of the imagination to see that, in a class with a lot more properties and actions, multiple constructors and functions overloaded for explicit conversions could add up to a lot of redundancy.

The benefits of reduced redundancy through implicit conversions vastly outweigh the unlikely cost of slower program performance.