Правило «вне игры» описывает синтаксис языка программирования , который определяет границы блока кода с помощью отступов . [1] [2]
Термин был придуман Питером Ландином , возможно, как игра слов на закон о положении «вне игры» в американском футболе .
Язык правил «вне игры» противопоставляется языку свободной формы , в котором отступ не имеет синтаксического значения и является строго вопросом стиля .
Язык правил «вне игры» также описывается как имеющий значительный отступ .
Питер Ландин в своей статье 1966 года « Следующие 700 языков программирования » определил правило «вне игры» следующим образом: «Любой непробельный токен слева от первого такого токена в предыдущей строке считается началом нового объявления». [3]
Ниже приведен пример блоков отступов в Python ; популярный язык правил офсайда. В Python правило используется для определения границ операторов, а не объявлений.
def is_even ( a : int ) -> bool : если % 2 == 0 : печать ( 'Даже!' ) вернуть Истину печать ( 'Странно!' ) вернуть Ложь
Тело функции начинается на строке 2, поскольку оно имеет отступ на один уровень (4 пробела) больше, чем предыдущая строка. if
Тело предложения начинается на строке 3, поскольку оно имеет отступ на дополнительный уровень, и заканчивается на строке 4, поскольку строка 5 имеет отступ на уровень меньше, то есть выдвинута.
Двоеточие ( :
) в конце строки оператора управления — это синтаксис Python; не аспект правила «вне игры». Правило может быть реализовано без такого синтаксиса двоеточия.
Правило «вне игры» может быть реализовано на этапе лексического анализа , как в Python , где увеличение отступа приводит к выводу лексером токена INDENT
, а уменьшение отступа приводит к выводу лексером DEDENT
токена. [4] Эти токены соответствуют открывающей фигурной скобке {
и закрывающей фигурной скобке }
в языках, которые используют фигурные скобки для блоков, и означают, что грамматика фразы не зависит от того, используются ли фигурные скобки или отступы. Это требует, чтобы лексер удерживал состояние, а именно текущий уровень отступа, и, таким образом, мог обнаруживать изменения в отступе, когда он изменяется, и, таким образом, лексическая грамматика не является контекстно-свободной : INDENT
и DEDENT
зависит от контекстной информации предыдущего уровня отступа.
Основная альтернатива разделению блоков отступами, популяризированная широким использованием и влиянием языка C , заключается в игнорировании пробельных символов и явном обозначении блоков фигурными скобками (например, {
и }
) или каким-либо другим разделителем. Хотя это обеспечивает большую свободу форматирования — разработчик может решить не делать отступы для небольших фрагментов кода, таких как операторы break и continue — небрежно отступованный код может сбить читателя с толку, например, ошибка goto fail .
Lisp и другие языки, основанные на S-выражениях , не различают операторы и выражения, и скобок достаточно для управления областью действия всех операторов в языке. Как и в языках с фигурными скобками, пробелы в основном игнорируются читателем (т. е. функцией чтения). Пробелы используются для разделения токенов. [5] Явная структура кода Lisp допускает автоматический отступ, чтобы сформировать визуальную подсказку для людей, читающих.
Другой альтернативой является начало и конец каждого блока явными ключевыми словами. Например, в ALGOL 60 и его потомке Pascal блоки начинаются с ключевого слова begin
и заканчиваются ключевым словом end
. В некоторых языках (но не в Pascal) это означает, что переносы строк важны [ требуется ссылка ] (в отличие от языков с фигурными скобками), но отступы не важны. В BASIC и Fortran блоки начинаются с имени блока (например, IF
) и заканчиваются именем блока, к которому добавлено END
(например, END IF
). В Fortran каждый блок также может иметь свое собственное уникальное имя блока, что добавляет еще один уровень явности длинному коду. ALGOL 68 и оболочка Bourne (sh и bash ) похожи, но конец блока обычно задается именем блока, записанным в обратном порядке (например, case
начинает оператор switch и распространяется до соответствующего esac
; аналогично условным операторам if
... then
...[ elif
...[ else
...]] fi
или циклам for for
... do
... od
в ALGOL68 или for
... do
... done
в bash).
Интересный вариант этого встречается в Modula-2 , языке, похожем на Pascal, который устраняет разницу между однострочными и многострочными блоками. Это позволяет пропустить открыватель блока ( {
или ) для всех, кроме блока уровня функции, требуя только завершающий блок токен ( или ). Это также исправляет висячий else . Custom — это размещение токена на том же уровне отступа, что и остальная часть блока, что дает очень читаемую структуру блока.BEGIN
}
END
end
Одним из преимуществ подхода Fortran является то, что он улучшает читаемость длинного, вложенного или иного сложного кода. Группа выступов или закрывающих скобок сама по себе не дает никаких контекстных подсказок относительно того, какие блоки закрываются, что требует возврата и более тщательного изучения во время отладки . Кроме того, языки, которые допускают суффикс для ключевых слов, подобных END, еще больше улучшают такие подсказки, такие как continue
versus continue for x
, и маркер конца цикла, указывающий индексную переменную NEXT I
versus NEXT
, и уникально именованные циклы CYCLE X1
versus CYCLE
. Однако современные редакторы исходного кода часто предоставляют визуальные индикаторы, такие как подсветка синтаксиса , и такие функции, как сворачивание кода , чтобы помочь с этими недостатками.
В языке Scala ранние версии допускали только фигурные скобки. Scala 3 добавила возможность использовать отступы для структурирования блоков. Дизайнер Мартин Одерски сказал, что это был единственный наиболее важный способ, которым Scala 3 улучшила его собственную производительность, что она делает программы более чем на 10% короче и держит программистов «в потоке», и советует использовать ее. [6]
Известные языки программирования с правилом «вне игры»:
#light
указано; в более поздних версиях, когда #light "off"
не указано [7]where
, let
, do
, или , case ... of
когда фигурные скобки опущеныИзвестные неязыки программирования, форматы текстовых файлов со значительными отступами: