Kotlin equiv to Ruby's &: syntax


#1

Is there any equivalent to the Ruby &: syntax? I often find myself wishing for something like that in Kotlin and I haven’t been able to find anything like it.

So, for instance, if you have a set of Users and you want to map to user.username, in Ruby instead of writing:
users.map { |user| user.username }

You can write:
users.map(&:username)

So, in kotlin, is there any more compact way to write:
users.map { it.username }

Yes, I understand this is a relatively small bit of syntactic sugar, but I’m used to it, so I’ve wished for this often enough that I thought I should actually ask if there’s something I’m missing.


#2

users.map(User::username)


#3

That actually uses the same character count as above, and any class with a name of 5 characters or more would be less compact, but it certainly is the equivalent to the operator.

It should also be noted that if the function is a top level function, rather than a method, it’s just ::functionName


#4

Indeed – I guess I was hoping for something like an instance-relative method reference, but I don’t think anything like that exists. I’m curious if users.map(User::username) ends up generating the exact same byte code as users.map { it.username() } now, but … maybe not curious enough to test it.


#5

Huh – there does seem to be a small byte code difference, but I’d have to read it more closely to see if I care. At a quick glance, it comes down to one extra local variable to store the it, but that’s pretty minor. The block syntax doesn’t seem to carry any more weight in the output.


#6

I know there was a plan to do instance relative method references. I forget if they’ve gotten around to it yet, though. The syntax for that would be user::username.


#7

The problem being in this case that there isn’t an instance variable at the map level – and there’s no “it” equivalent without doing the block, at which point you no longer need the method reference. Anyway, I think I should just accept that there’s no direct equivalent and that I can either map(User::username) or map { it.username }, and get on with my life. :wink:


#8

You could technically make one. It would require passing in a string of the name of the method and doing reflection, which I despise but it’s possible… You’d probably also have to specify the generics, though. So… dangerous AND not very helpful…