Это сделано в Scala для предотвращения путаницы разработчиков.
Если вы сообщите компилятору тип f12 явно, он будет работать так, как вы ожидаете:
`val f12:Int=>Int = f(1, 2)`
Это объясняет создатель языка (Мартин Одерский):
Почему завершающий знак подчеркивания?
Синтаксис Scala для частично примененных функций подчеркивает разницу в компромиссных решениях Scala и классических функциональных языков, таких как Haskell или ML. В этих языках частично применяемые функции считаются нормальным случаем. Кроме того, эти языки имеют довольно строгую систему статических типов, которая обычно выделяет каждую ошибку с частичными приложениями, которые вы можете сделать. Scala имеет гораздо более тесную связь с императивными языками, такими как Java, где метод, который не применяется ко всем его аргументам, считается ошибкой. Кроме того, объектно-ориентированная традиция подтипирования и универсального корневого типа принимает некоторые программы, которые считались бы ошибочными в классических функциональных языках.
Например, допустим, вы приняли метод drop (n: Int) в List для tail (), и поэтому вы забыли, что вам нужно передать число для отбрасывания. Вы можете написать «println (drop)». Если бы Scala приняла классическую функциональную традицию, что частично применяемые функции везде в порядке, этот код проверял бы тип. Тем не менее, вы можете быть удивлены, узнав, что вывод, напечатанный этим оператором println, всегда будет! То, что случилось бы, - то, что падение выражения рассматривалось бы как функциональный объект. Поскольку println принимает объекты любого типа, это скомпилировало бы OK, но это дало бы неожиданный результат.
Чтобы избежать подобных ситуаций, Scala обычно требует, чтобы вы указывали аргументы функций, которые явно не указаны, даже если указание так же просто, как `_ '. Scala позволяет отключать даже _ только тогда, когда ожидается тип функции.