![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Свершенно мерзкое словечко const. Стоит только лишь наивно поверить, что константность лучше указывать, чем игнорировать, как код начинает пестрить этим словечком, что АхредуптусЪ русский дореволюционный буквой Ъ. А ежели где его и позабудешь - компилятор, ессно, тебя не поправит, "сойдет и так".
Между тем, совершенно понятно, что константность значения в приличном языке должна быть обеспечена по умолчанию, без всяких ключевых слов, а именно вариабельность и следует указывать.
Например,
char **a;
приличной реализации языка следует понимать как константный указатель на константный указатель на константный символ.
А, к примеру,
char var **a = getAddress();
**a = 'Ъ';
следует понимать как цепочку константых указателей на неконстантный символ (который мы, собственно, и собрались менять). И вот тут-то, если где словечко var будет позабыто, компилятор начнет ругаться практически наверняка.
Мало этого. Слово var по большому счету тоже излишне. Неконстантность значения есть, вообще говоря, преступление перед Разумом. В приличном языке оператор присваивания, меняющий значение, уместен не более, чем оператор goto. Что это за бред такой?! Вы где-то видели в математике (оперирующей символами сплошь и рядом) какой-то там "оператор присваивания"?! Оператор присваивания полностью запутывает программу, принуждая программиста отслеживать так называемые "изменения переменных" - это пострашнее отслеживания любых переходов с метки на метку. Язык Prolog же, к примеру, как и следовало ожидать, прекрасно обходится без оператора присваивания. Ибо нафиг не нужен.

Между тем, совершенно понятно, что константность значения в приличном языке должна быть обеспечена по умолчанию, без всяких ключевых слов, а именно вариабельность и следует указывать.
Например,
char **a;
приличной реализации языка следует понимать как константный указатель на константный указатель на константный символ.
А, к примеру,
char var **a = getAddress();
**a = 'Ъ';
следует понимать как цепочку константых указателей на неконстантный символ (который мы, собственно, и собрались менять). И вот тут-то, если где словечко var будет позабыто, компилятор начнет ругаться практически наверняка.
Мало этого. Слово var по большому счету тоже излишне. Неконстантность значения есть, вообще говоря, преступление перед Разумом. В приличном языке оператор присваивания, меняющий значение, уместен не более, чем оператор goto. Что это за бред такой?! Вы где-то видели в математике (оперирующей символами сплошь и рядом) какой-то там "оператор присваивания"?! Оператор присваивания полностью запутывает программу, принуждая программиста отслеживать так называемые "изменения переменных" - это пострашнее отслеживания любых переходов с метки на метку. Язык Prolog же, к примеру, как и следовало ожидать, прекрасно обходится без оператора присваивания. Ибо нафиг не нужен.
no subject
Date: 2004-05-29 03:31 am (UTC)no subject
Date: 2004-05-29 03:37 am (UTC)Дык, однолюб я. Т.е. жутко консервативен. Опять же, нравится мне ООП. Тот, который не во главе с Арафатом.
> (Или я воспринимаю ваш текст слишком всерьез?)
:-)))
хе-хе
Date: 2004-05-29 05:10 am (UTC)"I invented the term Object-Oriented, and I can tell you I did not have C++ in mind."
-- Alan Key
Re: хе-хе
Date: 2004-05-29 10:14 am (UTC)Хотя, на мой взгляд, определение выглядит устаревшим.
no subject
Date: 2004-05-29 10:34 am (UTC)Кей, к примеру, определённо имел в виду объектную ориентацию программ, а не языка, понимаемого компилятором.
программы, написанные на C++, после компиляции объектно-ориентированными не являются (кроме тех редких случаев, когда все методы виртуальны, программист позаботился не отключить RTTI, и программа умеет читать свою собственную debug info).
термин "объектно-ориентированное" и звучит именно таким образом (а не, скажем, "класс-ориентированное" или "фигурно-скобочно-ориентированное"), потому что говорит об объектах. объект — это такая фигня, которая существует (то есть живёт в оперативной памяти, может быть идентифицирована, и имеет определёный тип) во время работы программы, а не её компиляции.
людям, пишущим batch-утилиты и не пользующимся никакой интроспекцией, это различие неважно. многим другим — важно.
no subject
Date: 2004-05-29 11:30 am (UTC)Что до RTTI, то помимо реализации мультиметодов, напрямую в С++ неподдерживаемых и всякой базовой мелочи, вроде стриминга идетнификаторов классов, я не вижу реальной необходимости в RTTI.
Что до Debug Info - опять же применение неясно. Что такого хорошего можно поиметь с интроспеции?
no subject
Date: 2004-05-29 01:21 pm (UTC)как показывает опыт, объяснять необходимость подобных радостей жизни совершенно бесполезно. если припрёт — поймёте сами, если не припрёт (а припирает далеко не всех, и это абсолютно нормально) — то и ну его.
чтобы меня правильно поняли: я вовсе не утверждаю, что C++ говно, потому что не по-настоящему объектно-ориентирован (он говно по достаточному количеству иных причин, право же). объектная ориентация не есть сама по себе критерий качества. я всего лишь пытался объяснить, что (как мне кажется) мог иметь в виду г-н Кей, поскольку (как мне, опять-таки, кажется) я понимаю откуда пляшут его определения, поскольку я неплохо знаком с системами типа Smalltalk'а и Lisp'а.
no subject
Date: 2004-05-29 01:26 pm (UTC)И понятно, что объяснить можно тому, кто и так всё почти понимает. По крайней мере, в двух абзацах.
Может, хоть ссылочки адекватнуе кинете по интроспекции и её нетривиальной пользе для долгоживущих систем, data-oriented programming и проч? - я б почитал.
no subject
Date: 2004-05-29 02:06 pm (UTC)вот поглядите, скажем, на стоящее перед Вами в данный момэнт устройство типа "персональный компьютер". на нём бежит большая, долгоживущая и интроспективная по самое не могу программа, называемая "операционная система".
предположим, эта система называется "юникс" (система типа "виндоуз" отличается от системы типа "юникс", но не существенно. "юникс" в принципе сильно проще, а посему представляет из себя лучший пример). аналогом "процедур" в языке "юникс" являются бинарные программы, интерпретируемые процессором. аналогом аргументов являются строчки из коммандной строки. аналогом пойнтеров — имена файлов. аналогом структур данных — файлы. единственным типом данных, который понимает "юникс", является голая строка из байтов, у которой даже длина не указана. имеется также run-time environment, называемый "ядро операционной системы", отвечающий за разделение процедур друг от дружки, подчищание экскрементов, убиение слищком жадных до памяти процедур, и прочая.
теперь представьте, что в качестве базового языка и run-time environment'а мы имеем что-то менее идиотское чем "юникс", например Smalltalk, или Lisp, или на худой конец Java. представьте себе теперь, что на основе подобного базиса написана настоящая операционная система (примеры имели место, и вполне успешные, кстати). можно ли написать подобную вещь привычным class-oriented стилем? нельзя, поскольку все объекты, с которыми подобной программе придётся иметь дело — "manifestly typed", то есть самоописывающиеся. их тип закодирован в них самих, мы не можем рассказать его компилятору и забыть о нём.
теперь более практически: программирование на Smalltalk, Lisp, или на худой конец Java разумнее рассматривать не как "написал код, скомпилировал в маааленький исполняемый файл, отправил заказчику", а как "взял исходную систему, расширил её своей функциональностью". таким образом, философия системы естественным образом перетекает в философию приложений, реализованных на базе этой системы.
что же касается "data-oriented programming", то ничего особенно содержательного в этом понятии нет. это просто следствие из видения мира, в котором полноценные типированные объекты (а не C++-like куски памяти, тип которых когда-то знал компилятор) живут в программе, а не только в компиляторе.
если всё-таки хочется ссылок, то лучше сгрузить с сети хороший Smalltalk или Common Lisp и поиграться с ним. :)
no subject
Date: 2004-05-30 01:17 am (UTC)Опять же, видимо, в силу моего ограниченного опыта, не совсем понятно, что нормальная программа (а не дебаггер-трассировщик какой-нибудь) может сделать с "полноценным типированным объектом" такого нетривиального. Есть, конечно, отдельные случаи, когда имеет смысл выяснить, поддерживает ли объект тот или иной интерфейс (C++ RTTI, COM IIDs etc.), но кажется, по большей части такая практика свидетельствует о неполноценности дизайна, который приводит к череде if-ов, разбросанных там-сям в программе и крайне тяжело поддерживаемых в больших проектах. Кажется, за такую практику Страуструп где-то и критиковал SmallTalk.
В целом ясно почти наверняка, что Вы знаете, о чем говорите :-), а мой опыт в OOP уж точно выкристализован действительно не в самом нормальном контексте С++ и не обогащен в достаточной мере иными ОО-языками. Просто пока содержательная часть ваших утверждений для меня не очень ясна - это следовало бы отметить, а не кивать головой в знак понимания того, чего я пока не понимаю.
no subject
Date: 2004-05-30 02:27 am (UTC)операционные системы (кроме некоторых совсем уж ужатых embedded) позволяют пользователю (и его программам) задавать вопросы о состоянии системы, и менять параметры системы исходя из этого. скажем, пользователь может спросить, сколько свободной памяти осталось. или узнать, реализована ли в системе конкретная процедура, пороверив наличие соответствующего исполняемого файла. или спросить, какой тип у определённого файла данных. или проверить, бежит ли некая программа, и если бежит — убить.
> Опять же, видимо, в силу моего ограниченного опыта, не совсем понятно, что нормальная программа (а не дебаггер-трассировщик какой-нибудь) может сделать с "полноценным типированным объектом" такого нетривиального. Есть, конечно, отдельные случаи, когда имеет смысл выяснить, поддерживает ли объект тот или иной интерфейс (C++ RTTI, COM IIDs etc.), но кажется, по большей части такая практика свидетельствует о неполноценности дизайна, который приводит к череде if-ов, разбросанных там-сям в программе и крайне тяжело поддерживаемых в больших проектах. Кажется, за такую практику Страуструп где-то и критиковал SmallTalk.
мой предыдущий пост был достаточно сумбурен, и этот обещает быть не лучше. :)
основная идея в следующем: говоря о data-oriented programming, я не пытаюсь что-либо рекламировать. я очевидным образом не сумел сформулировать самый важный пункт: DOP не есть что-то, что получается посредством сознательного применения каких-то там специальных методик. DOP — это то, что остаётся после отказа от явных глупостей. разумеется, придерживающиеся философии DOP системы делают практичными некоторые методики, о которых в C++ и иже с ним даже думать не получается, но это уже следствие и в данном контексте менее интересно.
например, я не в коем случае не утверждаю чего-либо о [не]желательности полноценного дизайна. ясное дело, наличие дизайна объективно лучше, чем отсутствие такового. означает ли это, что система не должна в принципе допускать возможности работать иным образом?
давайте я для простоты перечислю (некоторые) фундаментальные аспекты философии C++ и иже с ним, которые я считаю глупостями:
1. тип объектов как нечто, присутствующее лишь во время компиляции. это чисто философски неприятно:
0 — это число 0, а ни в коем случае не указатель на объект, сидящий по адресу 0, и не значок с кодом 0.
"abc" — это строка "abc", а не число 1633837824 и не указатель на объект по соответствующему адресу.
если мне захочется писать на ассемблере, я найду себе ассемблер. если же я рассматриваю объекты не как куски памяти, а как объекты, то я не желаю и думать про куски памяти, и я хочу чтобы мой runtime environment помогал мне в этом.
2. тип объектов как нечто, присутствующее лишь при компиляции. это чисто философски неприятно ещё и по той простой причине, что выкидывать информацию вообще в принципе некрасиво. кто он, чёрт возьми, такой, этот компилятор, и почему он считает себя умнее меня?
вообще, C++ и иже с ним навязывают разработчику определённые глобальные оптимизации, ценность которых, мягко говоря, неочевидна, и которые предполагают что разработчик либо пишет тупые batch-утилиты, либо знает Абсолютно Всё На Свете заранее.
3. (как следствие из предыдущих пунктов) unsafe runtime environment. в наше время это просто смешно, это даже оптимизацией не назовёшь, это мазохизм чистой воды (не говоря уже о проблемах с security).
> В целом ясно почти наверняка, что Вы знаете, о чем говорите :-), а мой опыт в OOP уж точно выкристализован действительно не в самом нормальном контексте С++ и не обогащен в достаточной мере иными ОО-языками. Просто пока содержательная часть ваших утверждений для меня не очень ясна - это следовало бы отметить, а не кивать головой в знак понимания того, чего я пока не понимаю.
это правильно. :)
no subject
Date: 2004-06-02 07:28 am (UTC)А именно? Что Вы имеете в виду?
> означает ли это, что система не должна в принципе допускать возможности работать иным образом?
Сложный вопрос. С одной стороны, кашу маслом не испортишь. Но вот считать RTTI и вообще интроспекцию необходимой частью OO без демонстрации сереьзных примеров применения, я бы не стал.
При этом я не отрицаю реальную необходимость RTTI в С++, как уже было сказано - но это в силу ограниченности средств языка (того же отсутствия мультиметодов), а не в силу естественности применения RTTI в OO.
Кастирование нуля в указатель итп., конечно, не очень удачно. Но почему нельзя рассматривать строки как указатели на память - именно ради оптимизации, понятно не очень. Так или иначе, понятно, что среда действительно крайне ненадёжна - мне как раз, в отличие от вас, видится, что отчасти это следствие именно оптимизации (строк и массивов вообще).
> выкидывать информацию вообще в принципе некрасиво
Слишком общее утверждение. Эдак, вы еще захотите, чтобы программе были доступны собственные исходники.
> тип объектов как нечто, присутствующее лишь при компиляции. это чисто философски неприятно
RTTI уже есть (его значение в С++ я не преуменьшаю). А что еще нужно, кроме него, чтобы тип объекта присутствовал в Run Time? Доступ к контейнеру, содержащему имена и типы всех методов объекта? :-) Или? И что мы с такой информацией такого можем сделать?
И опять же, как отсутствие типа объекта превращает делает нам "unsafe runtime environment" ?
no subject
Date: 2004-06-03 10:18 am (UTC)а очень просто.
файл "ook.h":
файл "eek.h":
файл "ook.cpp":
файл "eek.cpp":
скомпилируйте ook.cpp и eek.cpp и слинкуйте вместе. ответьте на вопрос: что именно считать определением типа "a" в результирующей программе, и будет ли она работать? :)
> > делают практичными некоторые методики, о которых в C++ и иже с ним даже думать не получается
>А именно? Что Вы имеете в виду?
нетушки :). я пока ещё не убедился, что мы вообще на одном языке разговариваем. потому что если Вам кажется, что Вам (или, если угодно, Вам как (по крайней мере, отчасти) типичному представителю любителей C++) пытаются "продать" safe runtimes, то мы друг друга не понимаем.
> Сложный вопрос. С одной стороны, кашу маслом не испортишь. Но вот считать RTTI и вообще интроспекцию необходимой частью OO без демонстрации сереьзных примеров применения, я бы не стал. При этом я не отрицаю реальную необходимость RTTI в С++, как уже было сказано - но это в силу ограниченности средств языка (того же отсутствия мультиметодов), а не в силу естественности применения RTTI в OO.
I beg your pardon? объектная ориентация подразумевает типирование объектов, точка. необходимой частью принятого стиля программирования на C++ RTTI, очевидно, не является. (это одна из причин, по которым о C++ желательно забыть, ну да ладно. :))
> Кастирование нуля в указатель итп., конечно, не очень удачно.
принцип "I don't care if this is wrong, as long as this is fast" вообще не очень удачен.
> Но почему нельзя рассматривать строки как указатели на память - именно ради оптимизации, понятно не очень. Так или иначе, понятно, что среда действительно крайне ненадёжна - мне как раз, в отличие от вас, видится, что отчасти это следствие именно оптимизации (строк и массивов вообще).
строка была не самым удачным примером, поскольку в C/C++ это действительно указатель на память. давайте так: "abc" — это именно и только указатель на место, где сидят 'a', 'b', 'c' и '\0'. а не номер 67868767, не массив целых чисел, не ...
> > выкидывать информацию вообще в принципе некрасиво
> Слишком общее утверждение. Эдак, вы еще захотите, чтобы программе были доступны собственные исходники.
не захочу. система типов (и прочая интересная структурная информация) никакого отношения к исходникам не имеет и исходников для интерпретации не требует.
> RTTI уже есть (его значение в С++ я не преуменьшаю). А что еще нужно, кроме него, чтобы тип объекта присутствовал в Run Time? Доступ к контейнеру, содержащему имена и типы всех методов объекта? :-)
не вижу причин для смайлика. насчёт имён не знаю, зависит от языка. но какую-то идентификацию — безусловно. потому что method dispatch обязан принимаеть во внимание тип объекта (а не тип указателя при компиляции и т.д.). вообще-то, в случае C++, такой "контейнер" принято называть vtable.
ладно методы. вот что абсолютно необходимо, так это описание data layout'а каждого класса.
> И что мы с такой информацией такого можем сделать?
пожалуйте изучить (ещё разок) примерчик из начала данного комментария. :)
> после компиляции объектно-ориентированными не являю
Date: 2008-09-18 08:00 pm (UTC)Re: > после компиляции объектно-ориентированными не яв
Date: 2008-09-18 08:37 pm (UTC)извините. :)
> пытался объяснить оригинальное (т.е. согласно Алану К
Date: 2008-09-18 08:38 pm (UTC)> извините. :)
np :-)
no subject
Date: 2004-05-29 03:56 pm (UTC)no subject
Date: 2007-03-29 03:39 pm (UTC)У вас есть какое-то разумное объяснение, почему в программе переменные - вторичны, а константы - первичны?
no subject
Date: 2007-10-31 01:14 am (UTC)no subject
Date: 2007-10-31 09:42 am (UTC)Вот посчитал по прожекту число присваиваний:
---------- DB_LAYER.CS: 225
---------- EFT.CS: 41
---------- TMS_MANAGEMENT.CS: 28
---------- TREASURYMONITORSERVICE.CS: 137
---------- TREASURYMONITORSERVICE_AIRTIME.CS: 79
---------- TREASURYMONITORSERVICE_LOYALTY.CS: 49
---------- TREASURYMONITORSERVICE_SPUR.CS: 33
---------- TREASURYMONITORSERVICE_TRANSACTION.CS: 144
---------- TREASURYMONITORSERVICE_VOUCHERS.CS: 35
Я бы сказал, не так уж и мало! Часть, так и быть, инициализация (хотя у меня большинство констант сидят в enum), но остальных присвоений тоже немерянно!
Я хочу сказать так: ни var, ни const не спасает от банально тупых алгоритмов. Куда больше гемороя приносят неочевидные "особенности" чужих функций.