Почему язык должен предпочитать отступ перед явными маркерами для блоков?

11

Я изучаю Haskell, и я искал инструмент для автоматического отступа. Я не особо выглядел и узнал, что в Haskell (как в Python) отступы означают блок. В результате я предполагаю, что невозможно создать инструмент автоматического форматирования, такой же сильный, как в других языках семейства C, в котором используются явные маркеры, такие как {} (фигурные скобки) или begin endключевые слова.

Я не возражаю против языка, обеспечивающего отступы для удобства чтения, но я не могу понять преимущества по сравнению с применением отступов и наличием некоторого явного маркера, так что автоматизированные инструменты могут понять, что принадлежит тому или иному блоку.

Если предпочтение заключается в том, чтобы пометить блок как отступ, чтобы код выглядел лучше, тогда я все еще не понимаю преимущества. Учитывая, что табуляция и пробелы представлены по-разному в разных редакторах и разных шрифтах (например, моно-пробелы выглядят аккуратнее), программист не может представить код достойно. Инструмент, который может учитывать текущий текстовый редактор, будет гораздо более подходящим для правильного форматирования кода.

Почему разработчик языка выбирает отступ вместо явных блочных маркеров?

Восстановить Монику
источник
8
Не ответ, но Haskell делает чувствительность к пробелам намного более необязательной, чем python. Вы можете использовать точки с запятой для большинства вещей, и при желании обернуть блоки в фигурные скобки. let x =1; y = 2; z = 3полностью действителен, как есть do { putStrLn $ show x; putStrLn $ show y; putStrLn $ show z; }. Те не должны быть на одной линии.
KChaloux
8
«невозможно создать инструмент автоматического форматирования» - фактически, в Python такой инструмент автоматического форматирования не нужен из-за правил отступа.
Док Браун
13
Хм, увеличение отступа - это явный маркер блока.
Карл Билефельдт
3
@ K.Gkinis: лучший источник точных мотивов, лежащих в основе решения о разработке языка, - это сами разработчики языка.
Роберт Харви
3
Этот вопрос на самом деле не субъективен. Он спрашивает, почему некоторые дизайнеры языка выбрали определенный синтаксис. На это можно ответить. Если бы вопрос задавался тем, какой синтаксис является лучшим , это было бы субъективно.
JacquesB

Ответы:

13

Гвидо фон Россум

Из интервью с Гвидо Ван Россумом , которое можно увидеть в полном тексте с books.google.com (выделено мое):

Выбор отступа для группировки не был новой концепцией в Python; Я унаследовал это от ABC , но это также произошло в Occam, более старом языке. Я не знаю, получили ли авторы ABC идею от occam, или изобрели ее самостоятельно, или был ли общий предок. Конечно, я мог бы решили не следовать примеру АВС, как я делал в других областях (например, ABC используется верхний регистр для ключевых слов языка и имен процедур, идею я не копировать), но я пришел , как особенность довольно немного при использовании ABC, поскольку это, казалось, покончило с определенным типом бессмысленных дебатов, распространенных среди пользователей C в то время, о том, где разместить фигурные скобки .

Фон Россум был сильно вдохновлен ABC , и хотя ему не нужно было копировать все это, использование отступов было сохранено, потому что это могло быть полезно во избежание религиозных войн.

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

Россум также засвидетельствовал ошибки из-за несоответствия между группировкой и отступом, и, очевидно, хотя полагание, что использование отступа только для структурирования кода будет более защищено от ошибок программирования 1 .

Дональд Э. Кнут и Питер Дж. Ландин

В упомянутом интервью Гвидо упоминает идею Дона Кнута об использовании отступов. Это подробно описано в « Обнаруженной цитате отступа Кнута» , которая цитирует структурированное программирование с помощью операторов goto . Кнут также ссылается на следующие 700 языков программирования Питера Джона Ландина (см. Раздел «Обсуждение»). Ландин разработал ISWIM, который выглядит как первый язык с отступом вместо блоков начала / конца. Эти документы больше о целесообразности использования отступов для структурирования программ, чем о реальных аргументах в пользу этого.


1. Я думаю, что это на самом деле аргумент в пользу наличия как группирующих конструкций, так и автоматического форматирования, чтобы выявлять и исправлять ошибки программирования, которые неизбежно произойдут. Если вы испортили свой отступ в Python, человек, который отладит ваш код, должен будет угадать, что правильно:

if (test(x)):
  foo(x)
  bar(x)

Должен barвсегда быть вызван или только если тест успеха?

Группирующие конструкции добавляют уровень избыточности, который помогает вам обнаружить ошибку при автоматическом отступе кода. В C эквивалентный код может быть автоматически вставлен следующим образом:

if (test(x))
  foo(x);
bar(x);

Если я собирался barбыть на том же уровне, что fooи авто-отступ, основанный на структуре кода, то я вижу, что есть что-то неправильное, что можно исправить, добавив фигурные скобки fooи bar.

В Python: мифы об отступах есть предположительно плохой пример из C:

/*  Warning:  bogus C code!  */

if (some condition)
        if (another condition)
                do_something(fancy);
else
        this_sucks(badluck);

Это тот же случай, что и выше, в Emacs, я выделяю весь блок / функцию, нажимаю Tab, а затем весь код переопределяется. Расхождение между человеческими отступами и структурой кода говорит мне о том, что что-то не так (это и предыдущий комментарий!).

Кроме того, промежуточный код, где отступ в C отключен, просто не проходит через главную ветку, все проверки стилей заставили бы GCC / Jenkins кричать на меня. У меня недавно была проблема, похожая на описанную выше в Python, с оператором, отступившим на один уровень отступа. Иногда у меня есть код на C, который выходит за пределы закрывающей скобки, но затем я нажимаю Tab и код «отступает»: это еще один шанс увидеть ошибку.

CoreDump
источник
3
«Чтобы избежать религиозных войн ...» Я удивлен, что истинная причина так тривиальна.
Роберт Харви
1
@RobertHarvey: акцент на этой фразе сделан coredump, а не van Rossum. Это не основная причина, если вы читаете цитату Ван Россума в контексте.
JacquesB
@JacquesB Пожалуйста, скажите мне, какой контекст отсутствует в цитате, чтобы я мог отредактировать ответ.
coredump
4
Я не получаю от вас личного комментария: если вы испортили отступ в Python, у вас есть ошибка. Если вы испортили скобки в C, у вас есть ошибка. Если вы используете авто-отступ, он одинаков на обоих языках. И если вы не используете авто-отступ, ошибка может быть скрытно скрыта в C, что невозможно в Python.
JacquesB
2
@JacquesB, потому что ввод закрывающей скобки - это то, что вы активно делаете; Недостаточный отступ - это то, что вы можете забыть сделать. Конечно, вы можете забыть закрыть скобку в нужное время, но в конечном итоге вам придется сделать это и получить еще один шанс подумать об этом. Я думаю, что Python хорошо работает для начинающих, потому что он привлекает внимание к отступам.
Марстато
7

Это очень субъективно и является причиной многих пламенных войн. Однако:

Наличие символов, разделяющих блоки и отступы, нарушает принцип DRY , поскольку вы выражаете одну и ту же информацию двумя разными способами. Наличие автоматических инструментов для отступов является признаком этого нарушения DRY: то, что вы можете автоматически генерировать отступы, показывает, что это избыточная информация, и это означает, что отступы и символы могут быть не синхронизированы, что приведет к вводящему в заблуждение коду.

Часто задаваемые вопросы по Python Design and History очень четко говорят об этом:

Почему Python использует отступ для группировки операторов?

Гвидо ван Россум считает, что использование отступов для группировки чрезвычайно элегантно и вносит большой вклад в ясность обычной программы на Python. Большинство людей учатся любить эту функцию через некоторое время.

Поскольку нет начальных / конечных скобок, не может быть разногласий между группировкой, воспринимаемой синтаксическим анализатором и человеком-читателем.

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

В Python допустимо использование табуляции и пробелов, поэтому рекомендуется никогда не смешивать табуляцию и пробелы (для отступов) в одной кодовой базе.

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

JacquesB
источник
6
Двойная бухгалтерия тоже нарушает DRY. Избыточность иногда является особенностью.
coredump
3
@coredump: правда, но это специально продуманная избыточность. Большинство языков программирования, включая Python, содержат намеренно выбранные избыточности - например, passключевое слово, которое может быть выведено автоматически, но требование его явного указания помогает обнаружить ошибки. Случайная избыточность наличия символов начала / конца (для компилятора) и отступа (для читателя-человека), кажется, вызывает больше ошибок, чем ловит. По крайней мере, это похоже на мнение ван Россума.
JacquesB
@coredump - теперь я знаю, почему я не бухгалтер.
JeffO
3
@coredump Ты PROCEDURE DIVISION.тоже скучаешь по Коболу ? Я никогда не могу сказать, где, где DATA DIVISIONзаканчивается, и процедуры начинаются на этих новомодных языках.
Msw
2
@coredump: «видеть отступы противоречит тому, что я имел в виду, достаточно, чтобы предотвратить ошибки» - точно.
JacquesB
2

Разработчики языка выбирают синтаксически значимые пробелы, потому что они верят (или, по крайней мере, думают, что их потенциальные пользователи считают), что точки с запятой и фигурные скобки добавляют шум при чтении кода, снижая производительность. Другая распространенная причина заключается в том, что плохой / несовместимый стиль кодирования вредит читабельности - благодаря использованию общей схемы отступов язык в целом лучше читается. Эта более поздняя причина менее важна сейчас, когда автоформатирование IDE более распространено, но все еще может применяться.

Telastyn
источник
1
Я понимаю, почему можно рассматривать точки с запятой и фигурные скобки. Но не менее ли продуктивно набирать 4/8/12 раз? И если вы пропустите один (так как они невидимы), у вас проблемы.
Восстановить Монику
5
Вот почему вы используете вкладки вместо пробелов или IDE, которая понимает, как преобразовывать вкладки в блоки из четырех пробелов.
Роберт Харви
@ K.Gkinis: отступы не являются невидимыми. Только пробелы на концах строк невидимы, но это не важно для любого языка. Только если вы смешаете табуляции и пробелы, вы попадете в беду. Так что не делай этого.
JacquesB
@JacquesB: проблема с видимостью / невидимостью отступов заключается в том, что, будучи человеком, вы часто не можете определить разницу между пробелами и табуляцией, в то время как компьютер может и часто делает это. Таким образом, хотя отступ виден, способ, которым компьютер интерпретирует отступ, может быть другим. Это реальная проблема: когда компьютер воспринимает невидимых персонажей иначе, чем людей. Люди измеряют отступ как расстояние на экране, компьютеры могут измерять его как буквальное количество символов. это невидимая часть.
Брайан Оукли
@BryanOakley: Да, именно поэтому вы не должны смешивать табуляции и пробелы в отступе.
JacquesB