Недавно я начал учиться программировать в Scala, и до сих пор было весело. Мне действительно нравится возможность объявлять функции в другой функции, что кажется интуитивно понятным.
У меня есть одна любимая мозоль о Scala - тот факт, что Scala требует явного возвращаемого типа в своих функциях . И я чувствую, что это мешает выразительности языка. Кроме того, просто сложно программировать с этим требованием. Может быть, это потому, что я из зоны комфорта Javascript и Ruby. Но для такого языка, как Scala, у которого в приложении будет множество связанных функций, я не могу представить, как мне в мозгу надо точно определить, какой тип конкретной функции, которую я пишу, должен возвращаться с рекурсиями после рекурсий.
Это требование явного объявления возвращаемого типа для функций не беспокоит меня для таких языков, как Java и C ++. Рекурсии в Java и C ++, когда они случались, часто имели дело с максимум 2-3 функциями. Никогда не объединяйте несколько функций, таких как Scala.
Поэтому я думаю, мне интересно, есть ли веская причина, по которой в Scala должно быть требование наличия функций, имеющих явный тип возврата?
источник
Ответы:
Scala не требует явного возвращаемого типа для всех функций, только для рекурсивных. Причиной этого является то, что алгоритм вывода типов в Scala (что-то близкое к нему) является простым сканированием от начала до конца, которое неспособно к прогнозированию.
Это означает, что такая функция:
возвращаемый тип не требуется, так как компилятор Scala может четко видеть, не используя логические переменные или просматривая что-либо, кроме параметров метода, что тип возвращаемого значения должен быть
String
.С другой стороны, такая функция:
вызовет ошибку во время компиляции, потому что компилятор Scala не может увидеть, без использования заглядывания или логических переменных, именно то, что тип
mapInts
. Максимум, что можно было бы сказать, если бы он был достаточно умным, это то, что возвращаемый тип - это супертипList[Nothing]
, посколькуNil
он того же типа. Это не дает достаточно информации, чтобы точно определить тип возвращаемого значенияmapInts
.Обратите внимание, что это характерно для Scala, и что существуют другие статически типизированные языки (большая часть семейства Miranda / Haskell / Clean, большая часть семейства ML и несколько других), которые используют гораздо более полные и функциональные алгоритмы вывода типов чем использует Scala. Кроме того, имейте в виду, что это не совсем ошибка Скалы; номинальный подтип и вывод целого модуля принципиально расходятся друг с другом, и разработчики Scala решили отдать предпочтение первому над вторым ради совместимости с Java, в то время как «более чистые» статически типизированные функциональные языки были в основном разработаны с противоположный выбор в виду.
источник
case Nil
самом деле пустымList[Int]()
? В этом случае достаточно умный компилятор может понять это. Думаю, все это играет в «Адвоката дьявола».