Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Нотация и синтаксис



Читайте также:
  1. I. Аннотация учебной дисциплины
  2. Аннотация
  3. Аннотация
  4. Аннотация
  5. Аннотация
  6. Аннотация
  7. Аннотация

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

Общеизвестным плохим примером является выбор знака равенства для обозначения присваивания, восходящий к языку Fortran в 1957 г. и слепо повторяемый до сих пор массой разработчиков языков. Эта плохая идея низвергает вековую традицию использования знака "=" для обозначения сравнения на равенство, предиката, принимающего значения true или false. Но в Fortran этот символ стал обозначать присваивание, принуждение к равенству. В этом случае операнды находятся в неравном положении: левый операнд, переменная, должен быть сделан равным правому операнду, выражению. Поэтому x = y не означает то же самое, что y = x. В языке Algol эта ошибка была исправлена путем простого решения: присваивание обозначили через ":=".

Программистам, привыкшим к использованию знака равенства для обозначения присваивания, это может показаться придиркой. Но смешивание присваивания и сравнения действительно является плохой идеей, поскольку в этом случае требуется другой символ для того, что традиционно выражает знак равенства. Сравнение на равенство стали обозначать двумя символами "==" (впервые в языке C). Это является отвратительным последствием, приведшим к аналогичным плохим идеям использования "++", "--", "&&" и т.д.

В языках C, C++, Java и C# некоторые из этих операций вызывают побочные эффекты, известный источник ошибок программирования. Например, можно было бы принять "++" для обозначения увеличения значения на единицу, если бы то же самое не обозначало само увеличенное значение, что позволяет писать выражения с побочными эффектами. Неприятность состоит в удалении фундаментального различия между оператором и выражением. Оператор - это инструкция, подлежащая выполнению, выражение - это значение, которое надлежит вычислить.

Уродство конструкции обычно проявляется в комбинации с другими средствами языка. На языке C программист может написать конструкцию x+++++y, загадку, а не выражение, представляющую проблему даже для сложного синтаксического анализатора. Равняется ли значение этого "выражения" значению ++x+++y+1? Верны ли следующие соотношения?

x+++++y+1==++x+++y

x+++y++==x+++++y+1

Так можно было бы постулировать новую алгебру. Я нахожу совершенно удивительной невозмутимость, с которой мировое сообщество программистов приняло этого нотационного монстра. В 1962 г. установившиеся традиции аналогичным образом подорвало постулирование правой ассоциативности операций в языке APL. Тогда x+y+z неожиданно стало обозначать x+(y+z), а x-y-z - x-y+z.

У условного оператора языка Algol, представляющего пример неудачного синтаксиса, а не только плохого выбора символов, имелось две формы (S0 и S1 обозначают некоторые операторы):

if b then S0

if b then S0 else S1

Это определение порождает очевидную двусмысленность, получившую название проблемы "висящего else". Например, оператор

if b0 then if b1 then S0 else S1

можно интерпретировать двумя способами, а именно,

if b0 then (if b1 then S0 else S1) и

if b0 then (if b1 then S0) else S1,

возможно, приводящими к совершенно разным результатам. Следующий пример еще более серьезен:

if b0 then for i:= 1 step 1 until 100 do if b1 then S0

else S1,

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

if b0 then [for i:= 1 step 1 until 100 do if b1 then S0

else S1]

и

if b0 then [for i:= 1 step 1 until 100 do if b1 then S0]

else S1

Однако выйти из положения здесь достаточно просто: нужно использовать явный символ end в каждой конструкции, являющейся рекурсивной, и начинать с явного стартового символа, такого как if, while, for или case:

if b then S0 end

if b then S0 else S1 end


Дата добавления: 2015-07-10; просмотров: 92 | Нарушение авторских прав






mybiblioteka.su - 2015-2024 год. (0.007 сек.)