Здравствуйте, zitz, Вы писали:
Z>В моем потоке небыло ниодно человека, который не понял операции присваивания в си. Может матиматиков это и сбивает, но обычный человек когда смотрит на = не задумывается о "симметричности"!
Я тоже понимаю, что = в C++ обозначает присваивание. И при чтении исходника это не вызывает проблем. Но я не программирую только на C, есть еще другие языки, SQL и т. д. И когда часто переключаешься между двумя языками, возникают опечатки (руки сами пишут). Так вот, одним из достоинств паскалевского синтаксиса является то обстоятельство, что односимвольная опечатка в большинстве случаем (только если это не имя идентификатора) приводит к ошибке компиляции. Хоть С я изучил раньше паскаля, но все равно мне часто приходилось натыкаться свои же опечатки, которые приводили к синтаксически, но не семантически корректной программе.
MS>Общеизвестным плохим примером является выбор знака равенства для обозначения присваивания, восходящий к языку Fortran в 1957 г. и слепо повторяемый до сих пор массой разработчиков языков. Эта плохая идея низвергает вековую традицию использования знака "=" для обозначения сравнения на равенство, предиката, принимающего значения true или false.
MS>Я не понял выделенного, что значит вековая традиция в его понимании? Сколько лет coputer science (
Здравствуйте, mefrill, Вы писали:
MS>>>Я по-прежнему считаю, что использование = вместо := более логично (к тому-же меньше синтаксического оверхеда VD>>Оно не более логично, и не менее логично. Это просто соглашение языка. С++ != математике! Вот и все!
M>Согласен, но тем не менее изучение языка это легче не делает. Ведь человек интуитивно воспринимает семантику символа = так, как его учили с детства. А учили его математике, а не программирвоания. А там вообще при записи подразумевается именно равенство. Поэтому изучающему трудно перестроится. Тем самым создаются дополнительные барьеры на пути неофита. Что по мне, так мне и := не нравится тоже. Логично было бы использовать кнтовскую нотацию <-. Вот здесь как раз все кажется понятно.
Мне нравится запись <=, но она задействована под .LE.
А принципе, есть свободная комбинация: =>, т.е. вполне можно было бы писать так:
x+y => z; // результат операции (x+y) помещаем в z;
Мне вообще кажется что такая запись более логичная, когда целевую ячейку хранения указываем в правой части выражения, а не в левой. Тогда при множественном присвоении мы будем двигаться слева направо, что более естественно при прочтении.
Хотя, в случае длинных выражений, не факт что это будет читабельно:
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Так у Вирта в статье как раз такая галиматья и критикуется:
Ну извините, фигню можно на чём угодно написать Можно подумать, если Вирт встретит вот такой код на Обероне, он запрыгает от восхищения?
if 0+x+1+1+x+1+1+x+x # 1+1+1+1+x+1+x+1+1+1 then
Die
end;
СГ>На языке C программист может написать конструкцию x+++++y, загадку, а не выражение, представляющую проблему даже для сложного синтаксического анализатора. Равняется ли значение этого "выражения" значению ++x+++y+1?
Нет загадки, правила лексического анализа однозначны. x+++++y это x ++ ++ + y, а второе выражение равно ++ x ++ + y + 1
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Так у Вирта в статье как раз такая галиматья и критикуется:
Так мы ее собственно и обсуждаем
СГ>
Я нахожу совершенно удивительной невозмутимость, с которой мировое сообщество программистов приняло этого нотационного монстра.
Интересно, а Вирта не смущает то, что в английском языке можно точно такие же невнятные конструкции строить?
А невозмутимость оттого, что нормальный человек на такие мелочи внимания не обращает. Не мешает — и фиг тогда с ней. Все остальное устраивает — ну и отлично. К чему все эти сотрясания воздуха!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
СГ>Так можно было бы постулировать новую алгебру. Я нахожу совершенно удивительной невозмутимость, с которой мировое сообщество программистов приняло этого нотационного монстра. В 1962 г. установившиеся традиции аналогичным образом подорвало постулирование правой ассоциативности операций в языке APL. Тогда x+y+z неожиданно стало обозначать x+(y+z), а x-y-z — x-y+z.
Ну и что? Особенности АПЛовской грамматики. Причём вполне объяснимые.
1) В языке большое количество 1- и 2-арных операторов, и расставлять между ними приоритеты — это только забивать голову и программисту, и парсеру. Поэтому волюнтаристски принято, что у всех операторов одинаковый приоритет.
2) Оператор присваивания правоассоциативный, поэтому для унификации принято, что все операторы правоассоциативные. Иначе присваивание пришлось бы переписывать в форме x*y*z -> dst
Да, это непривычно по сравнению с калькулятором, где все операторы также имеют равный приоритет, но левоассоциативны. И там действительно присваивание происходит в конце: x*y*z M+
Во всяком случае, единожды запомнив правила, в APL больше не запутаешься среди его безумных кружочков и звёздочек.
Вон язык Forth — тоже с непривычки ужасен. А на самом деле прост как сибирский валенок. И через это очень удобен.
Здравствуйте, Кодт, Вы писали:
К>2) Оператор присваивания правоассоциативный, поэтому для унификации принято, что все операторы правоассоциативные. Иначе присваивание пришлось бы переписывать в форме x*y*z -> dst
...что, кстати, было бы не такой уж и плохой идеей.
СГ>>Так можно было бы постулировать новую алгебру. Я нахожу совершенно удивительной невозмутимость, с которой мировое сообщество программистов приняло этого нотационного монстра. В 1962 г. установившиеся традиции аналогичным образом подорвало постулирование правой ассоциативности операций в языке APL. Тогда x+y+z неожиданно стало обозначать x+(y+z), а x-y-z — x-y+z.
К>Ну и что? Особенности АПЛовской грамматики. Причём вполне объяснимые.
Мои 5 копеек вдобавок к твоим.
3. Кроме монад и диад там есть причастия, конъюнкции (можно сказать функции высшего порядка) и цепочки (verb trains). Появление хотя бы одного такого конструкта существенно влияет на порядок разбора выражения. Введение приоритетов обычных глаголов сделало бы этот порядок вообще непостижимым.
4. В математике исторически композиция (f#g#h)(x), (что равносильно f g h x в АПЛ), это как раз f(g(h(x))), то есть ассоциативность правая. Распространение этого правила на остальные функции позволяет достичь единообразия.
К>Да, это непривычно по сравнению с калькулятором, где все операторы также имеют равный приоритет, но левоассоциативны. И там действительно присваивание происходит в конце: x*y*z M+
В обычном калькуляторе (не МК51) "(a+b)/(c+d)" невозможно вычислить без применения дополнительной памяти. Убогость!
К>Во всяком случае, единожды запомнив правила, в APL больше не запутаешься среди его безумных кружочков и звёздочек. Вон язык Forth — тоже с непривычки ужасен. А на самом деле прост как сибирский валенок. И через это очень удобен.
Согласен. Не нужно недооценивать адаптивные возможности человека!
Здравствуйте, dshe, Вы писали:
D>Здравствуйте, Кодт, Вы писали:
К>>2) Оператор присваивания правоассоциативный, поэтому для унификации принято, что все операторы правоассоциативные. Иначе присваивание пришлось бы переписывать в форме x*y*z -> dst
D>...что, кстати, было бы не такой уж и плохой идеей.
Ну... может идея и не плохая, но я часто ищу по исходному тексту предыдущее присваивание значения переменной "a". А это проще делать, когда смотришь по левому краю, нежели по правому.
Здравствуйте, vdimas, Вы писали:
V>А принципе, есть свободная комбинация: =>, т.е. вполне можно было бы писать так:
V>x+y => z; // результат операции (x+y) помещаем в z;
V>Мне вообще кажется что такая запись более логичная, когда целевую ячейку хранения указываем в правой части выражения, а не в левой. Тогда при множественном присвоении мы будем двигаться слева направо, что более естественно при прочтении.
Логичное не значит удобное. В присваивании достаточно важна информация о том, какой переменной присваивается значение. И часто эту информацию нужно искать по коду. У левого края выравнивание лучше, поэтому поиск по нему проще. А правый край вообще в случае сложных варажений может уехать за границы окна.
Здравствуйте, Mystic, Вы писали:
M>Здравствуйте, dshe, Вы писали:
D>>Здравствуйте, Кодт, Вы писали:
К>>>2) Оператор присваивания правоассоциативный, поэтому для унификации принято, что все операторы правоассоциативные. Иначе присваивание пришлось бы переписывать в форме x*y*z -> dst
D>>...что, кстати, было бы не такой уж и плохой идеей.
M>Ну... может идея и не плохая, но я часто ищу по исходному тексту предыдущее присваивание значения переменной "a". А это проще делать, когда смотришь по левому краю, нежели по правому.
Это привычка. На текущий момент уже поздно что-то менять, поскольку данный стереотип (правое присваивается левому) надежно укоренился в сознании большинства программистов. Хотя, надо признать, существовали языки в которых присваивание делалось слева направо. Одним из агрументов именно такой семантики присваивания было то, что в большинстве естественных языков (за исключением семитских) текст читается сверху вниз слева направо, поэтому текст программы (и потоки данных) удобно было бы направлять тоже сверху вниз и слева направо.
Сергей Губанов wrote: > x+++++y+1==++x+++y > x+++y++==x+++++y+1
Реально такое почти нигде не используется, так что проблем не
доставляет. А вот шорткаты в виде a++ и ++a — очень удобны.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>4. В математике исторически композиция (f#g#h)(x), (что равносильно f g h x в АПЛ), это как раз f(g(h(x))), то есть ассоциативность правая. Распространение этого правила на остальные функции позволяет достичь единообразия.
Когда это в математике инфиксные операторы с равным приоритетом (вроде тех же сложения и вычитания) были правоассоциативными?
И какую оценку поставил бы учитель арифметики школьнику, получившему в результате вычисления выражения 2 — 1 — 1 двойку?
А правоассоциативность f#g#h(x) и так соблюдается "автоматически": f(g(h(x))).
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
AVC,
LCR>>4. В математике исторически композиция (f#g#h)(x), (что равносильно f g h x в АПЛ), это как раз f(g(h(x))), то есть ассоциативность правая. Распространение этого правила на остальные функции позволяет достичь единообразия.
AVC>Когда это в математике инфиксные операторы с равным приоритетом (вроде тех же сложения и вычитания) были правоассоциативными?
Операция возведения в степень, операция извлечения корня. А также специальные операторы, например "плюс с крышечкой", смысл которого может меняться от статьи к статье в широких пределах.
AVC>И какую оценку поставил бы учитель арифметики школьнику, получившему в результате вычисления выражения 2 — 1 — 1 двойку?
Плохую, плохую. Исторически сложилось, что минус левоассоциативен.
AVC>А правоассоциативность f#g#h(x) и так соблюдается "автоматически": f(g(h(x))).
Совершенно верно. Взгляните на этот зоопарк:
Есть бинарные инфиксные левоассоциативные операторы с различными приоритетами.
Есть бинарные инфиксные правоассоциативные операторы с различными приоритетами.
Есть унарные операторы — правоассоциативны.
Есть функции — тоже правоассоциативны.
Но во-первых, операторы — это тоже функции. Во-вторых, добавление сюда функторов со своими приоритетами сделает нотацию неподъёмной — я об этом уже писал.
Зададимся целью упростить вещи. Поскольку все операторы — это функции, то пусть операторы будут так же ассоциативны справа и все будут одинакового приоритета. Это простое правило позволяет избавиться от скобок и единообразно рассматривать выражения смешанные из функций, определённых пользователем и функций из системы:
a =: % *: 10 myop 20
Здесь посчитано выражение 1/(myop(10, 20)^2), где myop определён пользователем. Заметим, что соглашения выше позволяют существенно разгрузить выражение от скобок и препинаний.
Можно ввести левую ассоциативность на функциях (опять же без приоритетов). Получится карринг из языков ML и Haskell:
f g h x y z (* вычисляется как (((((f g) h) x) y) z) *)
Опять же такая унификация позволяет существенно уменьшить потребность в скобках и препинаниях.
Наконец, если вы пользовались калькулятором MK51, то наверное отметите тот простой факт, что тот способ вычисления (+ 3 4) требует привыкания, но оказывается очень мощным. На одном дыхании вычислять очень сложные выражения, в то время как пользователи обычных калькуляторов вынуждены использовать бумагу для записи промежуточных результатов.
В качестве вывода: человек — достаточно гибкое существо, и во многих случаях оправдан отход от исторически сложившихся канонов с целью упрощения вещей.
Здравствуйте, Mystic, Вы писали:
M>Логичное не значит удобное. В присваивании достаточно важна информация о том, какой переменной присваивается значение. И часто эту информацию нужно искать по коду. У левого края выравнивание лучше, поэтому поиск по нему проще. А правый край вообще в случае сложных варажений может уехать за границы окна.
Да понятно, сам же и написал об этом.
Кстати — это, похоже, одна из причин, почему математики любят короткие нотации. У них зачастую результат приведения/упрощение/преобазования как раз справа находится.
a := sin(phi);
b := 3*a + sin(3*phi) + alpha;
c := a + b;
if a > arcsin(pi/4) then ; // Что такое a???
В данном случае я должен:
1. Поднять взгляд на строку выше
2. Прочитать c
3. Поднять взгляд на строку выше
4. Прочитать b
5. Поднять взгляд на строку выше
6. Прочитать a
7. Прочитать sin(phi)
А вот если бы это было так:
sin(phi) -> a
3*a + sin(3*phi) + alpha -> b
a + b -> c
if a > arcsin(pi/4) then ; // Что такое a???
То найти предыдущее присваивание сложнее:
1. Поднять взгляд на строку выше
2. Перевести взгляд в конец строки
3. Прочитать c
4. Поднять взгляд на строку выше
5. Перевести взгляд в конец строки
6. Прочитать b
7. Поднять взгляд на строку выше
8. Перевести взгляд в конец строки
9. Прочитать a
10. Перевести взгляд в начало строки
11. Прочитать sin(phi)
Итого большая нагрузка на глазные яблоки, больше усталось, больше опечаток, ниже качество, ...
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
AVC>>Когда это в математике инфиксные операторы с равным приоритетом (вроде тех же сложения и вычитания) были правоассоциативными?
LCR>Операция возведения в степень, операция извлечения корня. А также специальные операторы, например "плюс с крышечкой", смысл которого может меняться от статьи к статье в широких пределах.
Честно говоря, о возведении в степень я не подумал. Поэтому Ваш аргумент мне понравился.
Из известных мне (в прежние времена ) ЯП, оператор возведения в степень присутствует в Алголе-60 и Фортране.
Правда, вот незадача — в обоих случаях он левоассоциативен.
Это значит, что, например, в Алголе выражение a^b^c вычисляется как (a^b)^c = a^(b*c), а не как a^(b^c).
Вообще, в Алголе, как и в его потомках — Паскале и Обероне — операции с равным приоритетом всегда выполняются слева направо. Поэтому трудностей в понимании выражений нет.
Насчет же оператора "плюс с крышечкой" аргумент, конечно, неотразимый, учитывая, что его смысл "может меняться от статьи к статье в широких пределах". Тут я бессилен.
AVC>>А правоассоциативность f#g#h(x) и так соблюдается "автоматически": f(g(h(x))).
LCR>Совершенно верно. Взгляните на этот зоопарк:
LCR>Есть бинарные инфиксные левоассоциативные операторы с различными приоритетами. LCR>Есть бинарные инфиксные правоассоциативные операторы с различными приоритетами. LCR>Есть унарные операторы — правоассоциативны. LCR>Есть функции — тоже правоассоциативны.
LCR>Но во-первых, операторы — это тоже функции. Во-вторых, добавление сюда функторов со своими приоритетами сделает нотацию неподъёмной — я об этом уже писал.
LCR>Зададимся целью упростить вещи. Поскольку все операторы — это функции, то пусть операторы будут так же ассоциативны справа и все будут одинакового приоритета. Это простое правило позволяет избавиться от скобок и единообразно рассматривать выражения смешанные из функций, определённых пользователем и функций из системы: LCR>
LCR>a =: % *: 10 myop 20
LCR>
LCR>Здесь посчитано выражение 1/(myop(10, 20)^2), где myop определён пользователем. Заметим, что соглашения выше позволяют существенно разгрузить выражение от скобок и препинаний.
Скажу прямо — упрощенное Вами выражение я разобрать не смог (что, конечно, еще не аргумент).
Возможно, мне не хватило знания деталей какой-нибудь нотации, широкоизвестной в узких кругах.
Например, "*" могло бы означать возведение в квадрат, а "%" — получение обратной величины.
Но какой знак используется в таком случае для обычного умножения?
LCR>Наконец, если вы пользовались калькулятором MK51, то наверное отметите тот простой факт, что тот способ вычисления (+ 3 4) требует привыкания, но оказывается очень мощным. На одном дыхании вычислять очень сложные выражения, в то время как пользователи обычных калькуляторов вынуждены использовать бумагу для записи промежуточных результатов.
Насколько я понимаю, Вы предлагаете программисту самолично построить и линеаризовать в префиксном порядке синтаксическое дерево.
По видимому, дальше Вы предложите и код сгенерить вручную?
LCR>В качестве вывода: человек — достаточно гибкое существо, и во многих случаях оправдан отход от исторически сложившихся канонов с целью упрощения вещей.
Создается впечатление, что простоту каждый понимает по своему.
Что "функциональщику" просто, то "императивщику" — ночной кошмар.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Lazy Cjow Rhrr, Вы писали:
LCR>>>4. В математике исторически композиция (f#g#h)(x), (что равносильно f g h x в АПЛ), это как раз f(g(h(x))), то есть ассоциативность правая. Распространение этого правила на остальные функции позволяет достичь единообразия.
AVC>>Когда это в математике инфиксные операторы с равным приоритетом (вроде тех же сложения и вычитания) были правоассоциативными?
LCR>Операция возведения в степень, операция извлечения корня. А также специальные операторы, например "плюс с крышечкой", смысл которого может меняться от статьи к статье в широких пределах.
Возведение в степень и извлечения корня — не инфиксные операторы. А всякие "плюсы с крышечками" не бывают правоассоциативными.