Is there something like `myList.map(muFun)`? I kno...
# announcements
v
Is there something like
myList.map(muFun)
? I know there is
myList.map { myFun(it) }
but it requires me to explicitly call the function, if we compare to other languages this is often an anti-pattern.
r
myList.map(::myFun)
v
::
is new to me. Thanks!
What is the reason for requiring this syntax? Seems unnecessary.
e
Just curious at what makes you think it is unnecessary?
s
I think it has to do with the fact that methods/functions could be a instance method. Currently, you’d access a method-reference on an instance like this:
myObject::myFunction
. If it were
myObject.myFunction
it would be the value of a property… not a method-reference….
v
@elizarov I don’t see why
f
in
myList.map(f)
cannot simply refer to the function
f
, like in many other languages (js and python come to mind)
s
If it’s a method on a class:
MyClass::myFunction
(where
MyClass.myFunction
would be the value of a class-property)
For a top function it is
::myTopFunction
, because
myTopFunction
would be the value of a top-property
v
Sure, it makes sense if we’re talking about methods on a class. However, I don’t think it makes sense if we’re talking about simple functions.
@streetsofboston Are you implying that
f
and
::f
could refer to different things?
s
Yup.
f
would get you the value of a top property named ‘f’, while
::f
would be the method-reference to a top-function with the name ‘f’.
v
What is a top property? Oh! One have variables and functions with the same name. That explains it.
s
This is valid at the top of a kotlin source file:
Copy code
val f = ""
fun f() = ""
e
JS and Python are both dynamic languages. There are a few statically-typed languages where you can get a function reference by a simple
f
, but this convention does not seem to gaining main-stream popularity. However, you are always free to write your functions in "modern JS style" as
val f = { x: Type -> ... }
and then refer to them with a simple
f
.
🔥 1
r
For example:
Copy code
val f: (Int) -> Int = ...
fun f(i: Int): Int { ... }

fun test(func: (Int) -> Int) { ... }

test(f)
test(::f)
Both calls to
test
are valid. The first passes the
val f
, the second passes the
fun f
(Sorry, I guess I was late with that example 🙂)
v
Awesome examples guys! I get it now. But wow it does get messy when
val f = { x: Type -> ... }
is allowed… 😉
s
However, this gives a compiler error (removed the
i: Int
from the
fun f
)
Copy code
val f: (Int) -> Int = ...
fun f(): Int { ... }

fun test(func: (Int) -> Int) { ... }

test(f)
test(::f) // compiler error
v
Isn’t the distinction between variable and function silly since we still have the ambiguity of which function I refer to, for example
Copy code
val f = ""
fun f() = ""
fun f(x: Int) = ""
does
::f
refer to the version with zero or one argument?
e
It uses expected type to disambiguate which function you refer to. Kotlin is not a dynamic language and Kotlin's functions can be overloaded, too, in addition to "function/property" name overload. That's kind of Kotlin's (or other statically typed langauge's) answer to "flexible APIs" if you will.
You cannot apply your Python or JS reasoning here.
👍 4