Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Sinclair, Вы писали:
S>>Ничего подобного. Вполне можно обойтись goto.
СГ>Так убери еще и goto. Что изменилась мощность языка? То-то, а от шаблонов она не меняется.
Объясни — чем ты меряешь мощность языка? Ваттметром?
Имхо, показателем мощности можно считать число затрачиваемых программером физических и умственных усилий для написания кода, остальное — демагогия, не более того.
Здравствуйте, eugals, Вы писали:
E>...Соответственно, никто не мешает мне в какой-то момент изменить, не трогая его внешний интерфейс, внутреннюю организацию модуля A. Именно, взять и назначить класс cA наследником класса cB.
Извините, но раз модуль экспортирует класс, то частью интерфейса модуля является также все предки этого класса. Поэтому, то что Вы описали является изменением и интерфейса модуля тоже. Раз интерфейс модуля изменен, значит он уже не может быть загружен в систему вместо старого модуля. Надо перекомпилировать остальные модули тоже.
Кстати, именно всвязи с этим явлением десять лет назад появилась новая парадигма программирования — КОП (компонентно ориентированная парадигма программирования), основанная Клеменсом Шиперски (сооснователем Oberon Microsystems, а ныне трудящемся в Microsoft). КОП является дальнейшим развитием обычного ООП, но налагает на него некоторые ограничения. Одно из положений КОП заключается в том, что межмодульное наследование — это плохо. КОП приветсвует только межмодульное наследование АБСТРАКТНЫХ классов. В одном модуле определяется Абстрактный класс, а другие модули определяют классы — реализаторы того абстрактного класса-интерфейса. Другими словами межмодульное наследование должно быть двухуровневым интерфейс-реализация.
Собственно, язык Component Pascal и стал первым языком поддерживающим КОП. Потом появились дот.нетовские аналоги (что не удивительно, если принять во внимание уход Шиперского в Микрософт).
Здравствуйте, Курилка, Вы писали:
К>Объясни — чем ты меряешь мощность языка? Ваттметром?
Формального определения не дам. Дам интуитивное. Мощностью ЯВУ я называю количество вариантов разных программ, которые на нем можно написать. Например, интуитивно понятно, что если убрать из ЯВУ указатели, ссылки и оператор NEW, то на таком ЯВУ нельзя будет написать ни одной программы работающей с динамическими структурами данных, то есть размерность пространства всевозможных программ, которые можно написать на таком ЯВУ уменьшиться. Я употребляю слово "мощность", чтобы обозвать, хм, эту штуковину.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Курилка, Вы писали:
К>>Объясни — чем ты меряешь мощность языка? Ваттметром?
СГ>Формального определения не дам. Дам интуитивное. Мощностью ЯВУ я называю количество вариантов разных программ, которые на нем можно написать. Например, интуитивно понятно, что если убрать из ЯВУ указатели, ссылки и оператор NEW, то на таком ЯВУ нельзя будет написать ни одной программы работающей с динамическими структурами данных, то есть размерность пространства всевозможных программ, которые можно написать на таком ЯВУ уменьшиться. Я употребляю слово "мощность", чтобы обозвать, хм, эту штуковину.
И почему же шаблоны не влияют на твою мощность?
Имхо, очень даже влияют, т.к. без них ты не можешь писать статически полиморфичные алгоритмы, что обедняет язык.
Не зря же дженерики и в шарп и в яву добавили, значит нужно оно людям.
Хоть там и реализация несколько иная, чем в плюсах.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, eugals, Вы писали:
СГ>Одно из положений КОП заключается в том, что межмодульное наследование — это плохо. КОП приветсвует только межмодульное наследование АБСТРАКТНЫХ классов. В одном модуле определяется Абстрактный класс, а другие модули определяют классы — реализаторы того абстрактного класса-интерфейса. Другими словами межмодульное наследование должно быть двухуровневым интерфейс-реализация.
Гы. На самом деле межмодульное наследование крайне важная вещь и в то же время действительно есть куча граблей на которые народ постоянно наступает.
Возьмем к примеру оконную библиотеку (отдельный модуль). Естественно пользователи захотят клепать свои виджеты наследуясь от библиотечных. Наследование от интерфейсов здесь не поможет — т.к. не будет красивого решения, нужно именно наследование от классов. Но с другой стороны тут же может возникнуть гемморой связанный с обратной двоичной соместимостью. Т.е. если в библиотечный класс добавить переменную или изменить порядок виртуальных функций то старая прога не будет работать с новыми версиями библиотеки.
Однако эта проблема очень хорошо решается с помошью паттерна P-Impl:
class Base {
void *pImpl_; // закрытая реализация, вставляй добавляй что хочешь.public:
// интерфейсная часть
};
Вернее здесь нужен расширенный паттерн P-Impl с возможностью наследования. Т.е производному классу как-то нужно запихнуть свои данные в указатель *pImpl_ причем он ничего не знает о его типе и устройстве.
Я для этого дела даже написал небольшой фреймворк. Т.е. в базовом классе имеем указатель pImpl на структуру данных, и все дочернии классы могут получить себе в ней секцию для своих данных. Естесвено используется только один блок памяти, нарезанный для всех классов. Т.е. можно обеспечить полный простор в вопросах изменения реализации и при этом сохранить полную обратную двоичную совместимость м-ду модулями.
К примеру реализацию класса размазанного насделованием по Base.dll -> Extended.dll -> App.exe можно менять как угодно добавляя или удаляя данные не ломая совместимости м-ду библиотеками. Т.е. изменение в одно не требует перекомпиляции остальных.
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Извини, в ЯВУ нет push и mov. А мы, вроде как ЯВУ рассматриваем.
Значит, надо было просто не смущать народ некорректными определениями, а сказать просто:
В любом языке есть вещи, от которых можно отказаться. И есть те, от которых отказаться нельзя.
От шаблонов отказаться можно, за счет технологии copy-paste. От ООП как такового тоже, кстати Значит, ООП тоже не добавляет языку "мощности"?
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, prVovik, Вы писали:
V>> ... Если пользоваться вашей логикой ...
СГ>Логика заключалась в том, что мысленно убираются/добавляются конструкции языка высокого уровня и производится анализ того что это дает этому ЯВУ. Об ассемблерах в ЯВУ ничего не известно.
Ну хорошо. Удалим шаблоны из С++ и лишимся обобщенного программирования. Так пойдет?
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Sinclair, Вы писали:
S>>Ничего подобного. Вполне можно обойтись goto.
СГ>Так убери еще и goto. Что изменилась мощность языка? То-то, а от шаблонов она не меняется.
Гы-гы. Ну а зачем тогда в том же паскале столько вариантов циклов: for, repeat, wile. Нафига они вообще нужны, мощность языка от них ведь не меняется?
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Сергей Губанов, Вы писали:
СГ>>Извини, в ЯВУ нет push и mov. А мы, вроде как ЯВУ рассматриваем.
Д>Значит, надо было просто не смущать народ некорректными определениями, а сказать просто: Д>В любом языке есть вещи, от которых можно отказаться. И есть те, от которых отказаться нельзя. Д>От шаблонов отказаться можно, за счет технологии copy-paste. От ООП как такового тоже, кстати Значит, ООП тоже не добавляет языку "мощности"?
А что есть ООП? В узком смысле, ООП-ом можно обозвать процедурные переменные. Процедурные переменные (или в терминологии Си/Си++ — указатели на функцию) добавляют мощности языку (динамический полиморфизм). Кстати в самом первом обероне виртуальных функций не было, полиморфизм достигался благодаря процедурным переменным, тем не менее язык являлся ОО языком. Что касается расширения типов (наследования), наверное, напрямую мощность языка от этого не увеличивается (хотя утверждать этого не буду), но зато это позволяет сохранить в языке строгую статическую типизацию одновременно как бы и нарушая ее в каком-то более высоком смысле...
Здравствуйте, Курилка, Вы писали:
К> не можешь писать статически полиморфичные алгоритмы
Да, не могу. Но, тем не менее, количество разных программ которые я могу написать с шаблонами или без шаблонов (используя copy-paste) одинаково. То есть мощность языка не меняется. Шаблоны — это средство стоящее выше языка (над ним, мета-язык).
Здравствуйте, Sinclair, Вы писали:
S>Ну, на самом деле это не все. Паскаль — неизмеримо круче плюсов потому, что S> S> := гораздо понятнее, чем =
Для сишника это вообще какой-то абзац. Выглядит как автохреномент: x:=y это x=x:y и что это за операция двоеточие? Вспоминается APL. S> ^. гораздо понятнее, чем ->
Ну это фигня, в Си можно записать (*ptr).
Правда, в С++ это не всегда проканает (благодаря перегрузке обоих операторов, * и -> ) S> строковые константы ограничиваются одинарными, а не двойными кавычками (в ДВА раза меньше штрихов!)
Попробуйте вставить туда спецсимволы — тут же нарвётесь на некроссплатформенность, во-первых (а кто сказал, что LF в данной кодировке имеет значение 10?), и на уйму писанины, во-вторых. S> в If можно писать на одну пару скобок меньше
А как же слово then ? +then -() итого два лишних символа, а ещё обязательные пробелы... S>S>Хотя, конечно, главное — все-таки то, что преподавание языка, где присваивание выполняется при помощи "=" означает выставить себя посмешищем.
S>З.Ы. В самом популярном языке программирования для персоналок вообще оператор присваивания не отличается от оператора сравнения на равенство. Что не мешает миллионам людей осваивать его безо всяких Виртов.
Дейкстра уже говорил нащщот самого популярного языка...
Здравствуйте, Сергей Губанов, Вы писали:
СГ>А что есть ООП? В узком смысле, ООП-ом можно обозвать процедурные переменные. Процедурные переменные (или в терминологии Си/Си++ — указатели на функцию) добавляют мощности языку (динамический полиморфизм). Кстати в самом первом обероне виртуальных функций не было, полиморфизм достигался благодаря процедурным переменным, тем не менее язык являлся ОО языком. Что касается расширения типов (наследования), наверное, напрямую мощность языка от этого не увеличивается (хотя утверждать этого не буду), но зато это позволяет сохранить в языке строгую статическую типизацию одновременно как бы и нарушая ее в каком-то более высоком смысле...
Указатели на функции тоже не являются абсолютно необходимыми. Их при желании можно заменить на большой такой switch, который в зависимости от полученного числа будет вызывать разные функции. Значит, они тоже не добавляют языку "мощности"?
То же самое касается и наследования. С помощью copy-paste и такой-то матери без него тоже можно прекрасно обойтись
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Да вы что! Это же замечательная вещь. Можно работать с неименованной переменной без копирования в локальную переменную. Это и быстро (х.з. сможет компилятор ли соптимизировать лишее копирование), и красиво — не загромождаем код лишними переменными.
А вот нефиг копировать. Заводишь именованную ссылку на временный объект и наслаждаешься.
Заметьте, цикл for — с выделенными предикатом проверки и выражением итерирования. А не while, где это итерирование засунуто бог весть куда (что, кстати, не только читаемость ухудшает, но и даёт возможность для ошибок)
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Здравствуйте, Курилка, Вы писали:
К>> не можешь писать статически полиморфичные алгоритмы
СГ>Да, не могу. Но, тем не менее, количество разных программ которые я могу написать с шаблонами или без шаблонов (используя copy-paste) одинаково. То есть мощность языка не меняется. Шаблоны — это средство стоящее выше языка (над ним, мета-язык).
Тебе рядом приводили, что ООП тоже вполне может быть реализовано копипастом, так что количество тоже будет одинаковым?
Вон если взять ассемблер, то на нём тоже можно получить такое же число программ, значит ассемблер такой же мощности, что и твой оберон?
Здравствуйте, Kh_Oleg, Вы писали:
K_O>Я давно не пользовался MathLab, поэтому могу ошибаться, однако, насколько я помню данный продукт является специализированной системой для обработки математических выражений: взятие интегралов в аналитическом виде, решение огромных СЛАУ, решение дифференциальных уравнений больших порядков, вычисление пределов и проч., т.е. то, что математик (физик, химик, ученый или инженер другой специальности) вычислит и сам на бумажке, но у него на это уйдет много времени. Цель данного продукта — сэкономить время на решении трудоемких математических задач. Отсюда — иные средства, иной язык более удобный для математика, нежели для программиста, иные особенности. Математику достаточно знать, что вот это — матрица, с такими-то значениями, и требуемая операция над ней должна быть выполнена за относительно приемлемое время. А для ряда задач время выполнения вообще роли не играет — лишь бы посчиталось.
K_O>Тогда как мне, как программисту важно знать, как эта матрица представлена в памяти, какой тип данный у ее элементов, какими конкретно значениями она проинициализирована (и от этого тоже может зависеть алгоритм вычислений), как быстро над ней будет выполнена требуемая операция, что я смогу изменить, если время вычислений перестанет меня устраивать. Пример, о котором я говорю, большинство требуемой информации от меня скрывает.
K_O>Так что твой пример неудачный, с языками программирования общего назначения имеет мало общего.
Просто ты не лазил в тексты программ на матлабе. Это нормальный скриптовый язык, только встроенные типы у него — скаляры, векторы и матрицы.
Кстати, вся эта муть с огромными СЛАУ, интегрированием и т.п. — написана ручками на матлабовском скрипте. Внутри библиотек — с лёгкостью применяется императивный подход. Что, разумеется, требует от разработчика как математического образования, так и программистского.
Здравствуйте, Кодт, Вы писали:
К>Заметьте, цикл for — с выделенными предикатом проверки и выражением итерирования. А не while, где это итерирование засунуто бог весть куда (что, кстати, не только читаемость ухудшает, но и даёт возможность для ошибок)
Здравствуйте, AVM, Вы писали:
AVM>А на кой тебе надо логировать действия процессора ? AVM>У тебя исходники есть, процессор есть, тебе надо залогировать, только общий ход выполнения программы, AVM>что бы потом при разборе ты мог востроизвести ситуацию на Земле.
Если ошиблись при вводе программы, то исходники не помогут
Здравствуйте, Сергей Губанов, Вы писали:
СГ>Ни что не мешает делать аналогичную оптимизацию для WITH по сравнению с цепочкой dynamic_cast-ов.
Мешает, и ещё как мешает.
Если в спецификации не прописано явно, что with всегда выбирает most derived ветку, то порядок проверок становится существенным.
В этом отличие от case: целочисленная переменная не может быть равна нескольким разным ключевым значениям, а полиморфный объект — может принадлежать разным классам одновременно.
Честно говоря — не вижу вообще никакого смысла в этом споре о какой-то непонятной "мощности". Вполне очевидно, что ни один ЯВУ не может иметь бОльшей мощности, чем Ассемблер — если толковать это понятие так, как это делаешь ты
Поскольку С++ позволяет вставлять в программу фрагменты на ассемблере, а также довольно легко интегрировать их в основную прогу — можно сделать вывод, что он тоже обладает не меньшей мощностью. Если не ошибаюсь, в Обероне такой возможности нет. В таком случае, мощность Оберона должна быть намного меньше, чем у С++ и ассемблера.
Правильно?