Dropped Features


#1

According to http://youtrack.jetbrains.com/issue/KT-2360 tuples and complex pattern matching will be dropped with several other minor features.

Tuples are widely useful in language like Python but I haven’t used it in Kotlin so I can’t comment much.


#2

If you want me to comment, I can :)

Python’s tuples are not quite the same as tuples in a statically typed languages.
Tuples in Python are simply immutable lists. Kotlin will have immutable lists.
Tuples in Kotlin are different: they are kind of records where each entry has its own type. I.e. they strongly resemble classes, this is why we get rid of them.

We will also make our classes easies to use, so that they really replace tuples in a nice way.


#3

Tuples let you make objects w/o creating new classes. Which is a good thing if you wish to keep your codebase and distribution small.


#4

+1 on keeping Tuples, especially if they're done as anonymous types/classes where one can name the attributes. I really loath Tuple2/Tuple3/...Tuple10 etc. where you have get1() style indexes.

Altho…  if there was a simple data class definition available it could be ok. i.e.

data class { name: String, age: Int };

and have that generate an immutable class with equals/hashCode/getters etc.


#5

I'm not a big fan of tuples overall for the same reason I don't like structural typing: they both introduce some half-concept in the type system that is usually better implemented by using a real class and adds yet another feature that the other features of the language have to interoperate well with.


#6

I'd really like optional auto-generated equals() / compareTo() and toString() too (I find case classes in scala really handy for that). It should be possible with an annotation (@case, @data or @record something) and a compiler plugin (kinda like APT tool in Java but working on the kotlin AST before bytecode generation) to do that using the syntax you suggest. Might be nice to allow an optional include/exclude list of names of things to use for equality/comparison & order.

data class Person {   var name: String   var city: String   ... }

// or

data(excludes = list(“updatedTimestamp”)) class Person2 {
  var name: String
  var city: String
  …
}

I’ve raised this issue to track this: http://youtrack.jetbrains.com/issue/KT-2405


#7

I like the pattern matching feature which was originally proposed. How will that work w/o tuples? Will I have to create a class just to do that?


#8

Agreed. I really hate the foo._1 and foo._2 type stuff you get with Scala tuples for example.

Mostly Tuple2 would be much cleaner as just a class called Pair<A,B> and using actual names for the properties like first/last. If more than 2 or 3 values are required its immediately better to use a real class with real names than _1, _2, _3, … _N anyway.

The only area I’d actually miss tuples is:

  • iterating through maps using tuple syntax:

for ((k, v) in map) { ... }

  • switching variable around without having to use a temporary variable

(a, b) = (b, a)

Neither are super common though & could maybe be supported in the language syntax without requiring TupleN<...> classes (e.g. maybe one day we could use a pattern match with pair)...

for (Pair(k, v) in map) { ... }

Pair(a, b) = Pair(b, a)

So I'm not too worried if tuples go. (Am more bothered about proper string templates for HTML / XML / JSON escaping of string templates).


#9

Agreed,  but while swapping variables is rare, I find myself iterating over both (k, v) of maps fairly often, and the Java "EntrySet" iteration is annoyingly boiler plate. It would be nice if Kotlin could come up with a way to implement this idiom tersely without needing to introduce a new kind (tuple) or a new type (Pair<K, V>).


#10

couple of cases which I can think of

  1. return multiple values from a method
  2. pattern matching

it is true that Tuple21 may not be used. Upto 3, 4 values may be used in pattern matching

it will be nice to put names on the fields . Which makes it more readable. x._1, x._2   as in scala is not really helpful


#11

I'd like to add my two cents to this discussion. I've recently rewritten a small Python program into Kotlin and for the most part I missed some kind of destructuring assignment especially for iterating over maps. In addition, type aliases would have been useful in order to introduce more expressive names for the types of maps (in particular nested maps), but as far as I know type aliases will be eventually implemented.

So I strongly agree with James and Cedric that some kind of destructuring assignment would be useful even though support for tuples will be removed (for which I can understand the motivation). On the other hand, I would have liked to have real pattern-matching, what a pity :).


#12

Agreed. I should say swapping variables is rare, iterating over Maps is pretty common stuff. Though its pretty reasonable to be honest right now.

for (e in map) {
  println("key = ${e.key}, value = ${e.value}")
}

#13

This might be a bit a wild thought, now. But when I always keep my mouth shut for fear of burst of laughter then even my single good idea out of the other 99 crappy ideas will remain unnoticed ... Isn't a tuple something like a closure with closure variables only (e.g. the y and z in a closure like [  :y :z | some code ...]) but without any code? In a closure I'm free to name the closure variables the way I like. Hence no first/last or array[0]/array[1]. Maybe there is way to find a construct that unifies closures and tuples and things are "de-complicated" and simple again.


#14

Indeed, I didn't realize you could do it this way. This looks more than reasonable to me.


#15

>so that they really replace tuples in a nice way.

How this code looks like without tuples?

fun getSomething():#(Int, String){…}

#(a,b) = getSomething()

Do I need to create new class every time?


#16

What is wrong with "it"? I miss this feature in C#, because 80% lambdas looks like x => x.Something.


#17

If tuples are dropped then I'd assume the standard library would have a Pair class (which would be like a nicer-to-use Tuple2 class) so you can do things like this:

fun getSomething(): Pair<Int, String> {…}

val pair = getSomething()
println(“found {pair.first} {pair.last}”

pattern matching should be roughly the same though it requires using the name Pair rather than the #() syntax. I actually prefer the use of a Pair class when accessing the fields explicitly though; I’ve always hated tuple._1 and tuple._2 APIs in kotlin & scala.


#18

Agreed, it's a really simple and useful feature!


#19

Agree, and I would also would love to use some sugar, but only for Pairs, which would allow both to return two values from functions and to swap variables.

If we want  to return more thant two values from a fun, than in my opinion it’ better
to use a standard class, without the need of extra features such as data class or similar.

Go actually (well, at least it use last year) mix these two feature to substitute exception.
Something like this (Kotlin pseudocode):


  if (<its all ok>)

  
  return #(someResult,true)   else   return #(null,false)

}

val result?,ok = doSomething()

if (ok) {   <work on result> }

Don't get me wrong, I love exceptions and use them, but some times this is a nice costruct to use. Even Jdk use it some time, e.g. on File methods, only that Java will force us to check on nulls on the return values... For example, check how I get wrong here. If it would be a File method that used Go construct, I probably havn't incurred in my mistake, because the method signature have been made clear that I have to check a return value in order to check that the call has beeen successfully.


#20

I completely agree. 'it' is a very useful construct and the most commonsly used one