Читайте также: |
|
Стало модным относиться к нотации как ко вторичному аспекту, целиком зависящему от личных вкусов. Это отчасти верно, хотя выбор нотации не должен быть случайным. У этого выбора имеются последствия, обнаруживаемые в общем облике языка.
Общеизвестным плохим примером является выбор знака равенства для обозначения присваивания, восходящий к языку 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 | Нарушение авторских прав