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

Изменение приоритетов операций

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

// Пример Владислава:
MaybeUTF8 := (FirstByte and $С0 = $80) and (NextByte and $С0 = $80);		// Паскаль-вариант

MaybeUTF8 = FirstByte & 0xC0 == 0x80 && NextByte & 0xC0 == 0x80;		// Си-вариант
MaybeUTF8 = ((FirstByte & 0xC0) == 0x80) && ((NextByte & 0xC0) == 0x80);	// эквивалент со скобками 

// В каком порядке будет вычисляться это выражение при одинаковых приоритерах «&» и «&&»?
Изменение приоритетов операций
            Однако это не меняет того факта, что логические операции и побитовые операции применяются к разными типами данных. Поэтому логично заставить одни и те же операции решать разные задачи — в зависимости от типа данных. Проблему приоритетов логично решить неожиданным способом. Можно иметь две одинаковые по семантике операции «и», но с разными приоритетами:
результат = флаг 1 & флаг 2 && флаг 3

Повышение приоритета операций дублированием символа операции

            Операция «и», записанная двумя символами «&&», более приоритетна, нежели «&» — c одним символом. При одинаковом их смысле. Очерёдность выполнения операций будет такова:
1) флаг 2 && флаг 3			// в первую очередь
2) флаг 1 & результат 1-го шага	// во вторую очередь
3) результат = результат 2-го шага	// в третью очередь
Аналогично — для операций «или» и «исключающее или»:
результат = флаг 1 | флаг 2 || флаг 3
результат = флаг 1 ^ флаг 2 ^^ флаг 3
Если знаки операций записываются словами, то и тут можно попробовать одинаковым операциям назначить разный приоритет:
результат = флаг 1 and флаг 2 AND флаг 3	// больше буквы — больше приоритет
результат = флаг 1 or флаг 2 OR флаг 3
результат = флаг 1 xor флаг 2 XOR флаг 3
            Внимательный читатель заметит, что в приведённых выше примерах результат не зависит от порядка вычислений. Но примеры тут даны такие, чтобы иллюстрировать саму идею.

            Поскольку в будущем языке программирования важно придерживаться единого стиля — так легче постигается язык, то закономерно встанет вопрос о «симметричных» операциях. Об операциях «++», «--», «**» и «//», как более приоритетных вариантах всё тех же операций «+», «-», «*» и «/». Почему бы нет? Непривычно будет поначалу, конечно. Но ведь можно будет сэкономить на скобках.

            Потом, конечно, встанет вопрос о «==» как более приоритетном варианте «=». Но, позвольте, это ж проверка равенства... Тут стремление к единообразию вон куда нас вывело. Однократного повышения приоритета дублированием символа операции может быть недостаточно. Если встретилось сложное выражение, то такое вполне может иметь место. Как попроще выйти из положения?

Повышение приоритета операций многократным повторением символа операции

            Там, где можно поставить два символа подряд, можно поставить и три, и четыре — сколько надо:
a = b ** c ++++ d /// e	        // первым выполнится сложение
				// вторым — деление
				// третьим — умножение
				// четвёртым — присвоение
f = b * ((c + d) / e)		// эквивалентная запись в традиционной форме
            В таком случае вообще отпадает надобность в традиционных скобках. Можно ли вообще без них обойтись? Сложности возникают вот где. В C/C++ много операций, записанных двумя и тремя символами, а то и буквами. Например:
->	// доступ к члену класса по указателю на объект
new	// создание динамического объекта
->*	// обращение к члену класса по указателю на него
<=	// логическая операция: меньше или равно
>>=	// присваивание со сдвигом вправо
И как должна быглядеть Какие идеи? И чтоб попроще!

Повышение приоритета операций специальным символом

            Для приоритета операций можно выбрать какой-то специальный символ. Какой именно, надо подумать. Но пока что для обсуждения выберем «^» — треугольник вершиной вверх, которого нет на клавиатуре.
a ^= b ▲▲▲% c ▲▲!= 0 ▲| d ▲▲▲<< 2 ▲▲== e
a ^= ((b % c) != 0) | ((d << 2) == e)		// эквивалентная запись в традиционной форме
Какая запись нагляднее — обсуждаемая или традиционная?

Понижение приоритета операций специальным символом

            Приоритеты операций можно не только повышать, но и понижать:
a ▼▼^= b ▲% c != 0 ▼| d ▲<< 2 == e
Такой вариант тоже имеет право на рассмотрение.

Переопределение операций

            Поскольку повышение и понижение приоритета операций затрагивают только форму записи, но не семантику, то в переопределении операций ничего не меняется. Например, записанная двумя символами операция «&» не требует переопределения «&&». Переопределение последней нужно даже запретить.

Плюсы и минусы

            Плюсы:
  • делает возможным запись выражений без скобок. Скобки, честно говоря, не слишком хороший ориентир при визуальном анализе выражений.
  • программист может писать выражения, будучи уверенным, что порядок операций будет таким, как он задумал, без заглядывания в таблицу приоритетов. То есть упор на логику, а не на память.
            Минусы:
  • Ломает традиции. Наверно, даже чересчур.
  • Операции «++» (инкремент), «--» (декремент), «**» (возведение в степень) оказываются «заняты», а комментарии и вовсе придётся записывать по-другому из-за «//». А каким символам с клавиатуры должны соответствовать «▲» и «▼» — вообще непонятно.

Вычисление приоритетов в выражениях

            Формула расчёта приоритета операции:
<итоговый приоритет> = <множитель> * <число приоритетов> + <собственный приоритет>
где:
  • <множитель> — количество повышений приоритета (количество символов «▲» или уровень вложенности скобок).
  • <число приоритетов> — количество возможных приоритетов в языке программирования. В C++ число приоритетов, в зависимости от источника информации, колеблется 14 до 17.
  • <собственный приоритет> — приоритет конкретной операции. Например, в C++ приоритет операции «=» равен 1 (если отсчёт с нуля), а операции «||» равен 2. Отсчёт от нуля, чем выше приоритет — тем раньше выполнится операция. самый низкий приоритет — нулевой.

Нужен ли ещё один синтаксический сахар?

Когда-то был популярен такой упрёк в адрес Microsoft:

Вместо того, чтобы повысить надёжность программ, убрать все ошибки, сделать интерфейс проще и удобнее и убрать тормоза, они добавляют лишние свистки и колокольчики! Кому нужна лишняя функциональность? Лучше бы побороли глюки!

            И с этой идеей можно предъявить претензии в том же духе: «Сколько можно совершенствовать синтаксис? Зачем нужна ещё одна форма записи? Может, лучше поработать не над формой, а над содержанием?» И в этих словах будет немало истины...

P.S. «Ну, за проезд!» Когда-то Владислав напомнил мне анекдот:

В автобусе едет мужик. Достал бутылку водки и стакан, налил себе, поднёс ко рту и застыл в ступоре, вроде как забыл что-то важное. А тут по автобусу идёт контролёр:
— Мужчина, за проезд!
Тут его осенило:
— Ну, за проезд!

И вот пару лет спустя Владислав стал тем самым автобусным контролёром, который подтолкнул мою фантазию к теме приоритетов операций :)

Последняя правка: 2018-11-27    22:32

Оцените

Отзывы

     2018/11/26 11:57, ВежливыйЛис

Диез и бемоль — для повышения и понижения

     2018/11/26 12:33, Автор сайта

Есть такие символы в Юникоде: ♯, ♭. Но их нет на клавиатуре. Не лучший для языка вариант — использовать то, чего нет на клавиатуре. Ну и большинство не знакомо с нотной грамотой. Зачем использовать неочевидные для этих людей символы?

     2018/11/27 02:25, ВежливыйЛис

Кроме изменения приоритета, можно ещё дополнять состав операций.

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

Гейт переводит одно состояние регистра в другое. Действие гейта на регистр можно записать так: G∣R⟩=∣R′⟩

https://neerc.ifmo.ru/wiki/index.php?title=%D0%9A%D0%B2%D0%B0%D0%BD%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%B3%D0%B5%D0%B9%D1%82%D1%8B

     2018/11/27 14:45, Comdiv

Всё это только запутывает.

     2018/11/27 22:26, Автор сайта

ВежливыйЛис: Далёк я от квантовых гейтов и этой темы вообще... Если Вы имеете в виду прямо в языке описывать использование регистров процессора, то это слишком низкий уровень. Управление «железом» надо прятать под капот.
Comdiv: Мне кажется, что если выбирать из описанных выше вариантов, то наиболее доходчивый из них — повышение приоритета повторением символа. Типа «+++». Но это не повод отменять скобки. А Ваш выбор какой? Не трогать традиции, ничего не выдумывать, оставить всё как есть?

     2018/11/28 14:35, Comdiv

Всё зависит от целей создания языка. Если цель поразвлекаться, то и не такое можно придумать. Если ставятся практические задачи, то выдумывание на ровном месте без попыток осмысления последствий только вредит делу.
Какую задачу решает изменение приоритетов?

     2018/11/28 22:25, Автор сайта

Всё началось с того, что возникли сомнения, а нужны ли разные обозначения для логических и побитовых операций. Большой надобности в них действительно нет, но Владислав справедливо заметил, что у них разный приоритет, что создаёт реальные удобства в программировании. Вот поэтому возникли мысли, а как сделать удобнее? Есть разные варианты, в том числе и экзотические. Вопрос только — насколько они удобны и полезны.

     2018/11/29 04:50, Freeman

Дополнение состава операций есть в языке Эйфель (Eiffel) Бертрана Мейера. В нем есть даже «функциональные клавиши» — комбинации значков, не назначенные никакой операции, — с расчетом на то, чтобы программистам было куда привязывать свои придумки, не перекрывая традиционные.

Повышение приоритета повторением превращает язык операций в вики-разметку: 2+++1 без пробелов больше невозможны, нужно явно писать 2++ + 1, 2 + ++1 или 2 +++ 1.

С точки зрения вики-разметки клавиши ▲ и ▼ на клавиатуре есть. Это скобки. Дело в том, что указание приоритетов в самом выражении (а не в DSL/настройках) вынуждает читателя кода работать стековой машиной. Человеческий мозг — плохая стековая машина. Для повышения человечности нужно переходить от стека к визуальному представлению, что и возвращает нас к скобкам.

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

     2018/11/29 16:11, Автор сайта

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

Согласен. Она, по крайней мере, прошла проверку временем.

2+++1 без пробелов больше невозможны

Возможны, если пожертвовать инкрементом, т.е. за инкрементом закрепить другие символы, а «+» оставить только за сложением.

     2018/11/30 17:56, Freeman

Перевод инкремента на другие символы — снова нарушение правила вики.

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

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

Авторизация

Регистрация

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

Карта сайта


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Комментарии

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

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

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

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

●  Помеченные комментарии

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

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

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

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

Циклы

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

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

Изменение приоритетов операций

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

●  Изменение длины объекта в стеке во время исполнения

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

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

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

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

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

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

Компилятор

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

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

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

Новости и прочее

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

2018/12/16 17:17 ••• Геннадий Тышов
✎ Программирование без программистов — это медицина без врачей

2018/12/07 08:57 ••• Автор сайта
✎ Почему обречён язык Форт

2018/12/07 08:36 ••• Автор сайта
✎ Нужны ли беззнаковые целые?

2018/12/03 13:51 ••• kt
✎ Экстракоды при синтезе программ

2018/11/30 17:56 ••• Freeman
✎ Изменение приоритетов операций

2018/11/30 17:20 ••• Автор сайта
✎ Почему языки с синтаксисом Си популярнее языков с синтаксисом Паскаля?

2018/11/26 14:23 ••• Автор сайта
✎ Так ли нужны операции «&&», «||» и «^^»?

2018/11/18 15:21 ••• Freeman
✎ Устарел ли текст как форма представления программы

2018/11/17 03:28 ••• Comdiv
✎ Изменение длины объекта в стеке во время исполнения

2018/11/16 12:53 ••• Автор сайта
✎ Помеченные комментарии

2018/11/11 14:01 ••• Александр Коновалов aka Маздайщик
✎ Нерабочий код

2018/11/11 13:39 ••• Александр Коновалов aka Маздайщик
✎ О русском языке в программировании