Чому мова повинна віддавати перевагу відступу над явними маркерами для блоків?


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
@ К.Гкініс: Найкращим джерелом для точних мотивів мовного рішення є самі дизайнери мови.
Роберт Харві

3
Це питання насправді не є суб'єктивним. Це питання, чому деякі дизайнери мови обрали певний синтаксис. На це можна відповісти. Якби питання запитало, який синтаксис найкращий , він би був суб'єктивним.
ЖакБ

Відповіді:


13

Гвідо Фон Россум

З інтерв'ю з Гвідо Ван Россумом , який можна побачити в повному обсязі з books.google.com (моє наголос):

Вибір відступу для групування не був новітньою концепцією в Python; Я успадкував це від ABC , але це траплялося і в оккамі, більш старій мові. Я не знаю, чи автори АБВ отримали ідею з оккаму, чи винайшли її самостійно, чи був спільний пращур. Звичайно, я міг би вирішити не брати участь у програмі ABC, як це робилося в інших областях (наприклад, ABC використовував великі регістри мовних ключових слів та назви процедур, ідею, яку я не копіював), але мені ця функція дуже сподобалась Біт під час використання ABC, як здавалося, усуває певний тип безглуздих дискусій, поширених серед користувачів на той час, щодо того, де розмістити фігурні дужки .

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

Я також добре розумів, що читабельний код так чи інакше використовує відступ для вказівки на групування, і я натрапив на непомітні помилки в коді, де відступ не погоджувався із синтаксичним угрупованням за допомогою фігурних дужок - програміст та будь-які рецензенти припускали, що відступ відповідає групуванню і тому не помітив помилку. Знову тривалий налагоджувальний сеанс навчив цінного уроку.

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

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

У згаданому інтерв'ю Гідо згадує ідею Дон Кнута про використання відступів. Про це детально йдеться у перетвореній цитаті відступу Knuth , в якій цитується Структурне програмування з goto Statements . Кнут також згадує наступні 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 і відступи коду "неправильно": це ще один шанс побачити помилку.


3
"Щоб уникнути релігійних війн ..." Я здивований, що справжня причина настільки банальна.
Роберт Харві

1
@RobertHarvey: Акцент на цій фразі робиться з підрядчиком, а не Ван Россумом. Це не головна причина, якщо ви читаєте цитату Ван Россума в контексті.
ЖакБ

@JacquesB Скажіть, будь ласка, який контекст відсутній у цитаті, щоб я міг редагувати відповідь.
coredump

4
Я не отримую від вас особистого коментаря: Якщо ви прокрутили відступи в Python, то у вас є помилка. Якщо ви накрутите брекети на C, у вас є помилка. Якщо ви використовуєте автоматичне відступ, воно точно однакове на обох мовах. І якщо ви не використовуєте автоматичне відступ, помилка може бути приховано захована в C способом, який неможливий у Python.
ЖакБ

2
@JacquesB, тому що набирати фіксатор, що закривається, - це те, що ви активно робите; недостатнє відступ - це те, що ви можете забути зробити. Звичайно, ви можете забути закрити дужку в потрібний час, але вам доведеться це зробити в підсумку і отримати ще один шанс подумати про це. Я думаю, що пітон працює добре для початківців, оскільки він примушує увагу до відступу.
марстато

7

Це дуже суб'єктивно і є причиною для багатьох полум'яної війни. Однак:

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

Поширені запитання щодо дизайну та історії Python про це дуже чітко зазначено:

Чому Python використовує відступи для групування висловлювань?

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

Оскільки немає дужок початку / кінця, то між групуванням, сприйнятим парсером, і читачем людини не може бути розбіжностей.

Це правда, що ви не можете створити інструмент автоматичного відступу для Python, але це хороша річ: це означає, що у вас немає надмірностей у синтаксисі, для того щоб вам потрібно автоматичні інструменти для узгодження.

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

Python успадкував значне відступ від (тепер застарілої) мови попередника ABC. ABC - одна з небагатьох мов програмування, яка використовувала тестування зручності для керування дизайном. Тому, хоча дискусії про синтаксис зазвичай зводяться до суб'єктивних поглядів та особистих уподобань, вибір суттєвого відступу насправді має основу душі.


6
Облік подвійних записів також порушує DRY. Надмірність - іноді особливість.
coredump

3
@coredump: Це правда, але це свідомо розроблена надмірність. Більшість мов програмування, включаючи Python, містять навмисно обрані надмірності - наприклад, passключове слово, яке можна зробити автоматично, але вимагаючи явного явлення, допомагає виявити помилки. Випадкова надмірність символів початку / кінця (для компілятора) та відступу (для людського читача), схоже, викликає більше помилок, ніж сприймає. Принаймні, так виглядає погляд Ван Россума.
ЖакБ

@coredump - Тепер я знаю, чому я не бухгалтер.
JeffO

3
@coredump Ви також пропускаєте COBOL PROCEDURE DIVISION.? Я ніколи не можу сказати, де DATA DIVISIONпочинаються ці процедури та ці новомовні мови.
msw

2
@coredump: "бачити відступ суперечить тому, що я мав на увазі, достатньо для запобігання помилок" - точно.
ЖакБ

2

Мовні дизайнери обирають синтаксично значущий пробіл, оскільки вони вважають (або принаймні вважають, що їхні потенційні користувачі вірять), що напівколонки та дужки додають шум під час читання коду, що завдає шкоди продуктивності. Ще одна поширена причина полягає в тому, що поганий / непослідовний стиль кодування завдає шкоди читабельності - примушуючи до загальної схеми відступу, мова має кращу читаність за всіма. Ця пізніша причина є менш важливою тепер, коли автоматичне форматування IDE є більш поширеними, але все ще може застосовуватися.


1
Я можу зрозуміти, чому можна було б розглянути крапки з комою та фігурними шумами. Але хіба не менш продуктивним є введення простору 4/8/12 разів? І якщо ви пропустите його (оскільки вони непомітні), ви переживаєте проблеми.
Відновіть Моніку

5
Ось чому ви використовуєте вкладки замість пробілів або IDE, яка розуміє, як перетворити вкладки в чотири пробіли.
Роберт Харві

@ K.Gkinis: Відступи не невидимі. Лише пробіл на кінцях рядків невидимий, але це не є важливим для жодної мови. Тільки якщо ви змішаєте вкладки та пробіли, ви потрапите в проблеми. Тож не робіть цього.
ЖакБ

@JacquesB: Проблема з видимістю / невидимістю відступу полягає в тому, що, як людина, ви часто не можете визначити різницю між пробілами та вкладкою, тоді як комп'ютер може і часто робить. Отже, хоча відступ видно, спосіб комп'ютерної інтерпретації відступу може бути різним. У цьому справжня проблема: коли комп’ютер ставиться до невидимих ​​символів інакше, ніж до людей. Люди вимірюють відступ як відстань на екрані, комп'ютери можуть вимірювати це як буквальне число символів. це невидима частина.
Брайан Оуклі

@BryanOakley: Так, саме тому не слід змішувати вкладки та пробіли в відступі.
ЖакБ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.