4
votes

Implicit conversions seem to be a major and controversial feature of Scala, while they seem to have far less prominence in C#. What's the difference between them in the two languages? Is there anywhere I'm forced to use implicits in Scala, or can I always choose whether I want the conversion to be implicit or explicit as in C#? Often in C# I liked to make conversions explicit so as to maintain type-checking of the programmers intent, even if the consumer is myself.

Am I right in saying that neither C# or Scala can implicitly split or combine method / function parameters? As in def myMethod(v1: Int, v2: Int) will not accept a Tuple2[Int, Int] as its parameter list and a def yourMethod(v1: Tuple2[Int, Int]) will not accept two ints as its parameter list. Presumably implicit/ explicit parameter splitting / combining must have been considered by the language designers. I do find this feature desirable when using the multiple but similar graphics library's point structures.

2

2 Answers

9
votes

The key difference between Scala and C# implicit conversion is the much more flexible scoping rules in Scala, which lets you define which and where implicit conversion are available in which scopes.

While in C# an implicit conversion is a way to say that one of your class can be seen as another class, in Scala it allows you to decorate your class adding specific features only in certain context.

Additionally, while implicit conversion in C# needs to be defined in the class itself, in Scala you are allowed to add implicit conversions externally, which is a powerful tool to decorate pre-existing classes: Scala comes with a set of predefined explicit conversions.

3
votes

major and controversial feature

I have somehow missed the controversy, so I doubt it is a major one.

Implicit conversions are available, but generally frowned upon by experient Scala developers, depending on the specifics.

When an implicit conversion exists to add a method to a type through an "extension" class, then it's accepted. This extension class is not a type used as a type for parameters, definitions or variables, nor do its methods return itself, but the original type where applicable.

When an implicit conversion converts between two types that are normally used in a program, it is considered a bad thing. In fact, Scala 2.10 will come with warnings against this kind of usage.

The distinction can clearly be seen in the two packages available to convert between Java and Scala collections: scala.collection.JavaConversions and scala.collection.JavaConverters. The latter exists precisely because the implicit conversion style used in the former was considered bad.

Scala does allow you to make an implicit conversion not available inside a specific scope, but I have rarely seen it used. On the other hand, the flag -Xlog-implicit-conversions allows you to keep track of where implicit conversions are happening.

There aren't many implicit type conversions in the default scope in Scala. A String can be seen as a Seq[Char], and "primitive" numeric types have type widening -- that is, smaller types can be seen as larger types. There might be others I don't remember right now, but, generally speaking, you'll have to import an implicit conversion to use it.