A strange idea about `->`


#1

I was just writing some DSL, where infix to operation is used a lot to append values and nodes to the tree and a strange I’ve got a strange idea.

Let us imagine that to is an operator function and is representing arrow -> binary operation. My DSL would transform from something like this:

{
  "a" to 22
  "b" to {
    "c" to "myValue"
  }
}

to something like this:

{
  "a" -> 22
  "b" -> {
    "c" -> "myValue"
  }
}

Not a huge difference, but readability is slightly better. It would also resolve the complaints about map declaration syntax and to operator:

  mapOf(
    "a" -> 11,
    "b" -> 33
  )

But the most important part is a when expression. It always irritated me that while all other kotlin constructs like if and while have function syntax and could be in fact replaced by functions, when introduces different syntax. With -> as operator, when actually becomes regular function where each clause is a statement.

I do not say that this idea should be implemented, and there are probably some syntax issues preventing it (for example, -> is used in function definitions and I am not sure it is possible to separate those two cases), but I just wanted to share the thought while I have it.


#2

Disagree, you’ve changed two easily typed/read characters into difficult ones and changed the language while at it, but let’s discuss…

This isn’t really a unique idea, you’re idea is exactly what is done in Scala to create tuples. In Kotlin, to is not part of the grammar, just a simple extension function that combines the receiver and parameter into a pair. Same in Scala, ->is not part of the language, but a function. Meaning in Kotlin or Scala you could write this yourself if you wanted. But Kotlin very consciously choose not to allow these types of sigils as unescaped identifiers or you end up with the crazy sets of operators you see in Scala. And it would make little sense to change this to a grammar-supported binary operator for this purpose like they do with arithmetic operators.

I hope that clears things up a bit. If you want this, by all means, create your own infix extension for it and escape with backticks every time, but supporting it with out backticks requires changing the core language for no benefit IMO.

Now, there may be arguments to be made for collection literals (I’m against those) and for language defined tuples instead of Pair/Triple (I’m for this for various reasons around destructuring and currying).


#3

I do understand your position and if you look into previous discussions, I was advocating exactly the same position. I do not propose this to be implemented (at least in current kotlin, maybe in 2.0) for the reasons you mentioned. Also I am not talking about custom scala-like symbolic operations, only about binding function to operator like plus is bound to +. But one needs to understand that to, while being simple infix function, has very broad application in kotlin, so maybe it requires special treatment.

It would not worth mentioning at all if not for the last statement in my post. The when expression is the only part of kotlyn syntax (as far as I remember) that could not be replaced by function. I think that replacing it by function-like syntax is worth discussing just because it is beautiful. Again, I do not propose to implement it straight away.


#4

I like the idea but I don’t think there will ever be a way to implement something like when as a function, because when supports pattern matching (or a limited form of it).
I’m personally not sure about collection literals, especially about an operator to create pairs. I like the design of the to function because it is simple and does not need any additions to the compiler. That being said -> is probably the nicest operator that could be added to Kotlin for this IMO. Still I don’t like that it is also used for lambda declaration. It might lead to problems with lambdas generating pairs. { a -> it } would be ambiguous.

I would love to see some sort of n-Tuple syntax though once there are value types and they can be implemented in Kotlin without unnecessary boxing. Maybe together with multiple return values (but I’m just dreaming of the future right now)


#5

I disagree there and on the -> wrt looks, but I suppose it’s in the eye of the beholder. But even if I didn’t, there are language ambiguities with lambdas. For example:

fun foo(v: (Pair<Any?, Any?>) -> Pair<Any?, Any?>) {
    val (one, two) = v("a" -> "b")
    println("1: $one, 2: $two")
}

fun main(args: Array<String>) {
    foo { it -> it }
}

With this change, what does that print? Does it print 1: a, 2: b or 1: (a, b), 2: (a, b). Regardless, these little things are definitely not worth inclusion IMO and are not any more of a special case as when the next person comes along and says they want ++= or <- or anything else.


#6

Yes, I think the pattern matching blocks the idea at least with current koltin syntax. Still, it is interesting to think about.


#7

a little puzzle : assuming this code val x = "a"
{ x -> "b"} is:

  • a (Any?) -> String
  • a () -> Pair<String, String>

#8

I do understand it won’t work as is. It is just a general idea.


#9

Love the idea. But if that happens, maybe a colon would be better?

As far as I remember it’s not used as part of code blocks, and it will be similar to what is used in JSON and JavaScript:

{
  "a": 22
  "b": {
    "c": "myValue"
  }
}

That would also solve the problem of -> being "harder to type than to


#10

Indeed colons make more sense, the ambiguity with map {it -> it} would be resolved.


#11

I love the idea to use colon for this operator.


#12

Or maybe ~> ? It’s not used for anything so it would be clear that it’s not part of the language but some custom operator (and of course no clash in any situation)


#13

Colon is the clear winner in my opinion. It comes with the benefit of enabling DSLs to resemble JSON.


#14

Ya, in cases mentioned in this thread colon would be nicer, but it also has very concrete use in Kotlin and I wouldn’t be surprised if it was hard/impossible to reuse.


#15

I want to state my opinion since I’ve started the topic. I think that the colon is already considered for the role, but I am not sure it is possible. As for any new operators like ~>, I am opposed to the idea. It have the same number of symbols in it and does not improve anything, just one step in direction, we should not travel.