Большинство языков со статической системой типов предназначены для определения перед использованием , что означает, что перед вызовом должно быть какое-то объявление функции, чтобы можно было проверить вызов (например, функция, получающая правильное количество и типы аргументов). Такая конструкция помогает как человеку, так и компилятору читать программу: все, что вы видите, уже определено. Легкость чтения и популярность однопроходных компиляторов могут объяснить популярность этого правила проектирования.
К сожалению, определение перед использованием не очень хорошо подходит для взаимной рекурсии, и поэтому разработчики языка прибегли к ужасному хаку, в результате чего у вас есть
- Декларация (иногда называемая "предварительным объявлением" из ключевого слова в Паскале)
- Используйте
- Определение
То же явление вы видите на уровне типов в C в форме «неполной struct
декларации».
Примерно в 1990 году некоторые разработчики языка поняли, что однопроходный компилятор без абстрактного синтаксического дерева должен быть в прошлом, и два очень хороших проекта этой эпохи - Modula-3 и Haskell избавился от определения перед использованием: в этих языках любая определенная функция или переменная видима во всей своей области видимости, включая текстовые части программы перед определением. Другими словами, взаимная рекурсия используется по умолчанию как для типов, так и для функций. Хорошо, говорю я - на этих языках нет уродливых и ненужных предварительных объявлений.
Почему [иметь определение перед использованием]?
Легко написать однопроходный компилятор в 1975 году.
без определения перед использованием, вам нужно больше думать о взаимной рекурсии, особенно о взаимно рекурсивных определениях типов.
Некоторые люди думают, что человеку легче читать код.