B>>так что получается в обероне точно так же програмист не может быть "уверен, что перед следующим оператором после выхода из цикла выполняется условие ~p (NOT p)."
СГ>Может. Таково одно из положений структурного программирования. СГ>
СГ>WHILE p DO
СГ> ...
СГ>END;
СГ>
Лично мне нас**ть на "положения структурного программирования". Если в С можно выйти по брейку из цикла любого типа, а в Обероне для этого нужно использовать особый цикл, это говорит лишь о большей гибкости С, и Оберону здесь хвалиться нечем. Я часто проверяю условие p именно с целью узнать, как произошел выход из цикла: по брейку или "мирным путем". Меня за это расстреляют или наказание будет более жестокое: год программирования на Обероне?
Я отвечаю за свои слова, а не за то как вы их интерпретируете!
Здравствуйте, Mamut, Вы писали:
M>Блин. Костыль на костыле. Объясните мне какая разница между: M>
M>while
M> if
M> exit
M>
M>и M>
M>for
M> if
M> exit
M>
M>Почему в Обероне я не могу написать первый случай?
Не можете написать ни первый ни второй случай. В чем смысл вопроса я не понял. Где костыли (хотя бы один) я тоже не понял.
M>И еще вопрос. Что удобнее писать: M>
M>while(!stream.eof())
M>{
M> // code
M>}
M>
M>или M>
M>LOOP
M> IF ~stream.end THEN
M> {* code *}
M> END
M>END
M>
M>?
Тоже странный вопрос. В первом случае используется цикл с проверкой условия в начале итерации. Во втором случае используется безусловный цикл (исполняющийся вечно).
Здравствуйте, moudrick, Вы писали:
СГ>>Я немного оптимизировал: наиболее вероятная ветвь исполнения всегда должна идти после THEN, наименее вероятная ветвь в ELSE — такого требование современных конвеерных процессоров.
M>А что, команды языка Оберон напрямую транслируются в машинный команды?
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, moudrick, Вы писали:
СГ>>>Я немного оптимизировал: наиболее вероятная ветвь исполнения всегда должна идти после THEN, наименее вероятная ветвь в ELSE — такого требование современных конвеерных процессоров.
M>>А что, команды языка Оберон напрямую транслируются в машинный команды?
СГ>Есть и такие, но причем тут это?
При том, что разговор зашел про *требование современных конвейерных процессоров*, а не про требования современных виртуальных оберон-машин.
Здравствуйте, Слава Шевцов, Вы писали:
СШ>Здравствуйте, Сергей Губанов, Вы писали:
CГ>>Я немного оптимизировал: наиболее вероятная ветвь исполнения всегда должна идти после THEN, наименее вероятная ветвь в ELSE — такого требование современных конвеерных процессоров.
СШ>А в чём прикол? Вроде сумма длин прыжков (для каждой ветки) в обоих случаях одинакова и число разрывов конвеера тоже. Или?
Признаться честно, мне не известны тонкости реализации конвееров. Но то что данные из оперативной памяти грузятся в регистр процессора много тактов всем известный факт. Так вот, очевидно, что для ускорения работы надо "смотреть в перед" и загружать те данные, которые в скором времени понадобятся заранее. Спрашивается как быть процессору если встречается оператор ветвления? Данные из какой ветви загружать заранее? Предпочтение отдается главной ветви (т.е. коду в THEN, а код в ELSE считается исполняемым с меньшей вероятностью. Прошу прощения если не совсем прав, еще раз напоминаю, что мне не известны тонкости реализации конвееров.
Здравствуйте, Пацак, Вы писали:
П>Ну и где хваленое превышение в разы?
33/24 = 1.375
12/9 = 1.3333
Тоже не хилый оверхедец.
А если переписать си-образный код так как положено по общепринятым стандартам кодирования в промышленном программировании — фигурные скобки в любом случае и на новой строке, то и без того не хилый оверхедец возрастет еще.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Пацак, Вы писали:
П>>Ну и где хваленое превышение в разы?
СГ>33/24 = 1.375 СГ>12/9 = 1.3333
СГ>Тоже не хилый оверхедец.
Методика посчета — весьма спорная. Это следует из оценок на Ваших сообщениях с методикой.
СГ>А если переписать си-образный код так как положено по общепринятым стандартам кодирования в промышленном программировании — фигурные скобки в любом случае и на новой строке, то и без того не хилый оверхедец возрастет еще.
Покажите мне:
1. Промышленные программы на обероне.
2. Промышленные стандарты программирования на обероне.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Слава Шевцов, Вы писали:
СШ>>Здравствуйте, Сергей Губанов, Вы писали:
CГ>>>Я немного оптимизировал: наиболее вероятная ветвь исполнения всегда должна идти после THEN, наименее вероятная ветвь в ELSE — такого требование современных конвеерных процессоров.
СШ>>А в чём прикол? Вроде сумма длин прыжков (для каждой ветки) в обоих случаях одинакова и число разрывов конвеера тоже. Или?
СГ>Признаться честно, мне не известны тонкости реализации конвееров. Но то что данные из оперативной памяти грузятся в регистр процессора много тактов всем известный факт. Так вот, очевидно, что для ускорения работы надо "смотреть в перед" и загружать те данные, которые в скором времени понадобятся заранее. Спрашивается как быть процессору если встречается оператор ветвления? Данные из какой ветви загружать заранее? Предпочтение отдается главной ветви (т.е. коду в THEN, а код в ELSE считается исполняемым с меньшей вероятностью. Прошу прощения если не совсем прав, еще раз напоминаю, что мне не известны тонкости реализации конвееров.
Не совсем. Динамическое предсказание ветвлений рулит. здесь
П>>Ну и где хваленое превышение в разы?
СГ>33/24 = 1.375 СГ>12/9 = 1.3333
СГ>Тоже не хилый оверхедец.
Неплохо. Я в восторге. Нет, я просто тащусь от того, как научный работник умело подтасовывает данные. Только давайте поставим рядом исходные данные и внимательно на них посмотрим:
П>Итого: П>лексем — 24 П>строк кода — 12 П>символов (не считая отступов) — 236
П>Итого: П>лексем — 33 П>строк кода — 9 П>символов (не считая отступов) — 175
Тогда мы сразу увидим, по строкам оверхед не в пользу Оберона, а совсем наоборот! Не говоря уже о том, что по символам (которые собственно и наколачивает бедный программист) оверхед Оберона составляет 236/175 = 1.35
Если после этого у Вас не появится желания выпить йаду или застрелиться, то, я надеюсь, хотя бы пропадет желание писать сюда.
Я отвечаю за свои слова, а не за то как вы их интерпретируете!
Здравствуйте, CrystaX, Вы писали:
CX>Так Вы о чем говорите? О языке или о IDE? Определитесь пожалуйста.
Сначала хочу извиниться за задержку с ответами. Сейчас у меня Интернет только дома, отвечать могу только в нерабочее время, и, увы, похоже, я не успею ответить на все вопросы и возражения.
Что касется Вашего вопроса: язык или IDE, язык или среда.
Вопрос разумен.
Но особенность ситуации в том, что в обероновской среде нет никакого отдельного IDE.
Все перечисленные возможности программист получает практически "бесплатно". Также он может добавлять в среду новые возможности и развивать ее по своему усмотрению.
Считаю, что объединение мной особенностей языка и среды в данном случае совершенно правомерно.
Язык Оберон и был создан для того, чтобы создавать объектно-ориентированные программные системы с подобными свойствами.
Также как Си был создан в процессе работы над системой UNIX, основанной на других принципах (которые мне тоже нравятся).
Конечно, случаются и "традиционные" IDE для программирования на Обероне. Например, XDS Modula-2/Oberon-2. К таким случаям сказанное мной об обероновских документах неприменимо.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Sergey J. A., Вы писали:
SJA>Разрешите вклинится. SJA>Мой е2-е4:
"Остап не баловал соперников разнообразием дебютов". ("12 стульев")
AVC>>а) Соответствие структурным принципам.
AVC>>В отличие от синтаксиса Модулы/Оберона синтаксис Си/Си++ не соответствует принципам структурного программирования. AVC>>Рассмотрим хотя бы циклы.
SJA>Да. Рассмотрим. SJA>Пример:
SJA>
SJA>MODULE TestTest;
SJA> IMPORT StdLog, Files;
SJA> PROCEDURE Test*();
SJA> VAR by: INTEGER;
SJA> BEGIN
SJA> by := 10;
SJA> LOOP
SJA> (*I expect by==0 after LOOP. Always. Oberon is cool.*)
SJA> IF by=0 THEN EXIT END;
SJA> by := by - 1;
SJA> EXIT;
SJA> END;
SJA> IF by # 0 THEN
SJA> (*What the fuck !*)
SJA> END;
SJA> END Test;
SJA>END TestTest.
SJA>
SJA>Итак, Оберон тоже не соответствует принципам структурного программирования.
Все это замечательно, но... неверно.
(Наверное, я должен добавить "ИМХО"? )
Цикл LOOP ничего не "обещает" читателю программы. Он введен для особых ситуаций, где применение WHILE и REPEAT вызывает затруднения. В основном это обработчики прерываний и операции ввода/вывода.
Когда в программе встечается LOOP, то программист предупрежден, что в теле цикла, наверное, встретится EXIT, т.к. из этого цикла нельзя выйти другим способом, кроме как EXIT и RETURN. В Си/Си++ аналогом является бесконечный цикл for ( ; ; ).
Совсем иное дело циклы WHILE и REPEAT.
Что означает конструкция
WHILE p DO ... END; Q;
?
Она означает, что пока выполняется условие p, из цикла мы не выйдем (исключение составляет оператор возврата RETURN). Следовательно, после выхода из цикла и перед выполнением Q обязательно выполняется условие ~p. Иначе мы бы еще "крутились" в цикле WHILE (или бы уже вышли из подпрограммы).
А вот в программе на Си/Си++ в аналогичной ситуации
while (p) { ... } Q();
мы в этом не можем быть уверены (т.к. должны считаться с возможностью break или goto) и должны относиться к while практически также, как к LOOP или for ( ; ; ). Поэтому использование while не облегчает нам понимания программы.
Об этом я и написал в своем посте.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, achp, Вы писали:
AVC>>Когда программист пишет (или, что важнее, читает) на Модуле/Обероне цикл "WHILE p DO ... END" он абсолютно уверен... AVC>>...на Си/Си++, он не может быть в этом уверен, т.к. внутри цикла может находиться как оператор break, так и знаменитый goto.
A>Понимаете, мне кажется, что здесь имеется противоречие между двумя подходами к пониманию структурности.
A>"Академический" подход ставит структурность в сугубо формальные рамки и заявляет о её самоценности.
A>"Прагматический" подход рассматривает структурность как средство достижения удобства изложения алгоритма.
A>"Академический" подход спекулятивен: его сторонник созерцает код и склонен к проведению формальной верификации программ. "Вот у нас есть кусок кода — цикл. Каков его консеквент?"
A>"Прагматический" подход сугубо конструктивен: его сторонник ставит себе задачу написания кода, и применяет структурирование программы для облегчения её решения. "Напишем-ка цикл... А вот тут выйдем досрочно по break..."
A>Почему я ставлю кавычки? Теория без практики мертва, а практика без теории слепа. Ни тот, ни другой подход не является оптимальным в чистом виде. Программист должен и создавать, и сопровождать код, значит, хороший программист со спокойной совестью напишет цикл, содержащий break, но обязательно осознавая, каков консеквент цикла он имеет в виду получить, а если цикл получится большой или достаточно сложный, — ещё и задокументирует свои намерения для целей сопровождения.
A>Каков итог? Ни Оберон, ни Фортран-II популярностью не пользуются, а Си++ — пользуется.
Я получил большое эстетическое удовольствие от чтения Вашего трактата.
Правда, мне показалось, что Вы могли достичь желаемого консеквента, и не прибегая к столь спекулятивному антецеденту.
Достаточно было подсчитать количество ссылок в Гугле (или на заборе, на худой конец), что так любит при всяком удобном случае проделывать наш почтенный коллега Cyberax.
Но мы-то с Вами жаждем проникнуть в суть вещей, и не можем удовлетвориться выводом на основании голой статистики, не рассмотрев вопрос всесторонне с академической и прагматической точек зрения.
Приятно и даже умилительно сознавать, что добросовестный программист на Си/Си++ не станет прибегать к брейку, иначе как узрев мысленным взором во всех деталях консеквент цикла. После чего он (я ни секунды в том не сомневаюсь!) поспешит немедленно запечатлеть в лапидарном комментарии необоримую причину, принудившую его прибегнуть против воли к столь крайнему средству. И я уже ясно вижу, как навстречу ему в балетных тапочках и пачке грациозными прыжками приближается другой добросовестный программист, предназначеный судьбою сопровождать этот код сквозь годы тернистых испытаний. И вот он уже приник пытливым взором к исходному тексту, и светлая улыбка понимания озаряет его лицо, чтобы никогда более не покидать его. Слышна тихая музыка...
А на заднем фоне — сельский пейзаж, пастушок с пастушкой (а пастушок такой молоденький-молоденький)...
И слышно блеянье многочисленных и тучных барашков...
И здесь я просыпаюсь.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Здравствуйте, Кодт, Вы писали:
A>>>А как ты докажешь их корректность мне интересно? Насколько я знаю, доказать корректность нельзя даже для К>
A>>>double max(double a, double b) {
A>>> return a > b ? a : b;
A>>>}
К>
A>>А она и некорректна — double так не сравнивают.
К>Некорректно такое заявление. double нельзя (можно, но бессмысленно) сравнивать на равенство (операторами ==, != ), а также на строгое неравенство ( >, < ) с целью "поветвиться". К>В данном же случае криминала нет.
Ах, имелось в виду это... Не, я про другое: NaN'ы там всякие... Честно говоря, не знаю, что больше — 1, или QNaN (или исключение больше? ), но сравнение, это и ежу понятно, некорректно.
поэтому добавлю только свои комментарии. AVC>1. Собственно синтаксис.
AVC>а) Соответствие структурным принципам.
AVC>То же относится к циклам REPEAT UNTIL ~p и do {} while (p).
В данном примере в случае C++ проверяется истинность исходного условия. Для Оберона выполняется проверка его отрицания, что приводит к:
a) лишней ненужной операции — вы считаете лексемы языка, а я такты процессора;
b) запутывает алгоритм — есть такая мудрость, чтобы понять смысл алгоритма, попробуй произнести его на обычном языке; как по вашему, какая фраза проще для понимания — Оберон: "Повторять до тех пор пока не будет не выполняться p"; C++: "Повторять пока выполняется p". Так как? Какая конструкция проще для понимания?
AVC>б) Синтаксический "оверхед".
AVC>Я согласен с Сергеем, что в синтаксисе Си/Си++ заключен значительный "оверхед". AVC>Но таится он в основном в величине и сложности языка и его описания, а также в некоторых синтаксических деталях. AVC>Например, в количестве уровней и запутанности приоритетов операторов. AVC>Скажите честно: многие ли помнят таблицу приоритетов операторов Си/Си++ полностью?
Честно признаюсь не помню и большой надобности в этом не вижу. Помню только что адидтивный и мультипликативные операции имеют такой же относительный приоритет, как и в жизни (умножение выполняется раньше сложения, а "и" раньше "или"); помню, что [] выполняется раньше & (нужно для таких записей &vec[0]); помню что << и >> имеют очень низкий приоритет, поэтому писать надо так std::cout << (a + b). Для всех остальных случаев есть скобки!
AVC>2. Исходные тексты Си/Си++ и документы Оберона.
AVC>а) Документирование программ.
AVC>Вот простой пример. AVC>... AVC>А что же Си/Си++?
Как сказал Privalov — это проблема IDE, во-первых. Во-вторых, вот есть у меня код промышленной программы на C++, его объём составляет примерно 400 мегабайт, число файлов и количество строк не поддаётся исчислению... А теперь представьте, что в каждом файле будет ещё и по картинке.. Даже если это будет хорошо сжатый jpeg объём кода сразу же увеличиться эдак мегов на 500! Простите, у меня диск не резиновый! Да и читать такой исходный код будет малость утомительно — мне зачастую не нужны картинки и комментарии, хорошо написанный код с правильно подобранными именами переменных и функций, не зашумлённый лексемами сам по себе лучший комментарий.
AVC>б) Тестирование программ.
AVC>На Си/Си++ тесты, как правило, хранятся в отдельных файлах и "запускаются" отдельными скриптами, которые тоже хранятся в отдельных файлах. В итоге, хранение этих вспомогательных, но необходимых файлов вырастает в целую проблему.
Ни разу такой проблемы не встречал. Абсолютно все компиляторы или IDE позволяют выполнять пред- и пост-билд операции, большинство популярных библиотек для проведения юнит-тестов предоставляют удобные механизмы для запуска...
AVC>(Я уж молчу о той деликатной детали, что многие Си++программисты вообще не хранят тестов. По принципу: протестировал — и забыл. Если не забыл протестировать... )
Я храню — несколько мегобайт юнит-тестов... Доктор я феномен?
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, moudrick, Вы писали:
M>>1. Поддержка максимального количества парадигм программирования (в том числе и структурного)
СГ>1) Как Вам только что показали структурную парадигму не поддерживает.
Сударь! "Программирование без goto" и "структурная парадигма" — это совершенно разные понятия! Это даже сам Дэйкстра признавал — один из со-авторов концепции "программирование без goto", помните его статью, написанную совместо с Хоаром: "Использование оператора goto можно считать вредным" (год не помню). Так вот "программирование без goto" — это концепция (стиль), а не парадигма. Структурная парадигма — это именно парадигма, подход к проектированию и программированию, ориентированный на структуры данных. В рамках СП даётся ответ на вопрос, что представляют из себя данные и как ими можно оперировать. А уж использовать структурную парадигму можно на любом языке (хоть на ассемблере, где без jmp вообще очень трудно) и никакой дополнительной поддержки со стороны языка не требуется. А программирование без goto — это всего лишь стиль оформления, запрещающий использование goto в программах. Да я в курсе, что теорема, доказывающая возможность представления любого алгоритма с goto в виде алгоритма без goto с аналогичными множествами входных значений и результатов, называется теоремой о структурировании Дейкстры... Это только название теоремы и отношение к "структурной парадигме" как таковой оно имеет весьма коссвенное — эта теорема возникла в 50-ых (60-ых) годах (точно не помню), а структурная парадигма программирования окончательно сформировалась только к концу 70-ых, началу 80-ых, как логическое продолжение процедурного подхода. Вобщем как говорил дедушка Фрейд: иногда огурец — это всего лишь огурец.
СГ>2) Модульную парадигму не поддерживает (в языке нет модулей)
если уж на то пошло, то есть: lib, dll...
СГ>3) Компонентно ориентированное программирование не поддерживает (в языке нет модулей и нет сборки мусора)
проехали...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, AVC, Вы писали:
AVC>1. Собственно синтаксис.
AVC>а) Соответствие структурным принципам.
AVC>В отличие от синтаксиса Модулы/Оберона синтаксис Си/Си++ не соответствует принципам структурного программирования.
Кстати... Программирование без goto и структурная парадигма — это разные понятия, хоть и связанные исторически. Эта связь чисто по названию: структурная парадигма (конец 70-ых — начало 80-ых) — глобальная концепция сформировавшаяся из процедурного подхода и теорема о структурировании (60-ые годы) — теорема доказывающая возможность исключения операторов безусловного перехода из алгоритмов. Данная теорема дала импульс к дальнейшим исследования в этой области и привела в конце концов к возникновению методологии структурной парадигмы, которая как ни парадоксально, в свою очередь взяла от этой теоремы только название и не включила сам принцип программирования без goto. Потому что эта парадигма имеет более широкий и общий смысл и не завязывается на таких деталях.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Пацак, Вы писали:
П>Здравствуйте, Сергей Губанов, Вы писали:
П>>>... то я получу syntax error? СГ>>Ну да. Вы получите ошибку времени компиляции. Такая программа не будет скомпилирована. EXIT бывает только внутри LOOP ... END, а внутри WHILE или REPEAT его быть не может.
П>Угу, ясно. Допустим (совершенно условно):
П>
Не корректный вопрос... Сударь не позорьте сообщество программистов на C++, а то нас всех обвинят ещё и в некомпетентности . Если следовать доказательству теоремы о структурировании, то поступить надо так:
Хорошо или плохо — судить не мне, то что алгоритм (точнее реализация) получается сложнее — факт. Оберону эту проблему (усложнения реализации) тоже не решает — там код получится точно такой же. Но это и есть слепое следование принципу программирования без goto, которое, как я уже неоднократно подчёркивал, ни как не связано со структурной парадигмой (точнее структурная парадигма не включает в себя этот принцип).
Это был не наезд — обидеть не хотел . Просто попытка вас поправить (не всем довелось изучать эту чудную теорему ).
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Q>Тогда мы сразу увидим, по строкам оверхед не в пользу Оберона, а совсем наоборот! Не говоря уже о том, что по символам (которые собственно и наколачивает бедный программист) оверхед Оберона составляет 236/175 = 1.35
Это ещё так себе, академические примеры.
Если взять что-нибудь посложнее, с рекурсивными шаблонами, то с увеличением количества функций программа на Обероне и подобных якобы "чистых и правильных" языках будет расти в размерах экспоненциально, тогда как в C++ этот код будет автоматически генерироваться компилятором.
Вчера закончил переписывать часть своей программы с "тупой реализации" на шаблоны с характеристиками и стратегиями, код уменьшился более чем в 2.5 раза. А на Обероне есть возможность только той "тупой" реализации (или использовать generics, проверку типов в рантайме, о чём даже подумать страшно, как медленно это будет). Кстати, новый код заработал сразу, а в старом месяц находились мелкие погрешности, т.к. фактически было дублирование с минимальными изменениями. Специально для Сергея Губанова могу привести задачу, и мы поглядим на её реализацию на Обероне.
В другой ветке уже были примеры с новыми типами, с обощёнными алгоритмами — этого недостаточно?