Type conversions

I'd like to be able to write a function that accepts mutiple parameters but only of a certain types. Let's say that String and Int are allowed but not Double:

foo("a", 1) // compiles foo("b", 2.0) // won't compile, doubles are not allowed

In Scala, I would define implicits for each valid type, these implicits would convert to MyObject and my function would simply accept MyObject parameters.

I can’t come up with a way to do this in Kotlin. The first step seems to be to define extension functions on String and Int, but past this, I’m stuck.

Is there a way that I’m no seeing? Such a feature would go a long way toward making DSL’s less clutterered…

May be simple overloading will help you?


fun sum(a:Int, b:Int) = a + b
fun sum(a:Int, b:String) = sum(a, b.toInt())

fun main(args : Array<String>) {
  assert(sum(2, 2) == sum(2, “2”))

That's not good enough for DSL's, vararg support is mandatory.

Kotlin has no implicits, so there's no way of doing this for library types such as String and Int

That's what I thought, thanks Andrey.

I was playing with the idea of providing some limited implicit support (only for type conversion). Since it’s so easy to define extension functions in Kotlin, the compiler could look for functions with a certain signature, e.g.

fun to() : T

For example, I could define an implicit conversion from Int to MyClass:

fun Int.to() : MyClass {   return new MyClass(this) }

and then a function taking a MyClass can be passed an Int:

fun f(mc: MyClass) {   ... }

f(3); // will be converted automatically

I think the argument "We can't figure out what's going on" is silly, especially in languages that support extension functions. We have great IDE support already which can tell us everything we need to know without having to browse anything. For example, putting the cursor inside the parenthesis at the call site and pressing Ctrl-p would display all the signatures, both with explicit and implicit parameters.

The reason why I’m suggesting this is that Kotlin is emphasizing its support for DSL but I feel that without this kind of conversion support, DSL’s are severely crippled.

1 Like

Kotlin is deliberately designed to have no implicit conversions, the closest our feature exploration got to that is a provisional "explicit conversion operator": ~x (compiled to x.to()), so that you can always see where a conversion is performed.

There’s a technical problem with this kind of solution though (as well as the one you propose): two ordnary functions that differ only in the return type, to(): T and to(): T1, can not reside in the same class in Kotlin, becauseno overload resolution can discriminate the two. We could in principle hack the typechecker to skip this rule for functions named “to”, but this doesn’t seem exactly like a clean solution. And you wouldn’t be happy anyways, because the conversion is explicit.

Yes, I understand the limitations. I don't feel too strongly about this feature since I don't write a lot of DSL's myself, but I just thought I should point out that if one of Kotlin's claim to fame is DSL, then the absence of automatic conversions limits what can be done in this area. Instead of writing

myDsl { “a”, 1, ‘c’ }

I have to write:

myDsl { “a”.toObj(), 1.toObj(), ‘c’.toObj() }

or something along these lines.

Obviously, you can also have your closures accept vararg Any arguments and perform runtime casts. Not as elegant, but it keeps the DSL clean.

Overall, I have always been ambivalent about type conversions, probably because I was traumatized by them in C++ 20 years ago. However, I have softened up a bit on the topic because today’s IDE make it trivial to find out what’s going on, which wasn’t the case writing C++ on emacs in the 90’s, especially if you keep the design of type conversions very narrowly focused (Scala’s implicits are very powerful but since they are used to do more than type conversions, the result can lead to very confusing code).

If I could find other examples than DSL creation where type conversions can lead to elegant and readable code, I’d weigh in their favor more forcefully. Still looking.

Well, here's another useful example for type conversions, posted just a few days after my initial post:


I think the data in support of type conversions is piling up.

I am not the target for DSL capability of Kotlin but I'd like to see more diverse DSL scenarios than just these JSON DSLs.