[image]

Программная индустрия Америки тупеет...

 
1 2 3 4
+
-
edit
 

Mishka

модератор
★★★


>>В чем состояла "революционность" идею процедуры? В том, что она позволила обособить кусок кода и параметризовать его - хороший абстрактный шаг.


>Это умели уже первые хорошие макроассемблеры


Вопрос не в том, что у тебя есть приятная система ничего не контролирующая, но позволяющая приятно записывать. Процедурные языки ввели средство, которое позволило это делать так, что исчезал класс ошибок. Кстати, проблемы с макросами, которые всегда были, но которые известны благодаря С - использование  i++ в макросе. Поэтому я тут не согласен с тобой - не умели. Слегка поддерживали, но не умели.



>>в) появилась возмозность думать в более крупных концепциях - никто не воспринимает sin(x) иначе как sin - хотя это довольно сложная процедура.


>Есть ли принципиальная разница между, например, call sin x и math.sin(x) Первое - макроассемблер, второе - многие современные ЯВУ, от JavaScript до Python


Нет - но не понял к чему это возвражение. 


>>Оказалось, что у нас есть не просто данный, а набор оперций с ними связанный.


>Опять же, object->show(x,y) или show(object,x,y) или object(show,x,y) - разница невелика с точки зрения написания кода


Велика. Огромна. Например, ситации вызвать show из объекта, у которого нет этого метода в интерфейсе просто невозможно.


>>Своего рассвета он достиг в Алголе 68. Там можно не только перегружать известные, но и создавать новые.


>Как и сейчас, например, в Хаскелле И создавать новые, и приоритеты им назначать, и лево/право приоритентность... Ну и я уже молчу про Форт


Правильно, но это у истории - Алгол 68 появился в 68 - ни Хаскелем, ни Фортом тогда и не пахло.


>>Т.е. появилась возможность создания своеобразных языков приложений.


>Всё равно тут у Форта конкурентов до сих пор нет


Здесь некоторая проблема - отличие процедуры от оператора в синтаксисе - семантически это тот же вызов процедуры. Но синтаксис оказывает влияние на форму записи - отсюда и дополнительные правила про приоритет операции. У Форта, если я правильно помню, все идет к процедурам, даже в синтаксисе (хотя тут, я скорее не прав, чем прав - вообщем спорно - но попробуй определить в Форте операцию ## с приоритетом 6 - чтобы она в выржении типа a+b##c*d выполнялась раньше +, но позже *).


>>А в том, что сделан еще один шаг на пути к дальнейшей абстакции - сейчас, объявляя в программе объект, мы гарантируем, что он будет инициализирован


>Только всё равно этот объект ещё создать нужно. А какая разница, var = new object или var = object(new)?


Не понял про твой пример, но вот что я хотел сказать.


struct s str;


str.a = 1;


str.b = malloc( 20 );


strcpy( str.b, "aa" );


а потом не забыть сказать free( str.b );


или


S str;  и все - конструктор сделал массу за тебя, а d-tor еще и освободит это дело.


>>плюс объект снабжен всем набором методов и аттрибутов, которые определяют его поведение (методы как глаголы, аттрибуты как существительные).


>Только по настоящему это становится полезним лишь в интерпретируемых языках. А при статической компиляции объекты - это лишь чуть более удобный способ записи классических конструкций


Откуда дровишки? Не хотел ли ты часом сказать, что просто интрепретаторы позволяют проинтерпретировать строку, составленную динамически? Если не это, то не вижу разницы. А кроме того, ты упускаешь что-то типа DLL.



>>Итак, что появилось нового, что облегчает жизнь программисту: а) ассоциация методов и данных


>Между прочим, Хаскелл, который позволяет и создавать новые операторы и перегружить имеющиеся, АБСОЛЮТНО необъектный Форт тоже


По моему, ты здесь имеешь ввиду АТД - типы данных и операции ассоциированные с ними. В ООП это немного дальше - не только тип, но и конкретные инстансы связаны с даннымми


>>г) появилась возможность ограничивать людей от лазания грязными ручками внутрь объектов - инкапсуляция.


>Дык, если код в библиотеке, в него и без объектов не залезут, а если в исходниках - грязные ручки с таким же успехом что процедуры, что объекты подправить смогут


От хакеров нет спасения. Вопрос не в том, чтобы закрыться целиком (нельзя убивать, говорит закон - не значит, что физически нельзя - морально и по закону нельзя). Пример файлов, который один из первых ИМХО реальных ООП, в С показвает, что приходиться извращаться на уровне разных headers для ядра и ползователя. А в ООП - закрываешь при помощи private например и люди и знают струтуру, а языком или ООП запрещено лазить.


>>но у нас целый объект, со своими алгоритмами и данными и работать с этим объектом надо только через интерфейс. Любая процедура в библиотеке тоже требует строгого интерфейса


Описание интрефейса есть достижение процедурного программирования. Вот только с данными некоторая проблема. А в ООП можно дать класс с методами по его инстаншиации и работать с объетом как с целым. С этой точки зрения определение интерфейса уже на уровень выше.


>>Но тут решили добавить еще немного для создания удобства программирования - наследование.


>О! Наконец-то В общем, что я хотел сказать, не было, думаю, в области программирования настоящих революций со времён самых первых теоретических ещё концепций.


Я согласен, что это революциями назвать сложно. Если баловался машинами Тьюринга, то увидишь, что и концепций в 50-60 появилось не много.


>Было планомерное и методичное постепенное улучшение концепций, которые, правда, порой выдавались за нечто революционное, но на поверку было либо лишь некоторое обобщение и улучшение имеющегося, либо и вовсе просто подъятие чего-то давно забытого Вот, сейчас пытаются


Я люблю проводить аналогию с математикой. Революцией было обобщение понятие пространства на функции и описание этого пространства с помощью базиса. И Фурье ряды позволили создать для других дисциплин то, что они рассматривают как революцию. С точки зрения математики - это одно из многих. Да спрос был велик, но посмотри сейчас на wavelets - еще одно частно пространство.


>ропихивать концепцию агентного программирования. Дальнейшее развитие объектного.


Ну это не просто как абстракное программирование - описание мира через процедуры или ООП,  а как конкретная технология


>, между прочим, и сегодня у ООП немало противников. Начиная от Фортеров, кончая функциональным программированием. И если первые - своеобразный андеграунд, то тот же Хаскелл - это уже очень серьёзно Хотя, вот, в O'Caml объединили и ФП и ООП


А кто сказал, что ООП панацея? Тот же STL - это АТД чистой воды или как сам Степанов говорит - generic programming - когда у тебя есть настолько общие алгоритмы, что в ООП это не ложиться - скажем для С++ темплэйты были необходимым условием. Поэтому до С++ у Степанова была Ада фавориткой.


 
   
+
-
edit
 

Balancer

администратор
★★★★★
>>Это умели уже первые хорошие макроассемблеры
>Вопрос не в том, что у тебя есть приятная система ничего не контролирующая, но позволяющая приятно записывать.

Ну да... Велик ли уровень контроля в том же C/C++ с возможностью перетипировать типы? Я уже молчу про такую страшную вещь, как Порядок Аргументов в функции :) strcpy(char*,char*) - источник слева или справа? :) Какой уж тут контроль...

Не революция, а лишь ещё одно упрощение.

Вот, в современных языках сплошь и рядом уже даже порядок можно не соблюдать. Я промолчу про параметры XML-тэгов, но, вот, традиционный нынче стиль Perl/PHP/Python/etc в духе strcpy({dest=>s1, src=>s2}) будет работать как и strcpy({src=>s2, desc=>s1})... Порядок уже не важен... Вот только это ещё один шаг назад к макроассемблерам. Всегда можно зевнуть вместо dest написать dst... Контроля нет. Но у кого-то язык повернётся эти языки непроцедурными назвать?? :)


>Слегка поддерживали, но не умели.

Ну, что делать, выходит, в современных языках снова разучились :D Да и не умели толком никогда. См. снова Великую Проблему Порядка Аргументов Функции :)

>>>никто не воспринимает sin(x) иначе как sin - хотя это довольно сложная процедура.
>>Есть ли принципиальная разница между, например, call sin x и math.sin(x)
>Нет - но не понял к чему это возвражение.

К тому, что абстрагирование от внутреннего устройства конкретных подпрограмм вовсю использовалось ещё во времена ассемблера. Так что тут ничего нового тоже нет. А приближение к языку математических нотаций - так большинство ЯВУ очень далеки от этого :) И, вообще, только чисто функциональные языки близки именно математическим формам. У них присваивания нет, этого вечного бича конфликта математиков и программеров :)

>>Опять же, object->show(x,y) или show(object,x,y) или object(show,x,y) - разница невелика с точки зрения написания кода
>Велика. Огромна. Например, ситации вызвать show из объекта, у которого нет этого метода в интерфейсе просто невозможно.

Вот и выходит у тебя тогда, что у нас нет ЯВУ кроме C/C++ с ближайшими родственниками :) Потому что в подавляющем большинстве языков МОЖНО вызвать метод, отсутствующий в объекте. Да, при этом получить иксепшн или вовсе отсутствие диагностики об ошибке, но - можно.

Но свет клином не сошёлся на языках со статическим связыванием. Более того, по-настоящему объектными их трудно назвать :) Достаточно вспомнить не утихающте уже лет 10 и то и все 20 споры на эту тему :)

>Правильно, но это у истории - Алгол 68 появился в 68 - ни Хаскелем, ни Фортом тогда и не пахло.

Ну, ты про расцвет написал, мне почудилось в духе "сейчас так не делают" :)

>Здесь некоторая проблема - отличие процедуры от оператора в синтаксисе - семантически это тот же вызов процедуры. Но синтаксис оказывает влияние на форму записи - отсюда и дополнительные правила про приоритет операции.

Естественно. Кстати, в Хаскелле можно не только операторы вызывать как процедуры, но и процедуры, как операторы :) В духе c = a `mod` b - то же самое, что c=(mod a B)

>У Форта, если я правильно помню, все идет к процедурам, даже в синтаксисе (хотя тут, я скорее не прав, чем прав - вообщем спорно - но попробуй определить в Форте операцию

В Форте есть ТОЛЬКО слова :) Нет деления ни на процедуры, ни на функции, ни на операторы. Даже перменные - это такие же слова. Слова есть непосредственно что-то делающие с данными, есть создающите новые слова, управляющие исполнением программой и т.п.

А использование обратной польской записи избавляет от проблем инфиксности и приоритетов.

2 2 + .
Что 2 (хоть константа, хоть литерал), что +, что точка (вывод на печать) - это всё абсолютно семантически равнозначные конструкции.

Вообще, чрезвычайно изящный язык. Есть более быстрые, есть более удобные, но нет языков с более изящной внутренней структурой :)

>Не понял про твой пример, но вот что я хотел сказать.
[...]
>а потом не забыть сказать free( str.b );

Вот только на том же Форте динамические строки пишутся без всяких объектов, на коленке, за пол-часа. И ничего освобождать не нужно специально вручную, и сборщика мусора никакого нет... Ну а уж когда сборщик мусора появляется, то и вовсе про объекты редко вспоминать приходится. Достаточно сказать, что на C++ я без объектов просто не мог вообще что-то сложнее программки на один экран слепить, а на Perl или PHP у меня сотни килобайт кода за несколько лет и я ещё НИ РАЗУ не воспользовался их объектными моделями :)

А Хаскелл, с его перегружаемыми и создаваемыми опретаторами, невероятно гибкими структурами данных, ленивыми вычислениями и т.п. - вообще не знает ООП :) Оно ему просто не нужно :)

>S str;  и все - конструктор сделал массу за тебя, а d-tor еще и освободит это дело.

Вот и приходим к мысли, что ООП наиболее полезно тогда, когда нет сборки мусора и нет адекватных альтернативных средств, типа типовых стеков на Форте :) (там ты просто не можешь не вызвать деструктор своего типа чтобы удалить ненужное со стека).

>Откуда дровишки? Не хотел ли ты часом сказать, что просто интрепретаторы позволяют проинтерпретировать строку, составленную динамически? Если не это, то не вижу разницы.

При статической компиляции невозможно сделать что-то типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]jScript[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>function</span> show2<span style='color:#808030; '>(</span>x<span style='color:#808030; '>,</span>y<span style='color:#808030; '>,</span>step<span style='color:#808030; '>)</span>
  4. <span style='color:#800080; '>{</span>
  5.     <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>-</span><span style='color:#808030; '>></span>show<span style='color:#808030; '>(</span>x<span style='color:#808030; '>,</span>y<span style='color:#808030; '>)</span>
  6.     <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>-</span><span style='color:#808030; '>></span>show<span style='color:#808030; '>(</span>x<span style='color:#808030; '>+</span>step<span style='color:#808030; '>,</span>y<span style='color:#808030; '>)</span>
  7. <span style='color:#800080; '>}</span>

без привязки к объекту. Т.е. ты должен будешь лепить эти show2(...) для каждого объекта, к которому эта функция нужна. Да, в C++ появились шаблоны, но это, фактически, костыли. При динамической связке интерпретатор может уже при исполнении посмотреть, какие пришли объекты и в зависимости от этого что-то изменить.

Кстати, интерпретация, на самом деле, тут не совсем обязательный фактор, важен именно тип связывания объектов и функций. При статическом - подобное невозможно. И компилятор должен заранее приготовить код на все возможные комбинации. А это возможно только в тривиальных случаях. А динамическая связка возможна и в компиляторах. Скажем, на Форте я такое делал, и не сложно, в своей объектной библиотеке. Впрочем, на сегодня чистых интерпретаторов уже, считай, и не осталось. Разве что .bat в DOS и Shell-скрипты в Unix :) Даже Perl-скрипты и те давно компилируются во внутреннее представление перед выполнением.

> А кроме того, ты упускаешь что-то типа DLL.

А DLL тут совсем ни к селу, ни к городу. Это просто способ линковки библиотек не на этапе сборки программы, а на этапе выполнения. А уже DLL эта может быть любой, в том числе интерпретатором с динамическим связыванием. :)

>По моему, ты здесь имеешь ввиду АТД - типы данных и операции ассоциированные с ними. В ООП это немного дальше - не только тип, но и конкретные инстансы связаны с даннымми

На самом деле я немого лукавлю. Дело в том, что возможности работы с данными у Хаскелла очень хорошо подходят под парадигму ООП. Вот только ООП они это не называют... И даже открещиваются всеми способами, ругая O'Caml, который, к примеру, смешал объектность и функциональность. А всё почему? Ты, вот, только что упоминал i++ в макросах. Объекты ГОРАЗДО опаснее в этом плане :) Засунул ты в объект на C++ static-переменную и готово. Очередной бич высокоуровневых средств - неявные операции... А уж все эти игры с конструкторами/деструкторами... Там столько неявностей наворотить можно!

>А в ООП - закрываешь при помощи private например и люди и знают струтуру, а языком или ООП запрещено лазить.

Вот только и до ООП с этим прекрасно обходились областями видимости, в том числе и на ассемблере. Вынес объект в отдельный модуль (а только так и надо писать!), объявил общедоступные функции EXTRN/PUBLIC, и всё. Интерфейсные функции доступны из других модулей, и все потроха - сокрыты и недоступны. Их просто не видно из других модулей. В чём тут революционность ООП? :)

>Описание интрефейса есть достижение процедурного программирования. Вот только с данными некоторая проблема. А в ООП можно дать класс с методами по его инстаншиации и работать с объетом как с целым. С этой точки зрения определение интерфейса уже на уровень выше.

Хорошо. Но я опять не вижу революционности. От макросов переход к процедурам не революционный. В продвинутей макросы можно даже контроль типов вставить. Структуры (в Си-шном смысле) тоже у нас были изначально. Процедуры в структуры засовывать стали тоже давно, ещё до ООП... Напомню, что в C++ запись вида
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>class</span> xxx
  4. <span style='color:#800080; '>{</span>
  5.     <span style='color:#800000; font-weight:bold; '>int</span> a<span style='color:#800080; '>;</span>
  6.     <span style='color:#800000; font-weight:bold; '>int</span> b<span style='color:#800080; '>;</span>
  7.     <span style='color:#800000; font-weight:bold; '>int</span> func<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>,</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
  8. <span style='color:#800080; '>}</span>

Ничем не отличается от записи типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>struct</span> xxx
  4. <span style='color:#800080; '>{</span>
  5.   <span style='color:#800000; font-weight:bold; '>private</span><span style='color:#808030; '>:</span>
  6.     <span style='color:#800000; font-weight:bold; '>int</span> a<span style='color:#800080; '>;</span>
  7.     <span style='color:#800000; font-weight:bold; '>int</span> b<span style='color:#800080; '>;</span>
  8.     <span style='color:#800000; font-weight:bold; '>int</span> func<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>,</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
  9. <span style='color:#800080; '>}</span>

(мог и ошибок налепить, я уже года четыре серьёзно на C/C++ не программировал)

>скажем для С++ темплэйты были необходимым условием.

Шаблоны С++, как было сказано выше - это костыли, которые хоть как-то позволяют обходить ограничения статической компиляции. Кстати, я не задавался вопросом, как с этим делом на O'Caml. Потому, как его скорость (нередко быстрее C++) говорит скорее о статическом связывании, но при этом язык очень гибкий... Хаскелл же с его чисто динамическим связыванием проигрывает по скорости на порядок.

>Поэтому до С++ у Степанова была Ада фавориткой.

Ада, ИМХО, это вовсе сон разума :) Которые потому так и не прижился всерьёз. Если бы не военные, которые его выбрали, ожидала бы его судьба Модулы, Оберона и т.п. анахронизмов :)
   
+
-
edit
 

Mishka

модератор
★★★



>Ну да... Велик ли уровень контроля в том же C/C++ с возможностью перетипировать типы? Я уже молчу про такую страшную вещь, как Порядок Аргументов в функции :) strcpy(char*,char*) - источник слева или справа? :) Какой уж тут контроль...



Достаточно велик, даже с тем условием, что С это и есть макроассемблер, передать float параметром потребует специальных телодвижений.



>Не революция, а лишь ещё одно упрощение.

>Вот, в современных языках сплошь и рядом уже даже порядок можно не соблюдать. Я промолчу про параметры XML-тэгов, но, вот, традиционный нынче стиль Perl/PHP/Python/etc в духе strcpy({dest=>s1, src=>s2}) будет работать как и strcpy({src=>s2, desc=>s1})... Порядок уже не важен... Вот только это ещё один шаг назад к макроассемблерам. Всегда можно зевнуть вместо dest написать dst... Контроля нет. Но у кого-то язык повернётся эти языки непроцедурными назвать?? :)



Рома, не передергивай - никто не мешает перепутать значения источника и получателя - это ошибка того же уровня как и порядок операндов. Так что и в твоем случае, в твоем понимании контроля нет.


>Ну, что делать, выходит, в современных языках снова разучились :D Да и не умели толком никогда. См. снова Великую Проблему Порядка Аргументов Функции :)


Ага, а так же проблему написания "-" вместо "+", буквы "а" вместо "о".

>>>никто не воспринимает sin(x) иначе как sin - хотя это довольно сложная процедура.
>>Есть ли принципиальная разница между, например, call sin x и math.sin(x)
>Нет - но не понял к чему это возвражение.

>К тому, что абстрагирование от внутреннего устройства конкретных подпрограмм вовсю использовалось ещё во времена ассемблера. Так


Все-таки, ты missed the point полностью - не только важно средство для записи, а поддержка этого.


>что тут ничего нового тоже нет. А приближение к языку математических нотаций - так большинство ЯВУ очень далеки от этого :) И, вообще, только чисто функциональные языки близки именно математическим формам. У них присваивания нет, этого вечного бича конфликта математиков и программеров :)


Вопрос не в математической записи, а в том, что удобнее и что поддерживается языком.


>Вот и выходит у тебя тогда, что у нас нет ЯВУ кроме C/C++ с ближайшими родственниками :) Потому что в подавляющем большинстве языков МОЖНО вызвать метод, отсутствующий в объекте. Да, при этом получить иксепшн или вовсе отсутствие диагностики об ошибке, но - можно.


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

>Но свет клином не сошёлся на языках со статическим связыванием. Более того, по-настоящему объектными их трудно назвать :) Достаточно вспомнить не утихающте уже лет 10 и то и все 20 споры на эту тему :)



А те же виртуальные методы, это далеко не статическое связывание или я чего-то не понял.

>>Правильно, но это у истории - Алгол 68 появился в 68 - ни Хаскелем, ни Фортом тогда и не пахло.

>Ну, ты про расцвет написал, мне почудилось в духе "сейчас так не делают" :)


Я говорил в историческом аспекте, но ты покажи мне как Хаскел превосходит те возможности в Алголе 68. Если уровень не превосходит, то моя фраза верна и сейчас - уровень был достигнут.

>Естественно. Кстати, в Хаскелле можно не только операторы вызывать как процедуры, но и процедуры, как операторы :) В духе c = a `mod` b - то же самое, что c=(mod a B)


Не велика заслуга. В С++ тоже можно. Но операции были придуманы потому, что для человека в ряде областей это естесственнее.


>В Форте есть ТОЛЬКО слова :) Нет деления ни на процедуры, ни на функции, ни на операторы. Даже перменные - это такие же слова. Слова есть непосредственно что-то делающие с данными, есть создающите новые слова, управляющие исполнением программой и т.п.



Правильно, т.е. удобства записи 0. Пойми, я люблю Форт, но критики с этой стороны он не выдерживает. Недаром Дийкстра его назвал языком будущего для программистов прошлого.



>А использование обратной польской записи избавляет от проблем инфиксности и приоритетов.
Правильно, на ассемблере все возможно и избавляет от проблем синтаксиса даже Форта :D



>2 2 + .
Что 2 (хоть константа, хоть литерал), что +, что точка (вывод на печать) - это всё абсолютно семантически равнозначные конструкции.

>Вообще, чрезвычайно изящный язык. Есть более быстрые, есть более удобные, но нет языков с более изящной внутренней структурой :)


Что ты подразумеваешь под внутренней структурой? Определение языка, его имплементацию?


>Вот только на том же Форте динамические строки пишутся без всяких объектов, на коленке, за пол-часа.


На С++ - если без методов - 2 минуты.


>И ничего освобождать не нужно специально вручную, и сборщика мусора никакого нет...


И глобальные объекты не возникают, а, если и возникают, то освобождать их не надо - Ром, мемори лик на Форте элементарен.


>Ну а уж когда сборщик мусора появляется, то и вовсе про объекты редко вспоминать приходится. Достаточно сказать, что на C++ я без объектов просто не мог вообще что-то сложнее программки на один экран слепить, а на Perl или PHP у меня сотни килобайт кода за несколько лет и я ещё НИ РАЗУ не воспользовался их объектными моделями :)



??? это к чему ??? Отключи пакеты все в Перле - много ты напрограммируешь? Не надо говорить, что это составная часть. Посмотри вон на Ace - там масса всего есть того, чего Перлу и не снилось.



>А Хаскелл, с его перегружаемыми и создаваемыми опретаторами, невероятно гибкими структурами данных, ленивыми вычислениями и т.п. - вообще не знает ООП :) Оно ему просто не нужно :)



Ленивые вычисления, говоря твоим языком, это к APL - ничего нового. А что такого в гибкости структур данных в Хаскеле? А ООП  не должен быть затычкой во все дырки. И вообще, я как то не понял этого аргумента - оно ему просто не нужно - ассемблеру просто не нужно то, что есть в Хаскеле - правильно?



>S str;  и все - конструктор сделал массу за тебя, а d-tor еще и освободит это дело.

>Вот и приходим к мысли, что ООП наиболее полезно тогда, когда нет сборки мусора и нет адекватных альтернативных средств, типа типовых стеков на Форте :) (там ты просто не можешь не вызвать деструктор своего типа чтобы удалить ненужное со стека).


А с глобальными данными как? Или ты пишешь так, что их у тебя нет?

>>Откуда дровишки? Не хотел ли ты часом сказать, что просто интрепретаторы позволяют проинтерпретировать строку, составленную динамически? Если не это, то не вижу разницы.

>При статической компиляции невозможно сделать что-то типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]jScript[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>function</span> show2<span style='color:#808030; '>(</span>x<span style='color:#808030; '>,</span>y<span style='color:#808030; '>,</span>step<span style='color:#808030; '>)</span>
  4. <span style='color:#800080; '>{</span>
  5. <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>-</span><span style='color:#808030; '>></span>show<span style='color:#808030; '>(</span>x<span style='color:#808030; '>,</span>y<span style='color:#808030; '>)</span>
  6. <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>-</span><span style='color:#808030; '>></span>show<span style='color:#808030; '>(</span>x<span style='color:#808030; '>+</span>step<span style='color:#808030; '>,</span>y<span style='color:#808030; '>)</span>
  7. <span style='color:#800080; '>}</span>

без привязки к объекту. Т.е. ты должен будешь лепить эти show2(...) для каждого объекта, к которому эта функция нужна. Да, в C++ появились шаблоны, но это, фактически, костыли. При динамической связке интерпретатор может уже при исполнении посмотреть, какие пришли объекты и в зависимости от этого что-то изменить.



А наследование?


А тебе в новых объектах ничего писать не надо и у тебя код магически сам появляется из ниоткуда?



А в Jave например, можно вообще левый код загрузить.



>Кстати, интерпретация, на самом деле, тут не совсем обязательный фактор, важен именно тип связывания объектов и функций. При статическом - подобное невозможно. И компилятор должен заранее приготовить код на все возможные комбинации. А это возможно только в тривиальных случаях. А динамическая связка возможна и в компиляторах. Скажем, на Форте я такое делал, и не сложно, в своей объектной библиотеке. Впрочем, на сегодня чистых интерпретаторов уже, считай, и не осталось. Разве что .bat в DOS и Shell-скрипты в Unix :) Даже Perl-скрипты и те давно компилируются во внутреннее представление перед выполнением.



Ром, позднее связывание всегда было частью ООП.



>> А кроме того, ты упускаешь что-то типа DLL.

>А DLL тут совсем ни к селу, ни к городу. Это просто способ линковки библиотек не на этапе сборки программы, а на этапе выполнения. А уже DLL эта может быть любой, в том числе интерпретатором с динамическим связыванием. :)



А DLL показывают, что позднее связывание в ООП работает и что ты, мягко говоря, не совсем прав.




>На самом деле я немого лукавлю. Дело в том, что возможности работы с данными у Хаскелла очень хорошо подходят под парадигму ООП. Вот только ООП они это не называют... И даже открещиваются всеми способами, ругая O'Caml, который, к примеру, смешал


Да слон я, СЛОН, только по печени не бейте! :D


>объектность и функциональность. А всё почему? Ты, вот, только что упоминал i++ в макросах. Объекты ГОРАЗДО опаснее в этом плане :)


Поясни в чем?


>Засунул ты в объект на C++ static-переменную и готово. Очередной бич высокоуровневых средств - неявные операции... А уж все эти игры с конструкторами/деструкторами... Там столько неявностей наворотить можно!



А c-tor, d-tor  - пишешь в одном месте, а используются везде. В то время как в других языках - объявил, а потом будь добр не забудь сделать то, что положено.


Кто-то тут говорил, что на С не мог страницу кода написать, а на Перле - сотни тысяч. И ты говоришь, после этого, что в Перле нет не явных преобразований? Хе-хе



>А в ООП - закрываешь при помощи private например и люди и знают струтуру, а языком или ООП запрещено лазить.

>Вот только и до ООП с этим прекрасно обходились областями видимости, в том числе и на ассемблере. Вынес объект в отдельный модуль (а только так и надо писать!), объявил общедоступные функции EXTRN/PUBLIC, и всё. Интерфейсные функции доступны из других модулей, и все потроха - сокрыты и недоступны. Их просто не видно из других модулей. В чём тут революционность ООП? :)


Вот только внутри модуля все всем доступно. Можно конечно для каждого маленького кирпичика свой модуль объвлять, но боюсь ты будешь первым, кто начнет жаловаться на факт, что надо сначала импортировать 3194 модуля до того как ты сможешь написать программку типа Hello, Worв!





>Хорошо. Но я опять не вижу революционности. От макросов переход к процедурам не революционный. В продвинутей макросы можно даже контроль типов вставить. Структуры (в Си-шном смысле) тоже у нас были изначально. Процедуры в структуры засовывать стали тоже давно, ещё до ООП... Напомню, что в C++ запись вида
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>class</span> xxx
  4. <span style='color:#800080; '>{</span>
  5. <span style='color:#800000; font-weight:bold; '>int</span> a<span style='color:#800080; '>;</span>
  6. <span style='color:#800000; font-weight:bold; '>int</span> b<span style='color:#800080; '>;</span>
  7. <span style='color:#800000; font-weight:bold; '>int</span> func<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>,</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
  8. <span style='color:#800080; '>}</span>

Ничем не отличается от записи типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>struct</span> xxx
  4. <span style='color:#800080; '>{</span>
  5. <span style='color:#800000; font-weight:bold; '>private</span><span style='color:#808030; '>:</span>
  6. <span style='color:#800000; font-weight:bold; '>int</span> a<span style='color:#800080; '>;</span>
  7. <span style='color:#800000; font-weight:bold; '>int</span> b<span style='color:#800080; '>;</span>
  8. <span style='color:#800000; font-weight:bold; '>int</span> func<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>,</span><span style='color:#800000; font-weight:bold; '>int</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
  9. <span style='color:#800080; '>}</span>

(мог и ошибок налепить, я уже года четыре серьёзно на C/C++ не программировал)



А нет отличия - по умолчанию private стоит. :) А более серъезно, допустим, я хочу проконтролировать, что значения аттрибутов удовлетворяют соотношению, то я переношу их в private, объявляю методы доступа к ним, в которых и осуществляю контроль. В структуре это не возможно enforce - так любой может и просто присвоить. И только следованию стилю может помочь.




>Шаблоны С++, как было сказано выше - это костыли, которые хоть как-то позволяют обходить ограничения статической компиляции.


Ром, не прав ты - виртуальные методы - это есть позднее связывание. А темплейты - это веяние generic programming.


>Кстати, я не задавался вопросом, как с этим делом на O'Caml. Потому, как его скорость (нередко быстрее C++) говорит скорее о статическом связывании, но при этом язык очень гибкий... Хаскелл же с его чисто динамическим связыванием проигрывает по скорости на порядок.

>>Поэтому до С++ у Степанова была Ада фавориткой.

>Ада, ИМХО, это вовсе сон разума :) Которые потому так и не прижился всерьёз. Если бы не военные, которые его выбрали, ожидала бы его судьба Модулы, Оберона и т.п. анахронизмов :)

Рома, если следить по популярности, то Бейсик лучший язык. Форт, кстати, примерно там же, где и Ада, Оберон (компилятор с которого я писал вместе с другими в качестве развлекухи). Про Хаскел, Объектного Верблюда - вообще молчу. Где его используют?

   

ED

старожил
★★★☆


Господа airbase.ru/forums/index.php?s=&act=Profile&CODE=03&MID=1Balancer[/URL][/span]иairbase.ru/forums/index.php?s=&act=Profile&CODE=03&MID=206Mishka[/URL],[/span] мы все и так уже видим, что вы страшно умные. Возможно даже, что умнее нас. Но давайте вернёмся к обсуждению статьи.




Ничего нового в ней нет. Тенденция к специализации, упрощению и унификации работы специалистов наблюдается во всех сферах человеческой деятельности. Когда-то мост рассчитывал один инженер, он же и руководил его строительством. Мосты получались уникальные, идеально приспособленные к конкретному месту и носили имя автора. Теперь проектные организации штампуют типовые проекты мостов по отработанным методикам. Мосты получаются безликие, но так дешевле, быстрее и надёжнее. Бизнесу ничего другого и не надо. По второй своей специальности я радиоконструктор. Наблюдаю ту же тенденцию. Радиоаппаратура становится всё более стандартной и безликой. Работа конструктора сползает к комбинированию кем-то давно разработанных блоков и узлов. Если и приходится разрабатывать своё, то требуют использовать только стандартные методики и материалы. ИМХО уровень конструкторов падает. Но результат получается быстрее, предсказуемее и дешевле. Это решает всё. Моя первая специальность – военный лётчик. Вот уж где чистая романтика и простор для простор для импровизации? Ничего подобного. Современный военный лётчик – часть системы вооружения и его работа сводится к чёткому выполнению команд оператора и созданию жёстких условий для применения оружия. Утрирую, конечно, но Покрышкину и Кожедубу было веселее. В гражданской авиации ещё круче. Лётчик летает строго по утверждённым трассам, строго подчиняясь командам диспетчеров, общаясь с ними строго регламентированными фразами, каждое действие обязано соответствовать РЛЭ самолёта и т.п., возможность пилота влиять на события постоянно уменьшается. Сегодня даже взлёт и посадка автоматизированы. Требования к подбору пилотов постоянно снижаются - в США, например, достаточно получить лицензию на легкомоторный самолёт, сдать тесты на знание правил проведения полётов и всё. Набирай часы и летай хоть на В-747. Аэродинамику, навигацию, устройство систем и т.д. знать не надо. Зачем? Недавно на avia.ru обсуждали, какая профессия наиболее важна для авиакомпании. Больше всего высказались за менеджеров и экономистов. Про лётчиков почти не вспоминали. Чего про извозчиков вспоминать. 




К чему это я? Затронутая проблема далеко не нова. И причина этой проблемы найдена давно. Таковы требования современной экономики. Эффективность важнее всего. Просто «превращение» рядового программиста из полубога в типичного клерка произошло очень быстро, буквально на наших глазах. Потому и кажется ярче.  


   
+
-
edit
 

Mishka

модератор
★★★


>Господа airbase.ru/forums/index.php?s=&act=Profile&CODE=03&MID=1Balancer[/URL][/span]иairbase.ru/forums/index.php?s=&act=Profile&CODE=03&MID=206Mishka[/URL],[/span] мы все и так уже видим, что вы страшно умные. Возможно даже, что умнее нас. Но давайте вернёмся к обсуждению статьи.


Это мы точим копья религиозной войны. "Регилиозные секстанты" мы (согласно моему другу, который упобтреблял это выражение на ссылку одного двоечника однокурсника). :D



>Ничего нового в ней нет. Тенденция к специализации, упрощению и унификации работы специалистов наблюдается во всех сферах человеческой деятельности. Когда-то мост рассчитывал один инженер, он же и руководил его строительством.


Да мы понимаем, только пытаемся иногда проследить, а как интсрументы и технология помогают тем, у кого уровень хороший, а так же способстуют понижению уровня в профессии. На мой взгляд, всегда превращение из большого исскуства в инженерную профессию сопровождается такими событиями.


>Про лётчиков почти не вспоминали. Чего про извозчиков вспоминать. 


А тут даже в CMU появилась профессия - руководитель IT - немного разбираться в IT, но главное ими руководить.



>К чему это я? Затронутая проблема далеко не нова. И причина этой проблемы найдена давно. Таковы требования современной экономики. Эффективность важнее всего. Просто «превращение» рядового программиста из полубога в типичного клерка произошло очень быстро, буквально на наших глазах. Потому и кажется ярче.  


Да боюсь не современной экономики, а экономики в большом смысле - если обществу выгодна деятельность, то происходит ее стандартизация и унификация - по-возможности. Это все преследует одну цель - большое количество членов этого общества должны быть способны выполнять их. Поскольку, по определению, при расширении базы деятельности общий уровень падает, то мы и наблюдаем то, что Вы (а можно на ты?) описали.

   

ED

старожил
★★★☆

airbase.ru/forums/index.php?s=&act=Profile&CODE=03&MID=206Mishka[/URL]: [/span]«Это все преследует одну цель - большое количество членов этого общества должны быть способны выполнять их. Поскольку, по определению, при расширении базы деятельности общий уровень падает, то мы и наблюдаем то, что Вы (а можно на ты?) описали».


На ты запросто!


Мне кажется, что дело не совсем в увеличении количества. Тех же пилотов сильно больше не стало. Я писал: «Эффективность важнее всего». Хотел бы уточнить: «Гарантированная эффективность важнее всего». Современная экономика страшно боится рисков. Конечно, хорошо получить отличный продукт, но лучше получить продукт просто работоспособный, но в строго запланированные сроки и с запланированными параметрами. Много на этом не заработаешь, но за срыв договора огребёшь по полной программе, и очень повезёт, если сможешь потом отмыться. Поэтому ценятся серые, но надёжные исполнители. Правда и продукт получается надёжный, но серый. Появляется проблема его продать. Вот тут и становятся необходимыми менеджеры. Потому и считают они себя незаменимыми. Обиднее всего, что у них есть на то основания.


   
+
-
edit
 

Balancer

администратор
★★★★★
Нафиг лётчиков, дайте за святое зубами поклацать! :D

>Рома, не передергивай - никто не мешает перепутать значения источника и получателя - это ошибка того же уровня как и порядок операндов.

Э, нет! Источник с приёмником можно перепутать только с бодуна или по иной причине того же рода, а вот порядок операндов - это совсем другое... Хотя бы из-за того, что никакого стандарта нет, и то источник слева, а приёмник справа, то наоборот :)

>Ага, а так же проблему написания "-" вместо "+", буквы "а" вместо "о".

Это, всё же, СОВСЕМ другое :) Кмк минимум, если ты вместо 'a' напишешь 'o' - это компилятор даже отловить сможет. А минус с плюсом... Ну, да, в высшей математике в преобразованиях с этим вечная проблема... Но, согласись, что в операции перепутать операнды куда сложнее, чем порядок аргументов, особенно при отсутствии стандарта :)

>Примеры подавляющего большинства, пожалуйста.

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

>А те же виртуальные методы, это далеко не статическое связывание или я чего-то не понял.

Нет, виртуальные методы в C++ - это всё равно статическое связывание. Компилятор ещё на этапе компиляции разбирается, что к чему. Соотвтественно, всё и предопределено должно быть. Ну нет такого типа в C++, как "любой объект" :) Только в шаблонах до какой-то степени. Но это - просто упрощённый механизм размножения кода :) Опять же, статически компилируемого.

>но ты покажи мне как Хаскел превосходит те возможности в Алголе 68.

Я Alogol 68 совсем не знаю, а Хаскелл - очень плохо :D Но я сомневаюсь, что в Алголе была хотя бы элементарная сборка мусора, я молчу про ленивые вычисления, шаблонные функции и т.п. Можно ли было в Алголе так записать трёхпараметрическую функцию Аккермана?
code text
  1. a 0 x y = x+1
  2. a 1 x 0 = x
  3. a 2 x 0 = 0
  4. a 3 x 0 = 1
  5. a n x 0 = 2
  6. a n x y = (a (n-1) (a n x (y-1)) x)


Это прямой аналог вот такого C++ кода:
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3.  
  4. <span style='color:#800000; font-weight:bold; '>int</span> ackr<span style='color:#808030; '>(</span><span style='color:#800000; font-weight:bold; '>int</span> n<span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>int</span> x<span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>int</span> y<span style='color:#808030; '>)</span>
  5. <span style='color:#800080; '>{</span>  
  6.     <span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span><span style='color:#808030; '>!</span>n<span style='color:#808030; '>)</span>
  7.         <span style='color:#800000; font-weight:bold; '>return</span> x<span style='color:#808030; '>+</span><span style='color:#008c00; '>1</span><span style='color:#800080; '>;</span>
  8.  
  9.     <span style='color:#800000; font-weight:bold; '>if</span><span style='color:#808030; '>(</span>y<span style='color:#808030; '>)</span>
  10.         <span style='color:#800000; font-weight:bold; '>return</span> ackr<span style='color:#808030; '>(</span>n<span style='color:#808030; '>-</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>,</span>ackr<span style='color:#808030; '>(</span>n<span style='color:#808030; '>,</span>x<span style='color:#808030; '>,</span>y<span style='color:#808030; '>-</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>)</span><span style='color:#808030; '>,</span>x<span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
  11.     
  12.     <span style='color:#800000; font-weight:bold; '>switch</span><span style='color:#808030; '>(</span>n<span style='color:#808030; '>)</span>
  13.     <span style='color:#800080; '>{</span>  
  14.         <span style='color:#800000; font-weight:bold; '>case</span> <span style='color:#008c00; '>1</span><span style='color:#808030; '>:</span> <span style='color:#800000; font-weight:bold; '>return</span> x<span style='color:#800080; '>;</span>
  15.         <span style='color:#800000; font-weight:bold; '>case</span> <span style='color:#008c00; '>2</span><span style='color:#808030; '>:</span> <span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#008c00; '>0</span><span style='color:#800080; '>;</span>
  16.         <span style='color:#800000; font-weight:bold; '>case</span> <span style='color:#008c00; '>3</span><span style='color:#808030; '>:</span> <span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#008c00; '>1</span><span style='color:#800080; '>;</span>
  17.     <span style='color:#800080; '>}</span>
  18.     <span style='color:#800000; font-weight:bold; '>return</span> <span style='color:#008c00; '>2</span><span style='color:#800080; '>;</span>
  19. <span style='color:#800080; '>}</span>


Кстати, если код на Хаскелле почти на порядок проигрывает MSVC++7, то вот такой код на O'Caml
code text
  1. let rec a n x y =
  2.     match (n, y) with
  3.         (0, y) -> x+1
  4.       | (1, 0) -> x
  5.       | (2, 0) -> 0
  6.       | (3, 0) -> 1
  7.       | (n, 0) -> 2
  8.       | (n, y) -> (a (n-1) (a n x (y-1)) x)
  9.    ;;

оказывается просто быстрее сишного :)

Впрочем, это уже обсуждалось в форуме Форт и т.п. :)

>Если уровень не превосходит, то моя фраза верна и сейчас - уровень был достигнут.

Да превосходит, не сомневаюсь. Прогресс на месте не стоит :D

>>В духе c = a `mod` b - то же самое, что c=(mod a B)
>Не велика заслуга. В С++ тоже можно.

Э... Т.е. myabs(a,B) можно в инфиксной форме записать?? Я что-то упустил?? :D

>Правильно, т.е. удобства записи 0.

Э, нет! Форт имеет МОРЕ недостатков, но вот по удобству записи он как раз один из первых :D Хотя... Мда, смотря что под этим понимать :)

>Недаром Дийкстра его назвал языком будущего для программистов прошлого.

А мы все давно "программисты прошлого". Неужели непонятно? :)

>Правильно, на ассемблере все возможно и избавляет от проблем синтаксиса даже Форта :D

На ассемблере плотность информации на единицу кода намного ниже :)

>Что ты подразумеваешь под внутренней структурой? Определение языка, его имплементацию?

Я понимаю процесс компиляции и интепретации :D В каком ещё языке практически весь процесс создания/исполнения программы записывается в десяток строк элементарных операций того же языка? :)

>На С++ - если без методов - 2 минуты.

Без объектов? :) Пример!

>Ром, мемори лик на Форте элементарен.

Естественно. Есть дурная практика совать новые типы данных на классический стек данных. Откуда их по DROP и т.п. сбросить можно. Но хороший стиль - это свой стек под каждый тип данных. И если у меня $DROP будет освобождать память строки - откуда возьмутся утечки памяти? :)

А вот другого рекордсмена по утечкам, кроме C/C++ ещё поискать нужно :D

>??? это к чему ??? Отключи пакеты все в Перле - много ты напрограммируешь?

А при чём тут это? Большинство моих пакетов, с которыми я работаю - не объектные :)

>Посмотри вон на Ace - там масса всего есть того, чего Перлу и не снилось.

Это ты про новое изобретение Sun на базе Java с графическим программированием взаимодействия блоков? Я его ещё в глаза не видел. Но идеология не кажется мне верной :)

>Ленивые вычисления, говоря твоим языком, это к APL - ничего нового.

А я и не говорил, что новое. Я, собственное, весь спор веду только на тему того, что НИЧЕГО революционно нового нигде нет :)

>А с глобальными данными как? Или ты пишешь так, что их у тебя нет?

Да, стараюсь писать так. Глобальные переменные - это вред несравнимо больший, чем GOTO :) Наряду со статическими переменными, кстати. Нет, у меня ещё даже в коде всего двухлетней давности ещё полно глобальных переменных, но это - мой порок :) От которого я освобождаюсь. И, при всей нелюбви к Java не могу не признать большого шага вперёд в её полном освобождении от этой заразы :) И именно исключительно глобальные переменные Форта больше всего меня от него отталкивают. Ну, да, локальные можно и на коленке, опять же, за пол-часа слепить... Но это не то...

В общем, без глобальных переменных писать можно и нужно :)

>Откуда дровишки? Не хотел ли ты часом сказать, что просто интрепретаторы позволяют проинтерпретировать строку, составленную динамически? Если не это, то не вижу разницы.

Разница только в том, что "чистый" интепретатор жрёт оператор за оператором, строку за строкой и можно управлять его работой модифицируя исходник прямо на лету. Если до такого извращения не опускаться, то разницы почти и нет.

>А наследование?
>А тебе в новых объектах ничего писать не надо и у тебя код магически сам появляется из ниоткуда?

Уф. Наследование тут при чём? Функция show2() в том примере работает с любым объектом, имеющим метод show(). Соотсветственно, и с любым объектом, наследником данного, унаследовавшим функцию show(). Да, код для show() придётся писать, возможно, заново, но вот show2() так и будет работать с любым объектом, в котором есть show().

При статическом связывании такое невозможно. Ты должен написать код функции show2() для ВСЕ возможных объектов, к которым она может примениться. Пусть это даже и будет упрощено шаблонами.

>А в Jave например, можно вообще левый код загрузить.

Возможно. Я её совсем забыл. Более пяти лет с ней не возился.

>Ром, позднее связывание всегда было частью ООП.

??
На классическом С++ после компиляции у тебя есть только жёсткий немодифицирующийся код. См выше пример с show2(...). Такое в C++ принципиально невозможно.

>А DLL показывают, что позднее связывание в ООП работает и что ты, мягко говоря, не совсем прав.

Брррррр... DLL - это только метод линковки, отложенный от этапа компиляции до этапа исполнения. При чём тут связывание??

Название DLL расшифруй, а? :)

>>Объекты ГОРАЗДО опаснее в этом плане :)
>Поясни в чем?

Засунул статические данные внутрь объекта, модифицируешь их как бог на душу положит, да ещё в private где-то... Что может быть неявнее? :) Чем тот же i++ в макросе хуже статического i++ в объекте? :)

>Кто-то тут говорил, что на С не мог страницу кода написать, а на Перле - сотни тысяч.

Гмгмгм... Я на С/С++ тоже, пожалуй, сотни килобайт кода настрочил. Я говорил о том, что на С++ без объектов я не мог, а на Perl - они ни разу не понадобились. Это совсем иное :)

>И ты говоришь, после этого, что в Перле нет не явных преобразований?

Да полно их там! :D Я говорю, что объекты - ничего не предоставляют в плане защиты от неявных преобразований :) Более того, они запросто инкапсулируют эти неявные преобразования, чем становятся ещё более опасны :)

Единственный известный мне язык без известных мне неявных преобразований - Хаскелл :)

>Вот только внутри модуля все всем доступно. Можно конечно для каждого маленького кирпичика свой модуль объвлять, но боюсь ты будешь первым, кто начнет жаловаться на факт, что надо сначала импортировать 3194 модуля до того как ты сможешь написать программку типа Hello, Worв!

Гмгмгм... На Java, вот, каждый класс - отдельный модуль. И никто, вроде, не плачется. Но внутри класса - итак всё доступно. Так чем это хуже, чем у меня то же самое на ассемблере без объектов всяких будет? :) Так же, каждый логический объект - отдельный модуль со своей областью видимости и т.п. Ну да, на подгрузку нужных субмодулей в Java понадобится одна строка, а на ассемблере - две (ещё плюс проверка на загруженность, чтобы дважды одно не грузить). И это - революционность? :)

>А более серъезно, допустим, я хочу проконтролировать, что значения аттрибутов удовлетворяют соотношению, то я переношу их в private, объявляю методы доступа к ним, в которых и осуществляю контроль. В структуре это не возможно enforce - так любой может и просто присвоить.

Стоп-стоп. private: в структуре тоже не даст никому "снаружи" добраться до этих элементов!

>Ром, не прав ты - виртуальные методы - это есть позднее связывание.

Мне лениво сейчас писать тесты на C++, но на 99.99% уверен, что виртуальные методы в C++ - статическое связывание на этапе компиляции :)

На C++ принципиально невозможен тип "любой объект" :)

>Рома, если следить по популярности, то Бейсик лучший язык.

Если хорошенько репу почесать, то, возможно, так оно и есть, как бы нам не нехотелось этого признавать :D И дело тут вовсе не в политике Microsoft :) Этот язык был популярен почти с самого создания :)

>Форт, кстати, примерно там же, где и Ада

А я и не спорю :)

>Про Хаскел, Объектного Верблюда - вообще молчу. Где его используют?

Ну, Хаскелл сейчас используется, как минимум, не меньше, чем Форт :) Например, пару раз натыкался на веб-сервера на нём :) В смысле откликов сервера в логах. К сожалению, не смог сейчас найти их. А первое, что в голову пришло, Haskell.org - работает на банальном Апаче :D

Уф, ладно, пойду спать, что ли... А то сегодня 30-летие товарища справляли, так совсем уже плохо что-то мне... :)
   
+
-
edit
 

Balancer

администратор
★★★★★
>Правда и продукт получается надёжный, но серый. Появляется проблема его продать. Вот тут и становятся необходимыми менеджеры. Потому и считают они себя незаменимыми. Обиднее всего, что у них есть на то основания.

Кстати, и ненадёжный всё равно :) Но серый - это да. Всякое развитие любой цивилизации обычно только и делает, что поощряет серость... Но поскольку мны всё-таки из пещер выбрались и туда до сих пор не вернулись, то что-то есть такое в Человечестве, с чем никакое стимулирование серости не справляется :)
   

TEvg

аксакал

админ. бан
>Если хорошенько репу почесать, то, возможно, так оно и есть, как бы нам не нехотелось этого признавать :D И дело тут вовсе не в политике Microsoft :) Этот язык был популярен почти с самого создания :)

Басик - это отражение нашего серого мира. Серый язык - как раз то что требуется для бузинеса.

Вообще меня очень разочаровывает наша цивилизация. Социализм погорел на управлении. А капитализм? Те же яйца, вид сбоку - не нужны ему ни летчики, ни инженеры, ни программисты, ни рабочие. А нужны только манагеры, бесконечные манагеры, кои по своей сущности являются паразитами. Не понимаю как экономика может быть эффективной если количество пиявок в ней намного превосходит количество трудящихся. Конечно иногда и пиявка полезна, но все должно быть в меру. Этого нет.
Откуда например в США может быть эффективная экономика если там на 1 работающего приходится
0.3 лоера
0.3 банкира
0.2 госслужащего
1.5 сервисмена
5 безработных или нетрудоспособных

???
   
+
-
edit
 

timochka

опытный

>>>А те же виртуальные методы, это далеко не статическое связывание или я чего-то не понял
>>Нет, виртуальные методы в C++ - это всё равно статическое связывание. Компилятор ещё на этапе компиляции разбирается, что к чему. Соотвтественно, всё и предопределено должно быть. Ну нет такого типа в C++, как "любой объект" :) Только в шаблонах до какой-то степени. Но это - просто упрощённый механизм размножения кода :) Опять же, статически компилируемого
>>>Ром, позднее связывание всегда было частью ООП.
>>На классическом С++ после компиляции у тебя есть только жёсткий немодифицирующийся код. См выше пример с show2(...). Такое в C++ принципиально невозможно.
>А DLL показывают, что позднее связывание в ООП работает и что ты, мягко говоря, не совсем прав.
>Брррррр... DLL - это только метод линковки, отложенный от этапа компиляции до этапа исполнения. При чём тут связывание??

Рома, ты всеж-таке не прав. В С++ есть классическое динамическое связывание.

Приведу пример:
Объявление интерфейса (доступно в виде хедер файла для всех):
class IMyInterface
{
public:
virtual void Draw(void) = 0; // Draw some shit.
};

Реализация объектов (складывается в длл).

Библиотека Mylib1.dll --------
IMyInterface CreateInstance(void)
{
return new MyClass1();
}

class MyClass1 : public IMyInterface
{
public:
virtual void Draw(void)
{ MessageBox(0l, "Я класс MyClass1.", "Info", MB_OK); }
}


Библиотека Mylib2.dll --------
IMyInterface CreateInstance(void)
{
return new MyClass2();
}

class MyClass2 : public IMyInterface
{
public:
virtual void Draw(void)
{ MessageBox(0l, "Я класс MyClass2.", "Info", MB_OK); }
}


Основная программа -------
// грузим библиотеку Mylib1.dll
.......
// вызываем ее

IMyInterface obj = CreateInstance();
obj.Draw();

// и завершаем программу

Компилим, линкуем, запускаем.
Видим следущее "Я класс MyClass1." - что и ожидалось.

Теперь переименовываем файл Mylib2.dll в Mylib1.dll и снова запускаем.
Видим "Я класс MyClass2." - Но ведь мы ничего не пересобирали! Значит на лицо динамическое связывание.
   

ED

старожил
★★★☆
Balancer: «Нафиг лётчиков».
И такое говорится на АВИАБАЗЕ? Куда смотрит администрация? Ах, да….
Говорил я, что лётчики перестали котироваться, но не ожидал, что до такой степени.
   
+
-
edit
 

Mishka

модератор
★★★


ED>Balancer: «Нафиг лётчиков».
ED>И такое говорится на АВИАБАЗЕ? Куда смотрит администрация? Ах, да….
ED>Говорил я, что лётчики перестали котироваться, но не ожидал, что до такой степени.

Ed, тикай, а то покусают - зубы уже клацают :D


А что еще добавить - Рома не прав, но не в том, что летчиков, а в том, что динамическое связывание было и есть в С++, а уж в Джаве можно точно вызвать метод из любого объекта.


Говорил же я, что мы "регилиозные секстанты".


Но подробнее потом, а то я замаялся травку покосивши.

   
+
-
edit
 

Balancer

администратор
★★★★★


timochka>Теперь переименовываем файл Mylib2.dll в Mylib1.dll и снова запускаем.
timochka>Видим "Я класс MyClass2." - Но ведь мы ничего не пересобирали! Значит на лицо динамическое связывание.

Таки, ИМХО, это всё равно статическое связывание. Оно происходит при линковке программы, а не при её исполнении. DLL - это всего лишь продвинутая отложенная линковка. Хотя, могу и ошибаться. Но пример ещё не убедительный :)


К сожалению, у меня нет под рукой VC++, сделай, плиз, ассемблерный листинг вызова виртуальной функции - тогда и будет всё ясно :)


Кстати, вот ещё такая фишка. Динамическое связывание возможно только при наличии пространства имён, включённого в код готовой программы. А это автоматически подразумевает возможность вызова функции по её имени, полученному во время исполнения программы. Но мы знаем, что это на C/C++ невозможно :) Хотя, по-моему (тут не уверен) даже в O'Caml возможно (хотя чистейшей воды компилятор). Я не говорю уже про по-настоящему высокоуровневые языки :)


ED>Говорил я, что лётчики перестали котироваться, но не ожидал, что до такой степени.


Когда-то диназавры вымерли, сейчас лётчики вымирают, завтра вымрем мы, программеры... Уже начинается... :)


Mishka> А что еще добавить - Рома не прав, но не в том, что летчиков, а в том, что динамическое связывание было и есть в С++, а уж в Джаве можно точно вызвать метод из любого объекта.


На счёт Java ничего не могу сказать... Там виртуальная машина, так что язык, по сути - интепретатор. Думаю, очень ярким примером может быть реализация Python'а на Java (Jython). А там работа с объектами куда как богаче. Но в C++ - приведите мне ассемблерный кусок, показывающий именно динамическое связывание - я поверю :)


Да нет, бред это! Ну не умеет C++ работать с незнакомыми ему классами! Пусть у нас суперкласс не имеет нужной виртуальной функции. Тогда, чтобы её вызывать, как в постинге с примерами, что привёл timochka при добавлении её в субкласс, мы обязаны прописать её в суперкласс и перекомпилить dll с суперклассом. И это - динамическое связывание?? Зачем нам тогда перекомпиляция? :D
   

Lerm

втянувшийся
Balancer>На счёт Java ничего не могу сказать...
[/i]




В Jave можно для любого объекта вызвать любой метод. Точно. (И естественно получить по башке если такого метода не найдется).
   
+
-
edit
 

Balancer

администратор
★★★★★
Lerm>В Jave можно для любого объекта вызвать любой метод. Точно. (И естественно получить по башке если такого метода не найдется).

Ну и не удивительно. Язык-то фактически интерпретируемый :) (JVM - байткод). Вообще, если бы не ужасный синтаксис - язык бы хороший был. Впрочем, так и не щупал ещё Jython... :)
   

Lerm

втянувшийся
Balancer>Вообще, если бы не ужасный синтаксис - язык бы хороший был.




Гм. Ну иногда синтаксис да... Тот же вызов метода делается через <...>, зато универсален.
   
+
-
edit
 

Balancer

администратор
★★★★★


Lerm>Гм. Ну иногда синтаксис да... Тот же вызов метода делается через <...>, зато универсален.

Зато можно так:


code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]python[/b]'</font>
  2.  
  3. <span style='color:#800000; font-weight:bold; '>from</span> pawt <span style='color:#800000; font-weight:bold; '>import</span> swing
  4. <span style='color:#800000; font-weight:bold; '>import</span> java
  5.  
  6.  
  7. <span style='color:#800000; font-weight:bold; '>def</span> <span style='color:#e34adc; '>exit</span><span style='color:#808030; '>(</span>e<span style='color:#808030; '>)</span><span style='color:#808030; '>:</span> java<span style='color:#808030; '>.</span>lang<span style='color:#808030; '>.</span>System<span style='color:#808030; '>.</span><span style='color:#e34adc; '>exit</span><span style='color:#808030; '>(</span><span style='color:#008c00; '>0</span><span style='color:#808030; '>)</span>
  8.  
  9.  
  10. frame <span style='color:#808030; '>=</span> swing<span style='color:#808030; '>.</span>JFrame<span style='color:#808030; '>(</span><span style='color:#0000e6; '>'Swing Example'</span><span style='color:#808030; '>,</span> visible<span style='color:#808030; '>=</span><span style='color:#008c00; '>1</span><span style='color:#808030; '>)</span>
  11. button <span style='color:#808030; '>=</span> swing<span style='color:#808030; '>.</span>JButton<span style='color:#808030; '>(</span><span style='color:#0000e6; '>'Close Me!'</span><span style='color:#808030; '>,</span> actionPerformed<span style='color:#808030; '>=</span><span style='color:#e34adc; '>exit</span><span style='color:#808030; '>)</span>
  12. frame<span style='color:#808030; '>.</span>contentPane<span style='color:#808030; '>.</span>add<span style='color:#808030; '>(</span>button<span style='color:#808030; '>)</span>
  13. frame<span style='color:#808030; '>.</span>pack<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span>



:)


(гм. что-то он его не раскрашивает... а локально - всё ок)
   
RU Andy-Andrei #27.05.2003 15:05
+
-
edit
 

Andy-Andrei

втянувшийся

Под оперой - раскрашивает. А под мозилой и ие - нет. Забавно, да?
   
+
-
edit
 

Balancer

администратор
★★★★★
Andy-Andrei>Под оперой - раскрашивает. А под мозилой и ие - нет. Забавно, да?


Мда. Классно. И вправду. :) При чём код в начале страницы IE раскрашивает правильно...
   
+
-
edit
 

timochka

опытный



timochka>>Теперь переименовываем файл Mylib2.dll в Mylib1.dll и снова запускаем.
timochka>>Видим "Я класс MyClass2." - Но ведь мы ничего не пересобирали! Значит на лицо динамическое связывание.
Balancer>Таки, ИМХО, это всё равно статическое связывание. Оно происходит при линковке программы, а не при её исполнении. DLL - это всего лишь продвинутая отложенная линковка. Хотя, могу и ошибаться. Но пример ещё не убедительный :)


Dll это динамическая библиотека. Я могу загрузить ее по имени и получить указатель на функцию ПО ИМЕНИ ФУНКЦИИ. И огребу граблей при возове если не положу аргументы таким образом как хочет функция.



К сожалению, у меня нет под рукой VC++, сделай, плиз, ассемблерный листинг вызова виртуальной функции - тогда и будет всё ясно :)


Кстати, вот ещё такая фишка. Динамическое связывание возможно только при наличии пространства имён, включённого в код готовой программы. А это автоматически подразумевает возможность вызова функции по её имени, полученному во время исполнения программы.

А вот и не угадал. Все виртуальные функции класса нумеруются, а в классе заводится таблица виртуальных функций vtable. Там лежат указатели на РЕАЛИЗАЦИЮ данного метода в этом классе. И все вызовы виртуальных функций идут через таблицу. Т.е. класс тащит с собой указатели на собственные методы.

Т.е. невозможно вызвать метод по его символьному ИМЕНИ, но вполне можно вызвать если знаешь позицию метода в vtable. Именно так и работает с СОМ модулями писаными на С++ не объектные языки (ассемблер например).



Mishka> А что еще добавить - Рома не прав, но не в том, что летчиков, а в том, что динамическое связывание было и есть в С++, а уж в Джаве можно точно вызвать метод из любого объекта.

>Но в C++ - приведите мне ассемблерный кусок, показывающий именно динамическое связывание - я поверю :)


Да нет, бред это! Ну не умеет C++ работать с незнакомыми ему классами! Пусть у нас суперкласс не имеет нужной виртуальной функции. Тогда, чтобы её вызывать, как в постинге с примерами, что привёл timochka при добавлении её в субкласс, мы обязаны прописать её в суперкласс и перекомпилить dll с суперклассом. И это - динамическое связывание?? Зачем нам тогда перекомпиляция? :D


Не иметь прототипа в базовом классе это все равно что не знать ее имени. Ты не обязан знать ее реализацию ( func() =0 как раз и обозначает абстрактную функцию) Но надо указать ее смещение в таблице виртуальных функций и типы аргументов + тип возвращаемого значения.

А на ассемблере будет конструкция типа call classInstance.vtable[XXX]

Может тебя Рома такой кусок убедит.

class IMyInterface
{
public:
virtual void WhoIam(void) =0;
};

class MyClass1 : public IMyInterface
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass1", "Info", MB_OK); };
};

class MyClass2 : public IMyInterface
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass2", "Info", MB_OK); };
};

class MyClass33 : public MyClass2
{
public:
virtual void WhoIam(void) { MessageBox(0l, "Я класс MyClass33", "Info", MB_OK); };
};

IMyInterface GetInterface(void)
{
IMyInterface *pIntance = 0l;

switch (clock() % 3) // часы как датчик случайных чисел. Криво но так проще.
{
case 0:
pIntance = new MyClass1();
break;
case 1:
pIntance = new MyClass2();
break;
case 2:
pIntance = new MyClass3();
break;
}

return *pInstance;
}


// И гдето в нашей проге делаем такую шутку
for (int i = 0; i < 10; ++i)
{
GetInterface().WhoIam();
Sleep(100);
}
   
Это сообщение редактировалось 27.05.2003 в 16:41
+
-
edit
 

Balancer

администратор
★★★★★


timochka> GetInterface().WhoIam();


Ну и ругается он на эту строку: error C2259: 'IMyInterface' : cannot instantiate abstract class due to following members: 'void IMyInterface::WhoIam(void)' : pure virtual function was not defined test.cpp(6) : see declaration of 'IMyInterface::WhoIam' :)


Это захотел я код глянуть... Ну уверен я, что он статический будет :)
   
+
-
edit
 

timochka

опытный



timochka>> GetInterface().WhoIam();


Ну и ругается он на эту строку: error C2259: 'IMyInterface' : cannot instantiate abstract class due to following members: 'void IMyInterface::WhoIam(void)' : pure virtual function was not defined test.cpp(6) : see declaration of 'IMyInterface::WhoIam' :)


Это захотел я код глянуть... Ну уверен я, что он статический будет :)



Извини наврал в исходнике.

IMyInterface *GetInterface(void)
{
IMyInterface *pInstance = 0l;

switch (clock() % 3) // часы как датчик случайных чисел. Криво но так проще.
{
case 0:
pInstance = new MyClass1();
break;
case 1:
pInstance = new MyClass2();
break;
case 2:
pInstance = new MyClass3();
break;
}

return pInstance;
}

void main(void)
{
// И гдето в нашей проге делаем такую шутку
for (int i = 0; i < 10; ++i)
{
GetInterface()->WhoIam();
Sleep(100);
}

}

На асме кусок выглядит так (шоб я что-то понял)

; 53 : // И гдето в нашей проге делаем такую шутку
; 54 : for (int i = 0; i < 10; ++i)

$L54788:

; 55 : {
; 56 : GetInterface()->WhoIam();

call ?GetInterface@@YAPAVIMyInterface@@XZ ; GetInterface
mov edx, DWORD PTR [eax]
mov ecx, eax
call DWORD PTR [edx]

; 57 : Sleep(100);

push 100 ; 00000064H
call edi
dec esi
jne SHORT $L54788
pop edi

; 58 : }
; 59 :
; 60 : }


Могу сорец выложить.
   
+
-
edit
 

Balancer

администратор
★★★★★


Да я уже и сам ошибку исправил и скомпили. Код почти как у тебя. Вот только нет тут никакого динамического связывания. Обычная работа с указателями.


Я всё не могу чётко сформулировать, свою мысль на счёт свзывания. Ещё раз повторю такой пример. На C++ ты в суперклассе обязан указать все виртуальные функции. Ты не можешь из него вызывать функции, имена и интерфейсы которых на момент его компиляции ещё не определены. Это и есть одно из отличий статического и динамического связывания. При статическом - ты всё должен знать заранее. И для введения какого-то нового метода, общего для всех субклассов, ты должен перекомпилить суперкласс. Что невозможно, например, при расширении, скажем, коммерческой софтины частными DLL (только один из примеров). Скажем, есть у тебя программа A. Коммерческая, закрытая. Есть у неё API для пользовательских DLL. И по этому API все пользовательские DLL - это классы, наследники API-шного суперкласса. Всё хорошо, но в C++ с этого момента пользовательские расширения ограничены виртуальными методами суперкласса. И наследник расширения Б не может вызвать метод расширения В без введения этого метода в суперкласс API А. Да, расширение В, например, может слепить свой API и предоставлять его расширению Б. А если в другой раз захочется то же самое вызвать для расширения Г? В общем, получается, что всё равно ещё на этапе компиляции нужно знать всё обо всём, что там будет в дальнейшем. Что в реальных задачах не так уж редко нереально.


А в той же Java (как тут Lerm отмечает, я сам не пользовался этим) я могу рискнуть вызвать метод другого класса, даже если на этапе компиляции моей программы про тот метод ещё не было известно.
   
+
-
edit
 

Balancer

администратор
★★★★★


timochka>Извини наврал в исходнике.


Кстати, рекомендую [cоde cpp]...[/code] и [cоde asm]...[/code]. Чтобы симпатичнее смотрелось. Только от меня не копируй, я буквы русские вписал, чтобы не скомпилилось :)
   
+
-
edit
 

timochka

опытный



>Я всё не могу чётко сформулировать, свою мысль на счёт свзывания. Ещё раз повторю такой пример. На C++ ты в суперклассе обязан указать все виртуальные функции. Ты не можешь из него вызывать функции, имена и интерфейсы которых на момент его компиляции ещё не определены. Это и есть одно из отличий статического и динамического связывания. При статическом - ты всё должен знать заранее. И для введения какого-то нового метода, общего для всех субклассов, ты должен перекомпилить суперкласс. Что невозможно, например, при расширении, скажем, коммерческой софтины частными DLL (только один из примеров). Скажем, есть у тебя программа A. Коммерческая, закрытая. Есть у неё API для пользовательских DLL. И по этому API все пользовательские DLL - это классы, наследники API-шного суперкласса. Всё хорошо, но в C++ с этого момента пользовательские расширения ограничены виртуальными методами суперкласса. И наследник расширения Б не может вызвать метод расширения В без введения этого метода в суперкласс API А. Да, расширение В, например, может слепить свой API и предоставлять его расширению Б. А если в другой раз захочется то же самое вызвать для расширения Г? В общем, получается, что всё равно ещё на этапе компиляции нужно знать всё обо всём, что там будет в дальнейшем. Что в реальных задачах не так уж редко нереально.


А в той же Java (как тут Lerm отмечает, я сам не пользовался этим) я могу рискнуть вызвать метод другого класса, даже если на этапе компиляции моей программы про тот метод ещё не было известно.



Это все от того что С++ при динамическом связывании оперирует не символьными именами, а номерами методов. То есть в пределах одного дерева наследования компилер раздает всем виртуальным методам номера (они же смещения в таблице vtable). Естессно чтоб коректно раздать номера надо знать про все методы. В принципе ты можешь на низком уровне вызвать метод по номеру произвольно. То есть ты знаешь что у класса указатель на который тебе дали есть 10 виртуальных методов. Можешь дернуть все 10 методов сам. Но это дурной тон из соображений переносимости. Плюс если тебе дадут указатель который будет указывать на экземпляр имеющий только 5 методов, а попытаешься дернуть 10-й то программа рухнет. Поэтому требования иметь описания всех интерфейсов заранее это компромис для безопасности. Тем самым компилер проверяет за тебя корректность кода.

А низкоуровневый вызов выглядит чем-то типа
code text
  1. <font size=1>Created with colorer-take5 library. Type '[b]cpp[/b]'</font>
  2.  
  3. pInstance<span style='color:#808030; '>-</span><span style='color:#808030; '>></span>vtable<span style='color:#808030; '>[</span><span style='color:#008c00; '>10</span><span style='color:#808030; '>]</span><span style='color:#808030; '>(</span><span style='color:#808030; '>)</span><span style='color:#800080; '>;</span> <span style='color:#696969; '>// вызвать 11-й виртуальный метод</span>

Только учти что член класса vtable имеет атрибут private.
   
1 2 3 4

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru