почему некоторые языки требуют, чтобы функция была объявлена ​​в коде перед вызовом? - PullRequest
4 голосов
/ 28 января 2010

Предположим, у вас есть этот псевдокод

do_something();

function do_something(){
   print "I am saying hello.";
}

Почему некоторые языки программирования требуют, чтобы вызов do_something () появлялся под объявлением функции для запуска кода?

Ответы [ 2 ]

7 голосов
/ 28 января 2010

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

2 голосов
/ 01 февраля 2010

Большинство языков со статической системой типов предназначены для определения перед использованием , что означает, что перед вызовом должно быть какое-то объявление функции, чтобы можно было проверить вызов (например, функция, получающая правильное количество и типы аргументов). Такая конструкция помогает как человеку, так и компилятору читать программу: все, что вы видите, уже определено. Легкость чтения и популярность однопроходных компиляторов могут объяснить популярность этого правила проектирования.

К сожалению, определение перед использованием не очень хорошо подходит для взаимной рекурсии, и поэтому разработчики языка прибегли к ужасному хаку, в результате чего у вас есть

  1. Декларация (иногда называемая "предварительным объявлением" из ключевого слова в Паскале)
  2. Используйте
  3. Определение

То же явление вы видите на уровне типов в C в форме «неполной struct декларации».

Примерно в 1990 году некоторые разработчики языка поняли, что однопроходный компилятор без абстрактного синтаксического дерева должен быть в прошлом, и два очень хороших проекта этой эпохи - Modula-3 и Haskell избавился от определения перед использованием: в этих языках любая определенная функция или переменная видима во всей своей области видимости, включая текстовые части программы перед определением. Другими словами, взаимная рекурсия используется по умолчанию как для типов, так и для функций. Хорошо, говорю я - на этих языках нет уродливых и ненужных предварительных объявлений.

Почему [иметь определение перед использованием]?

  • Легко написать однопроходный компилятор в 1975 году.

  • без определения перед использованием, вам нужно больше думать о взаимной рекурсии, особенно о взаимно рекурсивных определениях типов.

  • Некоторые люди думают, что человеку легче читать код.

...