Каким должен быть язык программирования? Анализ и критика Описание языка Компилятор
Отечественные разработки Cтатьи на компьютерные темы Компьютерный юмор Прочее

«Двухмерный» синтаксис Python

Судя по отступам, Маяковский писал на Питоне

Язык Python удивителен тем, что синтаксический сахар в нём минимален. Самый частый символ этого сахара — это пробел.

 # поиск простых чисел
 for n in range(2, 10):
     for x in range(2, n):
         if n % x == 0:
             print n, 'равно', x, '*', n//x
             break
         else:
             # циклу не удалось найти множитель
             print n, '- простое число'

            Все гениальное — просто. Синтаксис Python — лучшая иллюстрация к этому. Всё, что правее и ниже ключевых слов for, if, else, является «подчинёнными» операторами. Полностью отпадает необходимость в «begin», «end», «{» и «}» — и так всё понятно. Хотя некоторые программисты, имевшие опыт программирования на Python, жалуются на трудность и непривычность чтения такого кода. «Ужасно! Для чтения программы надо прикладывать линейку к монитору», — и такое доводилось слышать. Хотя проблему мог бы решить редактор IDE, где в качестве фона могли бы нарисовать несколько таких линеек, по числу уровней программы. Тогда всё станет прозрачнее.

            Однако можно заметить, что синтаксис Python хотя и минимален, но не минималистичен. Как минимум две вещи можно смело считать излишеством.

            Первое: выражения for операторы цикла :, if условное выражение :, else : заканчиваются двоеточием, без которого можно обойтись.

            Второе. Двусмысленность оператора «else», которая берёт своё начало из Алгол-60:
 if условие 1
      выражения 1
 if условие 2
      выражения 2
 else
      выражения 3
К какому «if» относится «else»? За правило принято относить его к ближайшему (последнему) «if». В Modula-2 и многих других языках эта двусмысленность устраняется оператором «endif», в Python из-за отступов этот «endif» отсутствует.

            Третье. В разделе «Условные операторы» просматривается возможность замены оператора «elseif» на «if»:
 (if первое условие
       выражения, котрые выполняются при соблюдении первого условия
  if второе условие /* это «elseif» в языках типа Ada */
       выражения, которые выполняются при НЕсоблюдении первого условия
          и соблюдении второго условия
  else
       выражения, которые выполняются при НЕсоблюдении первого 
       и второго условий
 )
            Перечисленное в этих замечаниях не создают особых проблем. Тем не менее, надо признать, что синтаксис Python не идеален, хотя он достаточно удачен. Но попробуем предложить другой стиль для языка программирования.

            «Двухмерный» синтаксис — довольно неожидан на фоне традиционных языков. Можно шляпу перед его изобретателем, вот только кто он? Это кто-то из троицы создателей языка ABC: Leo Geurts, Lambert Meertens, Steven Pemberton. Этот синтаксис нам знаком по Python, но туда он попал из языка ABC.

Что ещё почитать на эту тему

Последняя правка: 2016-02-05    19:30

ОценитеОценки посетителей
   ███████████████████████████████████ 5 (83.3%)
   ▌ 0
   ▌ 0
   ███████ 1 (16.6%)

Отзывы

     2017/10/12 14:12, alextretyak

В качестве предисловия. Совсем недавно во время проводимых мной практических занятий (http://proglangs.ru) по языкам программирования, у одного парня не работала программа из-за того, что он поставил `;` сразу после `while (z != 0)`. «Двухмерный» синтаксис, помимо избавления от мелкого синтаксического сахара/мусора, даёт нечто большее. Что ещё так и не увидели/не поняли многие разработчики.

Проиллюстрирую это на примере документации к языку Nemerle (https://github.com/rsdn/nemerle/wiki/The-basics-(tutorial)#Rewriting_Line_Counter_without_the_loop]:

In Nemerle the if expression always need to have the else clause. It's done this way to avoid stupid bugs with dangling-else:

// C#, misleading indentation hides real code meaning
if (foo)
   if (bar)
     m1 ();
else
   m2 ();

If you do not want the `else` clause, use `when` expression, as seen in the example.

Скорее всего, разработчики Nemerle просто скопировали это из Haskell или Standard ML (https://semitwist.com/articles/article/view/nemerle-s-when-bad-idea-easily-solved [The mandatory 'else' is Nemerle's functional language inheritance showing]), не став даже разбираться в причинах указанного "stupid bug with dangling-else". А причина вовсе не в неправильной логике if, допускающем как отсутствие ветви else, так и её наличие, и даже не в забытых фигурных скобочках, а в... расхождении в восприятии данного кода человеком-программистом и компилятором. Человек воспринимает границы блоков визуально, посредством отступов, а компилятор — посредством малоприметных для человека символов, причём компилятор (языков C/C++, C#, Java, Nemerle и др.) объединяет все пробельные символы и разделители, и, таким образом, напрочь игнорирует отступы. Вот в этом и заключается корень проблемы — компилятор и человек видят такой код по-разному.

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

А для желающих временно добавить if, включающий в себя большой блок кода, который не хочется сдвигать лишний раз, я считаю, что вполне можно оставить поддержку фигурных скобок:
if foo \временно добавленное условие
{
m1() \нет отступа относительно if foo
...
if bar
    m2()
    ...
...
}
... заканчиваются двоеточием, без которого можно обойтись. Согласен.

По сути, это двоеточие не имеет смысла, так как есть операторы (if, switch, for/while, etc.), которые требуют всегда нового scope, и одного признака ‘‘новая строка с отступом’’ вполне достаточно.

Кстати, весьма интересна история появления этого двоеточия (http://python-history.blogspot.ru/2011/07/karin-dewar-indentation-and-colon.html Karin Dewar, "Indentation and the Colon"):

In 1978, in a design session in a mansion in Jabłonna (Poland), Robert Dewar, Peter King, Jack Schwartz and Lambert were comparing various alternative proposed syntaxes for B... Since they couldn't agree, Robert Dewar's wife was called from her room and asked for her opinion... But after the first version was explained to her, she remarked: "You mean, in the line where it says: 'FOR i ... ', that it has to be done for the lines that follow; not just for that line?!" And here the scientists realized that the misunderstanding would have been avoided if there had been a colon at the end of that line.

То есть, scientists, разработчики языка программирования прислушались к мнению женщины, не имеющей никакого отношения к программированию? Они хотели таким образом упростить понимание языка для новичков? Но новичком программист остаётся только короткое время в начале своего пути, а лишние двоеточия наблюдать и набирать придётся и дальше. Не думаю, что так уж сложно привыкнуть к их отсутствию.

Единственное полезное применение двоеточия — однострочные if'ы (if условие: выражения) и циклы, но выйти из положения можно с помощью обозначения scope в фигурных скобках (запись if условие {выражения}), как в Rust, либо взяв условие в скобки (if (условие) выражение).

В крайнем случае, я считаю вполне возможно это двоеточие вынести в настройки проекта. И команды разработчиков, которые примут у себя в качестве стандарта кодирования запись с двоеточием, будут писать с двоеточием, а кто не хочет следовать такому стандарту — пусть пишут без двоеточия. На уровне компилятора реализовать пропуск двоеточия в конце строки для нескольких операторов совсем несложно.

К слову, насчёт предложенного автором сайта «симметричного скобочного» стиля: если язык программирования будет поддерживать if–then–else as an expression (то есть, когда оператор «if» является не утверждением/statement, а выражением/expression, как в Scala, Ruby, Rust, Nemerle[Everything is an expression] и Nim, а также не будет, как Python, требовать ставить символ «:» после «if условие», тогда можно будет писать так:
result = (if условие
              выражения
          else
              выражения)
При этом «result =», очевидно, можно опустить, и тогда вопрос скобочек вокруг if становится лишь вопросом стиля (так как специальная поддержка скобочек вокруг if-else на уровне компилятора не потребуется, если if-else — это обычное выражение).

Кстати, я готовлю обширный интерактивный опрос/голосование по разным элементам стиля и синтаксису нового языка программирования (нужно ли двоеточие, точка с запятой, фигурные скобки, скобки вокруг условия if, количество пробелов на отступ, выбор обозначения операторов/операций [возведение в степень, целочисленное деление, логические и поразрядные операции, конкатенация строк, массивов и т.д.] и т.п.), и планирую туда включить вариант/вопрос, предлагающий ваш «симметричный скобочный» стиль. Вы не против, если я укажу ссылку на эту страницу: «Стиль языка программирования»? А также можете подумать и предложить какие-то свои вопросы, я ещё успею включить их в опрос (вообще, голосование начнётся не раньше, чем через 3 месяца, так что времени на подумать ещё довольно много). Вопрос, нужен ли else if и какой именно/конкретно (elseif, elsif, elif) также можно поставить на этом голосовании.

Хотя проблему мог бы решить редактор IDE, где в качестве фона могли бы нарисовать несколько таких линеек, по числу уровней программы.

Помимо вертикальных линеек я предлагаю ещё такие горизонтальные пунктирные линии: https://habrastorage.org/webt/59/dd/f4/59ddf464724da447828936.png

     2017/10/26 22:30, Автор сайта

Можете включить в голосование (если Вас не затруднит, дайте на него ссылку) ещё один пункт: «if», имеющий смысл как «else if»:
(if условие1
выражения 1
if условие 2 // здесь «if» играет ту же роль, что «else if»
выражения 2
else
выражения 3
)
В приведённом примере второй «if» не имеет впередиидущей скобки, что говорит о том, что он играет роль «else if». Это одна из гипотез грядущего языка программирования. Но скорее всего, это будет отвергнуто: оно провоцирует путаницу.

Что касается разделителей выражений, то выбрал для себя в качестве таковых «перевод строки» и «;».

     2018/03/07 23:56, alextretyak

если Вас не затруднит, дайте на него ссылку

Голосование откладывается в связи с [крайне] низкой заинтересованности к новому языку программирования, ссылка на статью:
https://habrahabr.ru/post/350694/.

     2018/03/10 20:05, Comdiv

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

     2018/04/30 09:49, geniepro

Синтаксис питона и правда напоминает синатксис ABC, однако за два десятка лет до ABC двумерный синтаксис был в языке ISWIM, а ещё за два десятка лет до него — в языке Plankalkül.

По поводу важности двумерного синтаксиса со значимыми отступами хорошую статью как-то написал Chris Okasaki в своей статье "In praise of mandatory indentation for novice programmers". Там он упоминал, что значимые отступы вместо всех этих {} begin-end дают значительное преимущество в облегчении изучения программирования. По сравнению с этим не особо важно, статическая типизация или динамическая, функциональный язык или ООП, строгие вычисления или ленивые...

     2018/04/30 14:03, Автор сайта

Из Википедии:

В Python Гвидо ван Россум позаимствовал некоторые наработки для языка ABC (Гвидо участвовал в разработке этого языка, ориентированного на обучение программированию).

Заимствование произошло не напрямую.

Очень даже верю, что отступы — самый сильный инструмент. Спасибо за ссылку.

Написать отзыв

Написать автору можно на электронную почту mail(аt)compiler.su

Авторизация

Регистрация

Выслать пароль

Карта сайта


Каким должен быть язык программирования?

Анализ и критика

Устарел ли текст как форма представления программы

Русский язык и программирование

Многоязыковое программирование

Синтаксис языков программирования

Синтаксический сахар

Некоторые «вкусности» Алгол-68

«Двухмерный» синтаксис Python

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

Должна ли программа быть удобочитаемой?

Стиль языка программирования

Тексто-графическое представление программы

●  Разделители

●  Строки программы

●  Слева направо или справа налево?

Комментарии

●  Длинные комментарии

●  Короткие комментарии

●  Комментарии автоматической генерации документации

●  Нерабочий код

Нужны ли беззнаковые целые?

Шестнадцатиричные и двоичные константы

Условные операторы

Переключатель

Циклы

●  Продолжение цикла и выход из него

Некошерный «goto»

Операции присвоения и проверки на равенство. Возможно ли однаковое обозначение?

Так ли нужны операции «&&», «||» и «^^»?

Постфиксные инкремент и декремент

Почему в PHP для конкатенации строк используется «.»?

Указатели и ссылки в C++

Использование памяти

Почему динамическое распределение памяти – это плохо

Как обеспечить возврат функциями объектов переменной длины?

●  Типы переменного размера (dynamically sized types, DST) в языке Rust

●  Массивы переменной длины в C/C++

●  Размещение объектов в стеке, традиционный подход

●  Размещение объектов переменной длины с использованием множества стеков

●  Размещение объектов переменной длины с использованием двух стеков

●  Реализация двухстековой модели размещения данных

●  Двухстековая модель: тесты на скорость

●  Размещение объектов переменной длины с использованием одного стека

Можно ли забыть о «куче», если объекты переменной длины хранить в стеке

Безопасность и размещение объектов переменной длины в стеке

Массивы, структуры, типы, классы переменной длины

О хранении данных в стеке, вместо заключения

Описание языка

Компилятор

Отечественные разработки

Cтатьи на компьютерные темы

Компьютерный юмор

Прочее

Последние комментарии

2018/07/03 03:27, rst256
Философия языка

2018/06/25 15:10, Автор сайта
Продолжение цикла и выход из него

2018/06/14 00:37, rst256
Лень — двигатель прогресса

2018/05/31 18:52, rst256
Программирование без программистов — это медицина без врачей

2018/05/31 17:57, rst256
Циклы

2018/05/31 17:50, Comdiv
Разбор цепочек знаков операций

2018/05/31 17:42, Comdiv
Как отличить унарный минус от бинарного

2018/05/30 18:57, Александр Коновалов aka Маздайщик
Раскрутка компилятора