Почему Котлин нуждается в функциональном синтаксисе ссылки?

Kotlin docs заявила, что поддерживает функции более высокого порядка . Зачем языку нужен даже синтаксис ::function при передаче функции верхнего уровня в качестве аргумента?

Данный:

 fun isOdd(x: Int) = x % 2 != 0 val numbers = listOf(1, 2, 3) println(numbers.filter(::isOdd)) // here. 

Почему не просто

 fun isOdd(x: Int) = x % 2 != 0 val numbers = listOf(1, 2, 3) println(numbers.filter(isOdd)) // simple and makes more sense 

Подробнее о синтаксисе ссылки на функции здесь .

Дизайн языка Котлин пытается избежать неоднозначных ситуаций, когда некоторое отсутствие чего-то может быть как правильным, так и неправильным синтаксисом одновременно. Например, если вы допустили предложенный синтаксис:

 isOdd // error, function invocation expected isOdd(...) isOdd // not error, you have a function reference 

:: – это четкий сигнал о намерениях. Из-за этого вы получаете только ошибку в случае isOdd потому что теперь у вас есть возможности, которые не перекрываются:

 isOdd // error, function invocation expected isOdd(...) ::isOdd // function reference isOdd() // error, missing parameter x isOdd(x) // function call 

Вот почему Котлин избегает вещей, которые приводят к неоднозначным состояниям. Ваши глаза также могут быстро решить проблему, как это делает IDE и статический анализ, как это делает компилятор. Если вы начнете разрешать этот синтаксис looser, вы начнете запутываться в смешанные неоднозначности, например, при использовании в качестве функций infix и т. Д. Дизайн языка более сложный, чем «о, давайте сделаем их тире меньше символов», потому что матрица сложности намного больше, чем вы себе представляете, если вы посмотрите только на один случай использования, игнорируя все остальные.

Почему принятый ответ выше неверен:

В принятом в настоящее время ответе говорится, что это проблема с пространством имен, это неверно. В этом образце они используют:

 val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 } 

И утверждают, что он работает без :: из-за пространства имен. Это фактически работает, потому что это уже ссылка на функцию и объявлена как ссылка на функцию, и поэтому не требуется оператор, чтобы сделать ее ссылкой на функцию . Однако функция не является ссылкой. Это функция. Ему нужен оператор :: для преобразования его в ссылку на функцию, которая требуется для использования в качестве предиката для метода filter .

Претензия в этом ответе вводит в заблуждение и неверна.

Поскольку Java (и, следовательно, Kotlin) использует отдельные пространства имен для полей и методов, вам необходимо :: избегать двусмысленностей. Пример:

 val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 } fun isOdd(x: Int): Boolean { return x % 2 != 0 } val odds = listOf(1,2,3).filter(isOdd) // uses the val version val otherOdds = listOf(1,2,3).filter(::isOdd) // uses the fun version