# Proposal: conversion method "into"

**URL:** <https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435>\
**Category:** Language Design\
**Created:** [August 12, 2022, 10:22am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435 "2022-08-12T10:22:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 12, 2022, 10:22am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/1 "2022-08-12T10:22:42Z")

</div>

Allow easy conversion between types. E.g.

```kotlin
fun String.into(): URL = URL(this)

```

The call site could look like

```kotlin
fun sendRequest(url: URL) {}
sendRequest("https://example.com".into())

```

In case of diamond problem, it could be resolved by explicitly stating the type

```kotlin
interface A
interface B: A
interface C: A
fun SomeClass.into(): B {}
fun SomeClass.into(): C {}

fun foo(a: A) {}

fun main() {
    val s: SomeClass
    foo(s.into()) // Ambiguity exception
    foo(s.into<B>()) // OK
    foo(s.into<C>()) // OK
}

```

Or even allow implicit casting in a block:

```kotlin
fun String.into(): URL {}
fun sendRequest(url: URL) {}

fun main() {
    autoConvert(URL::class) {
        sendRequest("https://example.com"/*Automatically into'd into URL*/)
    }
}

```

Edit:  
This can also maintain Java interoperability by using the `toX()` pattern, `A.into(): B` would be `A.toB()`

---

<div class="post-metadata">

**Author:** ![al3c](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@al3c](https://discuss.kotlinlang.org/u/al3c)\
**Post date:** [August 12, 2022, 10:45am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/2 "2022-08-12T10:45:35Z")

</div>

> [@Ciel](#):
>
> Allow easy conversion between types. E.g.
> 
> ```auto
> 
> ```

Doesn’t this just work with Kotlin as-is?

> [@Ciel](#):
>
> Or even allow implicit casting in a block:
> 
> ```auto
> 
> ```

Automated coversions are very often a bug farm. Kotlin design went for not doing any automated conversion.

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 12, 2022, 10:50am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/3 "2022-08-12T10:50:51Z")

</div>

> Doesn’t this just work with Kotlin as-is?

Well if you want to achieve the demonstrated method, it

1. requires a hacks to check what type it is, and then return to it with a cast, like the pattern `get(Class<T>): T`
2. Doesn’t allow for externally declared conversion methods, like String.into(): URL in the example  
Edit:  
You _can_ do something with reflection and get “to$class.simplename”, but that means it is resolved at runtime instead of compile time, and additional checks have to be done, instead of it being statically resolved at compile time. Which is, again, a hack and doesn’t allow for extension.

> Automated coversions are very often a bug farm. Kotlin design went for not doing any automated conversion.

Indeed it is, that’s why I didn’t say it should be fully automated, the idea behind the block is to only allow a certain type to be automatically converted, similar to the idea of `with`, though I can understand why it might not be the part of the final addition, which is why I said “or even” 🤔

---

<div class="post-metadata">

**Author:** ![tom000](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tom000](https://discuss.kotlinlang.org/u/tom000)\
**Post date:** [August 15, 2022, 4:00pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/4 "2022-08-15T16:00:10Z")

</div>

This (well, without the automatic conversion part) is in fact a special case of a more general pattern – allowing functions with signatures which are identical except for the return type, disambiguating between them by expected and/or explicitly mentioned return type at call site – right?

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 15, 2022, 4:13pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/5 "2022-08-15T16:13:02Z")

</div>

Well, not exactly, it can be trivially compiled into JVM like “toA”, “toB” etc, it’s just such a commonly used pattern I think there should be some standard to it. I wouldn’t put it in the same basket exactly, since resolving the collision isn’t the main point here.

---

<div class="post-metadata">

**Author:** ![tom000](https://avatars.discourse-cdn.com/v4/letter/t/3e96dc/32.png) [@tom000](https://discuss.kotlinlang.org/u/tom000)\
**Post date:** [August 15, 2022, 4:21pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/6 "2022-08-15T16:21:45Z")

</div>

Hm, you say resolving the collision isn’t the main point, but unless I’m missing something this collision is the only reason why this (again, excluding the auto-conversion part) can’t be done in Kotlin currently, right?

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 15, 2022, 4:58pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/7 "2022-08-15T16:58:44Z")

</div>

Well, not exactly, unless return type collision is clarified via a type parameter(which I doubt it would), it wouldn’t be the same.  
Im more inclined to think of it as `fun < T > into(): T` which is then dispatched at compile time.

---

<div class="post-metadata">

**Author:** ![usrusr](https://avatars.discourse-cdn.com/v4/letter/u/858c86/32.png) [@usrusr](https://discuss.kotlinlang.org/u/usrusr)\
**Post date:** [August 17, 2022, 3:32pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/8 "2022-08-17T15:32:34Z")

</div>

What’s wong with `myString.let(::URL)`? It’s certainly a little longer than `URL(myString)` but it shares the nice left-to-right of the .into() proposal that the direct constructor call lacks.

The String → URL example is a constructor call and those shouldn’t be more hidden than necessary.

What I miss far more (and just dealt with a few days ago with an inline that I certainly wouldn’t mind seeing in the standard library) is casting in “dot order”:

`(x as Y)` is certainly an improvement over java’s parentheses-hell of `((Y)x)` and `as?` beats the java equivalent by an even larger margin, but they still require jumping back for parentheses if x is a complicated expression.

`x.asOrNull<Y>()?.someYMethod()` would work nicely left-to-right no matter how complicated x actually is. (the as-sans-? variation `any.asOrCrash<Y>()` might seem a little overdramatic in naming, but I do like the explicit “OrNull” in autocomplete lists)

---

<div class="post-metadata">

**Author:** ![donaldtam](https://avatars.discourse-cdn.com/v4/letter/d/ad7895/32.png) [@donaldtam](https://discuss.kotlinlang.org/u/donaldtam)\
**Post date:** [August 17, 2022, 8:27pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/9 "2022-08-17T20:27:24Z")

</div>

You can do

```auto
fun String.toUrl(): URL = URL(this)

```

then you can do this:

```auto
sendRequest("https://example.com".toUrl())

```

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 18, 2022, 10:03am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/10 "2022-08-18T10:03:46Z")

</div>

Not everything can be converted this way, the example was only for illustrative purposes anyway.

The proposal is not about changing the casting system, it’s to standardize the `toX` pattern that was used a lot.

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 18, 2022, 10:06am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/11 "2022-08-18T10:06:14Z")

</div>

That’s exactly what this pattern was aiming to solve D: the `toX` pattern is commonly used, and standardising it on a language level could be nice. Especially since this way, the type can be implicit. But the `toX` would be how its presented when interoperating with Java 😉

---

<div class="post-metadata">

**Author:** ![donaldtam](https://avatars.discourse-cdn.com/v4/letter/d/ad7895/32.png) [@donaldtam](https://discuss.kotlinlang.org/u/donaldtam)\
**Post date:** [August 18, 2022, 11:10am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/12 "2022-08-18T11:10:57Z")

</div>

If I understand you correctly, you would like for the compiler to automatically generate these functions for you?  
For example:

```auto
// say I have a custom class
class Point {
    var x = 0
    var y = 0
}

// and I have another class
class IntPair {
    var first = 0
    var second = 0
}

```

How would the compiler know how to convert between the two classes?

```auto
val point = Point()
val converted: IntPair = point.into() // how would the compiler generate .into()?

```

If I have a vastly different class, how would the auto-generation of these conversion methods work?

```auto
class User(
    val name: String,
    val age: Int,
    val height: Float
)

val user = User("Josh", 24, 172.3F)
val converted: IntPair = user.into() // how?

```

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 18, 2022, 11:14am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/13 "2022-08-18T11:14:43Z")

</div>

No… I want compiler to decide which method to call…  
The user would define  
fun Point.into(): IntPair = IntPair(x, y)  
fun Point.into(): Pair\<Int, Int\> = x to y

fun foo(pair: IntPair) {}

val point: Point

foo(pair.into()) // automatically calls the one that returns IntPair

which is stated quite clearly in my original post imo.

---

<div class="post-metadata">

**Author:** ![donaldtam](https://avatars.discourse-cdn.com/v4/letter/d/ad7895/32.png) [@donaldtam](https://discuss.kotlinlang.org/u/donaldtam)\
**Post date:** [August 18, 2022, 11:17am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/14 "2022-08-18T11:17:40Z")

</div>

If I understand correctly, does that mean you want the standardization of conversion methods and the benefit of not having to type potentially longer name like .into() instead of .toURL() or .toJSON()?

Because you also still need to manually write the conversion methods.

Edit: I just now understood your intention

IMO the benefit is trivial and isn’t worth standardizing.  
I only see the point in standardizing conversions if they enable implicit conversions so you don’t even have to type .into() like you can do in C++  
But again, the Kotlin team has decided to not allow implicit conversions

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 18, 2022, 11:19am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/15 "2022-08-18T11:19:15Z")

</div>

That is correct, the point is just to unify all conversion methods into one method, `Any#into()`. Rust has a trait for this purpose. See [Into in std::convert - Rust](https://doc.rust-lang.org/std/convert/trait.Into.html)

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 18, 2022, 11:22am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/16 "2022-08-18T11:22:43Z")

</div>

I think this works well for Kotlin because despite not using a trait system, the extension methods can be used to achieve the same effect.

---

<div class="post-metadata">

**Author:** ![arocnies](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/arocnies/32/5143_2.png) [@arocnies](https://discuss.kotlinlang.org/u/arocnies)\
**Post date:** [August 19, 2022, 1:37am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/17 "2022-08-19T01:37:33Z")

</div>

I think it would make sense to consider use cases and the core problems it solves.

For me, I don’t see an `into` operator or adding it as a member of the Top class `Any` to be strong enough to overcome the [minus 100 points](http://stronglyemergent.com/blog/2013/negative-100-points/) rule. Yes, it has some pros but it’s not so beneficial on its own to be convincing.

Instead, a trait system, type classes, and other more powerful language concepts that would enable this style of conversion might be a better consideration.

---

<div class="post-metadata">

**Author:** ![Ciel](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ciel/32/9351_2.png) [@Ciel](https://discuss.kotlinlang.org/u/Ciel)\
**Post date:** [August 19, 2022, 6:52am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/18 "2022-08-19T06:52:05Z")

</div>

Fantastic point, I had a similar feeling when I was thinking about the system. I wouldn’t be that upset either if it doesn’t get added, I just thought it could be a useful feature and made a proposal. 😛

---

<div class="post-metadata">

**Author:** ![usrusr](https://avatars.discourse-cdn.com/v4/letter/u/858c86/32.png) [@usrusr](https://discuss.kotlinlang.org/u/usrusr)\
**Post date:** [August 19, 2022, 8:59am UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/19 "2022-08-19T08:59:50Z")

</div>

Annotate single-arg constructors to generate an .into or a .toX extension function with the parameter type as receiver?

I’m decidedly in the camp of those who wouldn’t like it at all to see this generated automatically for _all_ single-arg constructors, because there are plenty of cases where the semantics are completely different (e.g. a mutable class with some form of owner/patent reference, that’scertainly not “the same data, but in a different shape”). Perhaps default for data classes?

And in the question of .into vs .toX, I’d prefer .toX by a wide margin. Because reading is important (reading would be one of the prime benefits of this entire thing, y.toX() would read better than X(y), particularly for non-trivial expressions in the place of y)

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 19, 2022, 5:50pm UTC](https://discuss.kotlinlang.org/t/proposal-conversion-method-into/25435/20 "2022-08-19T17:50:18Z")

</div>

I agree with @tom000 . If Kotlin would support overloading functions by their return type, then I think your `into()` would be possible and it would become just a convention. I’m not sure, what do you mean here:

> [@Ciel](#):
>
> Well, not exactly, unless return type collision is clarified via a type parameter(which I doubt it would), it wouldn’t be the same.
