Re[19]: О правильных и неправильных классификациях...
От: FR  
Дата: 17.03.06 15:53
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Здравствуйте, FR, Вы писали:


FR>>Похоже очень большая часть программ как раз и нарушает любые законы развития — и кривые и неэффективные

FR>>И ничего прекрасно живут
КЛ>Как раз-таки непрекрасно. Расплата заключается в резком увеличении сложности сопровождения таких программ. Например, я видел несколько программ, за которые ряд аутсорсеров просно не рискнули взяться, т.к. сложность сопровождения была очень высока. А те, что взялись, так и не смогли выполнить пожелания заказчика, т.к. просто не смогли побороть основные баги.

Все это так, но вопрос в том может ли тут помощь ТРИЗ, и эффективнее ли он чем классические методики?
По моему эффективность ТРИЗ для решения задач проектирования и программирования под большим вопросом.
Re[9]: О правильных и неправильных классификациях...
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.03.06 19:38
Оценка: 10 (1)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

C>>Все еще уверены, что чем компактнее код — тем он лучше?


LCR>Много синтаксического оверхеда. Это не компактный код. Это просто утоптанный код


Это не синтаксический оверхэд. Это классический пример во что выливается стремление к компактности если при этом упускается из виду абстрагирование и декомпозиция.

Я уже не раз замечал, что менее компактный, но более поддающийся декомпозиции и абстрагированию EBNF воспринимается намного лучше чем более компактные регулярные выражения.

При этом синтаксический оверхэд скорее в EBNF, но при этом читается он намного лучше.

Для восприятия важно чтобы компактным был не весь код программы, а чтобы компактно выглядело описание некоторой мысли.

Есть три способа повысить компактность:
1. Использовать короткие идентификаторы и символьные сокращения. Это путь регекспов, Перла и многих функциональных языков.
2. Использоват массу умолчаний. Опять же многие ФЯ этим злоупотребляют.
3. Описание задачи с использованием высокоуровневых абстракций с отдельной детализацией абстракций. Этот путь доступен почти в любом современном языке программирования, но к сожалению он требует усилий от программиста, а значит целиком и полностью зависит от его оптыта. Язык может только подталкивать к декомпзиции предоставляя удобные средства для этого. ООП, функции высшего порядка, да и просто процедуры — это все средства декомпозиции.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: О правильных и неправильных классификациях...
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.03.06 19:38
Оценка: +1
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>В добрый путь. Я попробую на J:

LCR>
LCR>divmod=: <.@% , |~

LCR>anag=: (4 : 0)^:(1: < #@])
LCR>  'q n'=. x. divmod !<:#y.
LCR>  (q{y.) , n anag (q{.y.) , (>:q)}.y.
LCR>)


Ужас. И зачем такими извращениями вообще заниматься?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: О правильных и неправильных классификациях...
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.03.06 19:38
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Краткости можно достигнуть необязательно в ущерб чтению.


LCR>Приведу пример (qsort на Erlang и C).

LCR>
LCR>sort([Pivot | T]) ->
LCR>    sort([ X || X <- T, X < Pivot]) ++
LCR>    [Pivot] ++
LCR>    sort([ X || X <- T, X >= Pivot]);
LCR>sort([]) -> [].
LCR>

LCR>
LCR>qsort( a, lo, hi ) int a[], hi, lo;
LCR>{
LCR>  int h, l, p, t;
LCR>  if (lo < hi) {
LCR>    l = lo;
LCR>    h = hi;
LCR>    p = a[hi];
LCR>    do {
LCR>      while ((l < h) && (a[l] <= p)) 
LCR>          l = l+1;
LCR>      while ((h > l) && (a[h] >= p))
LCR>          h = h-1;
LCR>      if (l < h) {
LCR>          t = a[l];
LCR>          a[l] = a[h];
LCR>          a[h] = t;
LCR>      }
LCR>    } while (l < h);
LCR>    t = a[l];
LCR>    a[l] = a[hi];
LCR>    a[hi] = t;
LCR>    qsort( a, lo, l-1 );
LCR>    qsort( a, l+1, hi );
LCR>  }
LCR>}
LCR>

LCR>Легко видеть, что краткость в первом случае выше (я так же отдаю себе отчёт в том, что во втором случае быстродействие круче, но сейчас это неважно).

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

На С тоже можно создать уграханную реализацию "уже не быстрой стртировки" воспользовавшись выскооуровневыми функциями манипуляции со списками и отказавшись от сортировки по месту (императивной по своей сути).

Вот как это могло бы выглядеть:
List Sort(List list)
{
    Elem pivot = GetFirst(list);
    return Concat(GetGreater(list, pivot), pivot, GetSmallerOrEq(list, pivot));
}

И что этот код на С сильно сложнее примера на разных КулХаскелях или Эрлэнгах?

Да, нисколичко! Он даже понятнее.

Так что дело в абстракцийях, а не магии языков. Просто некоторые языки подталкивают к абстрагированию, а другие нет. Плюс конечно наличие мощьных языковых конструкций вроде листкоприехеншона позволяют скрять часть сложности алгоритма.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: О правильных и неправильных классификациях...
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 18.03.06 08:39
Оценка:
VladD2,

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


Да, конечно, абстракции имеют важное значение. (Видел плюсик к посту Евгения?)

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

Возьмём C. Что можно сделать с функцией (абстрактным действием)?
1. Вызвать функцию из другой функции.
2. Взять у функции указатель и вызвать через указатель.
Всё.

Языки типа Java/C# добавляют сюда ещё виды клея (пока то, что в голову пришло, возможно не всё):
3. Генерация функций в рантайме.
4. Логическая классификация функций и привязка функций к данным.
Cахар:
5. Расширенные возможности для записи функций. (ex: проперти в C#)

Вот и получается, что зачастую то, что делается легко и непринуждённо в Java, на C идёт тяжело.

Так что для достижения краткости магия имеет значение. Последний пример:
    ord =: /:@:/:
    ord 6 4 5 10
2 0 1 3

(результат — вектор ординалов, а использовано лишь 2 кирпича "/:"). Здесь применён вид клея, вообще отсутствующий в C-подобных языках — называется "fork" и сахар, также отсутствующий в C-подобных языках, называется "tacit form".
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re: О правильных и неправильных классификациях...
От: AVC Россия  
Дата: 18.03.06 13:28
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>К сожалению, очень много программистов знают только один способ борьбы со сложностью — полиморфизм. И применяют его как к месту, так и не к месту. Но есть и другие способы группировки, есть критерии для объединения сущностей в группу, есть и типичные ошибки группирования.


Вот еще один заслуживающий внимания способ решать подобные задачи, основанный на нахождении инварианта:
http://www.embedded.com/story/OEG20010725S0103

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[16]: О правильных и неправильных классификациях...
От: AVC Россия  
Дата: 18.03.06 13:50
Оценка:
Здравствуйте, FR, Вы писали:

FR>Да самый эффективный в одной узкой области. В других областях ничем ни выдающийся. Хотя его общие положения о развитии систем и идеальной машине мне нравятся


Насчет других областей — не уверен.
В свое время меня удивил факт, насколько близок ТРИЗ к классической диалектике.
То, что писал о мышлении, например, философ Ильенков, в самом главном — почти один в один согласуется с ТРИЗ.
А ведь Ильенков — не "технарь", а философ (и даже марксист ), о ТРИЗ, скорее всего, не знал.
В качестве примера подобного мышления он приводил решение Марксом проблемы прибавочной стоимости.
Описание проблемы выглядело примерно так: капиталист покупает товар по его стоимости, продает по его стоимости, а получает прибыль.
Я хочу сказать, что применение вполне "тризовских" методов может иметь место и без лейбла "ТРИЗ".
Но ТРИЗ привел их в систему, что очень хорошо.

FR>А оно есть это основное противоречие? а если его нет?


Ах, где бы взять такую архитектуру — без противоречий...

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[20]: О правильных и неправильных классификациях...
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 18.03.06 15:52
Оценка: 12 (1)
Здравствуйте, FR, Вы писали:

FR>Все это так, но вопрос в том может ли тут помощь ТРИЗ, и эффективнее ли он чем классические методики?


Классическая ТРИЗ включает ряд инструментов различных системных уровней и уровней сложности:

1. Приемы устранения технических противоречий (http://www.altshuller.ru/triz/tools.asp).
2. Систему стандартов (http://www.altshuller.ru/triz/standards0.asp).
3. Алгоритм решения изобретательских задач (http://www.altshuller.ru/triz/ariz.asp).
4. Физические, химические, геометрические эффекты (http://www.altshuller.ru/triz31.asp, http://www.altshuller.ru/triz32.asp).
5. Законы развития технических систем (http://www.altshuller.ru/triz/zrts.asp).
6. Методы борьбы с психологической инерцией (http://www.altshuller.ru/triz36.asp).
7. Курс развития творческого воображения (http://www.altshuller.ru/rtv/).
8. Системный оператор (http://www.altshuller.ru/triz/zrts6.asp).

Ряд из этих инструментов "заточен" для решения изобретательских задач в технике. Например, приемы, стандарты, АРИЗ, физические, химические и геометрические эффекты. Понятно, что прямолинейный (и, следовательно, тупой) перенос этих инструментов в программирование невозможен. Во всяком случае, все известные мне попытки такого переноса закончились неудачей. И это неудивительно — ведь инструменты создавались для решения задач совсем иного класса.

Тем не менее, другие инструменты и понятия ТРИЗ (высокого системного уровня), например, законы развития технических систем, идеальность, системный оператор могут быть использованы для решения сложных "программистских" задач. Собственно, мы это попытались показать в своих статьях. Например, статья "Освобождение узников оператора "IF" (http://www.triz-ri.ru/themes/method/creative/creative57.asp) как раз про системный оператор.

К сожалению, сложные инструменты ТРИЗ (законы, идеальность, системный оператор) предъявляют высокие требования к квалификации человека, который их применяет. Опыт показал, что большинство людей, использующих ТРИЗ, применяют приемы. Кропотливый разбор задачи по АРИЗ или постановка задачи при помощи системного оператора дается, увы, не многим. Аналогичная ситуация складывается и в программировании — большинству людей удобнее применять паттерны (аналог приемов) и рефакторинг, чем качественно и кропотливо ставить задачу, рассматривать вещь не саму по себе, а в контексте, в группе. Честно Вам скажу, разнесение сущностей по разным системным уровням (выделение подсистемы, системы и надсистемы) — еще та задачка. (Здесь я, конечно же, не имею в виду совсем тривиальные вещи типа колеса, автомобиля и автотранспорта, где системные уровни всех трех сущностей очевидны.)

Тем не менее, более простые инструменты ТРИЗ, "заточенные" под решение "программистских" задач создать все-таки возможно. Только для этого нужно пользоваться не простым переносом приемов из "железной" ТРИЗ, а созданием и анализом информационного фонда. Собственно, такая работа уже ведется, и опубликованные статьи — лишь "первые ласточки".
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[17]: О правильных и неправильных классификациях...
От: Кодт Россия  
Дата: 18.03.06 20:20
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Я сразу хочу отметить, что с ТРИЗом знаком поверхностно и защищать его не хочу, хочу грокнуть "так таки да или таки нет". Может пригодится.


Извините, что влезаю с полу-оффтопиком.
Сама постановка вопроса: таки-да или таки-нет — это как раз дуальность, и к ТРИЗу имеет прямое отношение

Можем даже переформулировать. В терминах ТРИЗ.

Проблема 1:
— хочется представлять задачи как можно проще (например, прозревать в них единственный паттерн "противоречие")
— хочется представлять задачи как можно гибче и детальнее (прозревая разные паттерны, наиболее подходящие по месту)

Проблема 2:
— хочется грокнуть ТРИЗ
— не хочется тратить время на гроканье ненужных вещей

Из этого следует, что паттерн "противоречие" (а значит, и методология работы с ним) никуда из природы не девается, и ему есть ненулевое место. Какое именно?

А вот какое. У творческой ситуации есть три стороны:
— проблема (текущее положение дел)
— цель
Концентрация на проблеме — представление её в тех или иных моделях (ТРИЗовой, GoFовой и т.д.). Концентрация на цели — разные методологии.
Как вы понимаете, сами по себе, в отрыве друг от друга, они не приносят плоды.
Механическая состыковка возможна в достаточно узком круге случаев.
Собственно, опять дуальность.

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

В общем, мораль такая. Грокнуть нужно чуть-чуть в учебных целях. А когда/если пригодится — тогда уже грокать на всю катушку.
Перекуём баги на фичи!
Re[7]: О правильных и неправильных классификациях...
От: Кодт Россия  
Дата: 18.03.06 21:09
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

C>>Первый пример вообще никуда не годится. Имеем стандартный случай с

C>>необходимостью создания функции (тем более, что в реальной жизни у нас
C>>не будет хороших статических массивов из трех строк).

КЛ>Первый, как и все остальные примеры, взят из реальной жизни. Это к вопросу о надуманности.


Знаете, в чём тут фокус. Вы оба закапываетесь внутрь системы, которая называется "проектирование".
Введите компонент "проектировщик" и посмотрите на его качества.

У проектировщика есть опыт, одна из важных составляющих которого — способность распознавать шаблоны.
ТРИЗовец натаскан на один набор шаблонов, ГОФовец — на другой, индусский тапёр вообще не натаскан и играет как умеет.

Модели, естественно, взаимно проникают и пересекаются.
Поэтому в случае с обработкой строки мы можем увидеть и классическое противоречие, и посылку для рефакторинга "выделение функции", и посылку для готовых инструментов обработки строк.
В случае иерархией классов (Безье, сонм датчиков и т.д.) — можно разглядеть сразу посылку для некоторых структурных и функциональных паттернов: например, Посетитель и Адаптер / Прокси.

Чем богаче арсенал разработчика, и чем менее он обусловлен любимыми (или навязанными) инструментами, тем ему проще.
Буч, как отец-основатель иерархий классов, попался с датчиками. Кирилл, как приверженец ТРИЗ, пошёл трудным путём с кривыми Безье (переоткрыв ГОФ-паттерны).



Эти две тризовские статьи немного лукавят, предлагая читателю не отвлекаться на известные ему решения в других парадигмах ("объясните школьнику"). С целью обучения конкретной парадигме — это справедливо. В других целях — это разовьёт догматизм.

Теперь, чтобы вернуть в природу равновесие, нужно написать такой же вводный учебный курс по ГОФ



Да, кстати, насчёт отладки утечек. Ещё одно лукавство мелкого плана: а именно, время-деньги.

Тотальное журналирование new/delete находит все полюсы проблемы за единственный запуск программы.
Выборочное журналирование находит некоторые полюсы за логарифмическое количество запусков.

Вот и выбираем асимптотики — O(1) со зверским коэффициентом при инструментировании против O(log n) с относительно дешёвым инструментированием и неизвестно каким коэффициентом при запуске.

Например, сервер или встроенный софт так тестировать точно нельзя. Эту булочку мы уже проходили
Перекуём баги на фичи!
Re[8]: О правильных и неправильных классификациях...
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 18.03.06 21:50
Оценка: :)
Здравствуйте, Cyberax, Вы писали:

C>Все еще уверены, что чем компактнее код — тем он лучше?


То, что Вы продемонстрировали, как раз и называется подсистемным мышлением. Судя по приведенному примеру, Вы предполагаете, что программный код – это набор символов. Но это неправильно! Это все равно, что предполагать, будто дом – набор кирпичей или строительных блоков.

Так же, как письменная речь не сводится к набору букв, так и программный код – нечто большее, чем набор символов. Код имеет иерархическую структуру, и на каждом уровне этой иерархии в качестве элементов выступают разные абстракции:

0. Символы.
1. Слова (операторы, переменные, константы, типы данных).
2. Функции и функциональные блоки.
3. Типы данных, определяемые пользователем.
4. Иерархии, группы связанных классов.
5. Библиотеки.
6. И т.д. – наверняка что-то пропустил.

Соответственно, когда я пишу, что хороший код – это компактный код, я отнюдь не имею в виду минимальное количество символов. Ибо хорошо понимаю, что код – это нечто большее, чем просто набор символов, и вижу различные системные уровни.

Как я уже писал, для задания критерия качества кода мне привычнее пользоваться понятием идеальность. Это «тризовский» термин, и суть его заключается в следующем:

Идеальная система – эта система, которой нет, а функция ее выполняется.

Применительно к программному коду, это правило будет звучать так:

Идеальный код – это код, которого нет, а функция его выполняется.

Понятно, что в реальной жизни ни идеальных технических систем, ни идеального программного кода не существует. Идеальность – это модельное понятие. Это предел, к которому в своем развитии стремится любая система (самолет или модуль искусственного интеллекта для гоночной игры).

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

Например, для хранения координат и выполнения операций над ними можно использовать встроенные типы данных:
int iOldX;
int iOldY;
int cx;
int cy;
//...
int iNexX = iOldX + cx;
int iNewY = iOldY + cy;

А можно создать свои типы данных и выразить те же самые действия иначе:
CPoint pt;
CSize sz;
//...
CPoint pt1 = pt + sz;

Мы видим, что вторая запись компактнее, а, следовательно, идеальнее. Ее компактность обеспечивается не небольшим количеством символов (системный уровень 0), а небольшим количеством слов – названий переменных и операторов (системный уровень 1).

В данном случае, повышение идеальности на уровне 1 привело к небольшому снижению идеальности на уровнях 2 и 3 – нам пришлось добавить классы CPoint и CSize и определить оператор ‘+’ для этих типов данных. Соответственно, мы можем повысить идеальность на этих уровнях, если будем использовать уже готовую библиотеку, где классы CPoint и CSize определены (например, MFC). В этом случае, правда, ухудшится идеальность на уровне 5. Но если библиотека уже была нами использована для каких-то иных целей, то снижение идеальности не произойдет.

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

О чем это говорит? О том, что любое правило нельзя применять бездумно. Нужно четко видеть различные системные уровни и изменения, которые происходят на них в процессе развития или под воздействием правила. Как было написано в статье, отсутствие системного мышления – типовая ошибка разработчиков и причина «глючного» кода. Подозреваю, что по этой причине просьба Заказчика о внесении изменений в Ваш компонент оказалась неожиданной. Потому что Вы оперируете одной системой, одним компонентом, а не классами подобных систем и не классами подобных компонентов.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[9]: О правильных и неправильных классификациях...
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 19.03.06 04:31
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

C>>Все еще уверены, что чем компактнее код — тем он лучше?


КЛ>То, что Вы продемонстрировали, как раз и называется подсистемным мышлением. Судя по приведенному примеру, Вы предполагаете, что программный код – это набор символов. Но это неправильно! Это все равно, что предполагать, будто дом – набор кирпичей или строительных блоков.


КЛ>Так же, как письменная речь не сводится к набору букв, так и программный код – нечто большее, чем набор символов. Код имеет иерархическую структуру, и на каждом уровне этой иерархии в качестве элементов выступают разные абстракции:


КЛ>0. Символы.

КЛ>1. Слова (операторы, переменные, константы, типы данных).
КЛ>2. Функции и функциональные блоки.
КЛ>3. Типы данных, определяемые пользователем.
КЛ>4. Иерархии, группы связанных классов.
КЛ>5. Библиотеки.
КЛ>6. И т.д. – наверняка что-то пропустил.

КЛ>Соответственно, когда я пишу, что хороший код – это компактный код, я отнюдь не имею в виду минимальное количество символов. Ибо хорошо понимаю, что код – это нечто большее, чем просто набор символов, и вижу различные системные уровни.


На самом деле, эта "игра уровнями" проявляется где-то начиная с 2-го по вашей классификации.

КЛ>Как я уже писал, для задания критерия качества кода мне привычнее пользоваться понятием идеальность. Это «тризовский» термин, и суть его заключается в следующем:


КЛ>Идеальная система – эта система, которой нет, а функция ее выполняется.


КЛ>Применительно к программному коду, это правило будет звучать так:


КЛ>Идеальный код – это код, которого нет, а функция его выполняется.


Блин, забавно. Вводится термин, означающий 0 и "бесконечность" одновременно. Я же говорил — Дзенский коан!

Здесь разумнее было бы ввести термин "ТРИЗ-идеальность", а не цеплять общепринятую семантику термина "идеальность". А то так можно договориться до того, что "идеализм"="компактизм", но понимать друг друга сможет только ограниченное количество людей. Общепринятый смысл термина "идеальность", это, всё-таки, приближение к некоей идее, в нашем случае — идее решения некоторой задачи.

КЛ>Понятно, что в реальной жизни ни идеальных технических систем, ни идеального программного кода не существует. Идеальность – это модельное понятие. Это предел, к которому в своем развитии стремится любая система (самолет или модуль искусственного интеллекта для гоночной игры).


Вы противоречите сами себе. Если уж система развивается, а "идеальность" тем выше, чем система меньше, то становится ясно, что система развивается всегда только в одном направлении — к не-идеальности. Возможно вы имеете ввиду, что любая система стремится к бесконечному росту (и это так и есть), но тогда получается, что у вас бесконечноcть и нуль — однои то же. А это абсурд чистой воды!

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


Вот-вот. А с чего вы взяли, что идеальный код — это код, которого нет, а компактность — наиглавнейшее мерило? Всё ваше рассуждение получается лишённым практического смысла — зачем рассуждать о приближении к тому, что воплощено может быть только своим отсутствием? Бесспорно, я понимаю глубину влияния подобных разговоров на слушателя...

Зачастую всё обстоит наборот: компактный, но слабоструктурированный код — это ужас во плоти. А в несколько раз большее по объёму, но при том сильно структурированое решение — вполне себе поддаётся сопровождение и развитию.

На полях замечу, что как бы забавно это ни прозвучало, но вот такой вот "компактный" и, следовательно — "идеальный" код на практике поадает в "идеальные" же условия относительно изменений — его все трогать боятся! Тогда как остальные сегменты корёжат в хвост и в гриву, для сведения к идеальности, надо думать...

Обычно понятийную модель программы пытаются привести возможно ближе к понятийной базе задачи, а отнюдь не к абстрактной идеальности. То бишь, если мы рассуждаем об "идеальности" заведомо существуещего предмета (программа-то существует!), то можно говорить только об идеальности (sic!) противоречий с постановкой задачи. Например, "хорошая" программа в части моделирования, скажем, отары овец не заставит думать о том, что овцу нужно вынуть из хипа, потом сбросить на диск и т.п. И не потребует всегда сначала создать двух серых овец. То есть, влияние технологической базы на связь элементов модели предметной области и связанные с этим противоречия будут минимальными. Самая же хорошая в мире программа будет обладать "идеальными" противоречиями с решаемой задачей. То есть, не будет противоречить постановке задачи вообще.

Но вернёмся к нашим компактно-идеальным баранам. Собственно, вместо употребляемого вами термина "идеальность", инверсного к существованию, для отражения той же меры вещей есть нормальное программистское понятие: метрика программы. Начиная от простейшей — объём в килобайтах и заканчивая навороченными, которые рассчитываются по весьма непростым формулам на основании довольно сложного анализа. И здесь сразу обнаруживается, что сами по себе метрики — очень спорная вещь. Что лишний раз подтверждает спорность предложенного вами критерия "идеальности".

КЛ>Например, для хранения координат и выполнения операций над ними можно использовать встроенные типы данных:

КЛ>
КЛ>int iOldX;
КЛ>int iOldY;
КЛ>int cx;
КЛ>int cy;
КЛ>//...
КЛ>int iNexX = iOldX + cx;
КЛ>int iNewY = iOldY + cy;
КЛ>

КЛ>А можно создать свои типы данных и выразить те же самые действия иначе:
КЛ>
КЛ>CPoint pt;
КЛ>CSize sz;
КЛ>//...
КЛ>CPoint pt1 = pt + sz;
КЛ>

КЛ>Мы видим, что вторая запись компактнее, а, следовательно, идеальнее. Ее компактность обеспечивается не небольшим количеством символов (системный уровень 0), а небольшим количеством слов – названий переменных и операторов (системный уровень 1).

Да-да, здесь понятийная модель программы подводится к модели понятий геометрии, где мы оперируем такими терминами, как "точка", "размер", "расстояние" и т.п. Кстати, подводится довольно спорно: что получится от сложения точки с размером? Квадрат? Круг? Новая точка? Ну да ладно уж.

КЛ>В данном случае, повышение идеальности на уровне 1 привело к небольшому снижению идеальности на уровнях 2 и 3 – нам пришлось добавить классы CPoint и CSize и определить оператор ‘+’ для этих типов данных. Соответственно, мы можем повысить идеальность на этих уровнях, если будем использовать уже готовую библиотеку, где классы CPoint и CSize определены (например, MFC). В этом случае, правда, ухудшится идеальность на уровне 5. Но если библиотека уже была нами использована для каких-то иных целей, то снижение идеальности не произойдет.


Правильно. За всё приходится платить усложнением системы. Но за счёт этого система начинает решать всё более широкий круг задач. Например, решается задача организации взаимодействия человека с программой в терминах геометрии, а не машинных кодов.

КЛ>Возвращаясь к приведенному Вами коду, можно сказать, что он некомпактен и уж, тем более, не идеален. Не смотря на то, что количество символов небольшое, количество разных сущностей велико.


И снова — нехорошо смешивать калий с водой, бабахнуть может. Зачем здесь упоминать про "идеальность"?

КЛ>О чем это говорит? О том, что любое правило нельзя применять бездумно. Нужно четко видеть различные системные уровни и изменения, которые происходят на них в процессе развития или под воздействием правила. Как было написано в статье, отсутствие системного мышления – типовая ошибка разработчиков и причина «глючного» кода. Подозреваю, что по этой причине просьба Заказчика о внесении изменений в Ваш компонент оказалась неожиданной. Потому что Вы оперируете одной системой, одним компонентом, а не классами подобных систем и не классами подобных компонентов.


Парадоксально, но факт. Проще всего в систему вводятся те изменения, возникновение которых было заподозрено разработчиками заранее, т.е., система была готова к такому повороту событий, поскольку эти изменения уже существовали в головах разработчиков! Уже существовали! Впрочем, в терминологии Дз..., тьфу, ТРИЗ, с системой одновременно происходит бесконечное множество идеальных изменений — ничего не меняется.

Мне вполне понятно ваше желание применить идеи ТРИЗ к программированию, только вы неправильно выбрали цель. Поверьте, попытка решить какаую-то подзадачу "идеально", т.е., за счёт использования, например, каких-то побочных эффектов уже имеющихся функций (модулей, классов, бибилотек...) может привести к очень неприятным последствиям.

А вообще ваша позиция, будучи выражена терминами, инверсными по отношению к существованию, по сути — совершенно бесспорна. Ну разме можно спорить с абсолютом? А с бесконечностью? А с нулём?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[18]: О правильных и неправильных классификациях...
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 19.03.06 04:46
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Проблема 1:

К>- хочется представлять задачи как можно проще (например, прозревать в них единственный паттерн "противоречие")

Двойка тебе, Кодт. Будь я тризовцем — разнёс бы тебя только за попытку сопоставить прямую и инверсную интерпретацию задачи. Паттерн — существует сам по себе. Противоречие — возможно только между чем-то и чем-то, т.е., с паттерном не может даже и сопоставляться. Ну, блин, представь себе хлопок одной ладони!

Ну, или ещё проще — задача vs. решение.

К>- хочется представлять задачи как можно гибче и детальнее (прозревая разные паттерны, наиболее подходящие по месту)


К>Проблема 2:

К>- хочется грокнуть ТРИЗ

Сутра 14-го патриарха тут поможет.

К>- не хочется тратить время на гроканье ненужных вещей


К>Из этого следует, что паттерн "противоречие" (а значит, и методология работы с ним) никуда из природы не девается, и ему есть ненулевое место. Какое именно?


Вот-вот. Это и есть место хлопка одной ладони.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[9]: О правильных и неправильных классификациях...
От: Cyberax Марс  
Дата: 19.03.06 10:57
Оценка:
Кирилл Лебедев wrote:
> То, что Вы продемонстрировали, как раз и называется *подсистемным
> мышлением*. Судя по приведенному примеру, Вы предполагаете, что
> программный код – это *набор символов*.
Да. Програмный код — это набор символов. Если спуститься на уровень ниже
— это набор байт.

Если подняться выше, то программный код — это запись AST данного языка.
Во внутренностях компилятора код — это запись T-SSA (Single Static
Assignment Tree). И т.п.

> Но это неправильно!

Почему?

> Это все равно, что предполагать, будто дом – *набор кирпичей* или *строительных

> блоков*.
А у нас дома из воздуха строятся? Я почему-то всегда думал, что из
кирпича/бетона/...

> Код имеет иерархическую

> структуру, и на каждом уровне этой иерархии в качестве элементов
> выступают разные абстракции:
Ничего код не имеет. Это мы можем _интерпретировать_ код как
иерархическую систему.

В общем, "hierarchy is in the eye of the beholder"

То что для вас является красивой иерархией — мне кажется спутанным
набором блоков, который рухнет если попытаться добавить слой.

> Соответственно, когда я пишу, что хороший код – это *компактный код*, я

> отнюдь не имею в виду минимальное количество символов. Ибо хорошо
> понимаю, что код – это *нечто большее*, чем просто набор символов, и
> вижу различные системные уровни.
Прекрасно. Что лучше: "v~=s/aa/bb/g;" или
std::string res;
for(std::string::const_iterator f=str.begin();f!=str.end();++f)
{
    if (str.compare("aa",f,2)==0)
    {
        res+="bb";
        f+=2;
    }
    else
        res+=*f;
}

?

> /Идеальная система – эта система, которой нет, а функция ее выполняется./

> Применительно к программному коду, это правило будет звучать так:
> /Идеальный код – это код, которого нет, а функция его выполняется./
Вот это и совершенно не подходит для программных систем.

"Компактный код" (в смысле размера или концентрации идей на квадратный
килобайт) может быть абсолютно непригодным к использованию по причине
нерасширяемости и/или неподдерживаемости в ряде случаев.

Так что думайте дальше над формулировкой идеальности.

> Мы видим, что вторая запись *компактнее*, а, следовательно, *идеальнее*.

> Ее компактность обеспечивается не небольшим количеством символов
> (системный уровень 0), а небольшим количеством слов – названий
> переменных и операторов (системный уровень 1).
Не пойдет.

> Возвращаясь к приведенному Вами коду, можно сказать, что он некомпактен

> и уж, тем более, не идеален. Не смотря на то, что количество символов
> небольшое, количество разных сущностей велико.
Попробуйте лучше переписать. Приведенный код является победителем
International Obfuscated Perl Contest, а значит очень близок к идеалу
этого конкурса — абсолютно непонятная программа на языке Perl, но
делающая интересные осмысленые действия.

Их идеал не совпадает с вашим? Что же, очень жаль....
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[17]: О правильных и неправильных классификациях...
От: Cyberax Марс  
Дата: 19.03.06 11:48
Оценка:
Andrei N.Sobchuck wrote:
> Хе-хе. Вот нет в Java оператора "super super" для доступа к методу не
> родителя, а дедушки и попробуй это нарушить. А вопрос, как это сделать,
> я видел и в ru.java и на rsdn.
Просто решили не делать, так как нечасто требуется. Никаких
фундаментальных запретов для super.super нет.

> Или требование типа "должна отработать быстрее чем за N времени".

На какой машине?

> With class-based encapsulation mechanism, the only way to ensure this is

> to make the reference to the /submorphs/ secret and never pass it out of
> the parent morph. Unfortunately, this *conflicts (выделение моё)* with
> the need of some of Morph’s clients to use the protocol provided in
> Collection to enumerate the submorphs.
Вопрос такой: а зачем нужно реализовывать протокол коллекций?

> первые два — не законы физики, конечно, но там дальше эти ограничения

> конкретизированы. А последнее требование — очень и очень строгое.
> Ы?
Обычная ситуация — противоречие показывает, что у нас неправильная
архитектура (требуется доступ к приватным данным) или на недостаточность
архитектуры.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[8]: О правильных и неправильных классификациях...
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 19.03.06 14:10
Оценка:
Здравствуйте, Кодт,

1. Умение использовать для постановки и решения задач различные модели, разумеется, благо. И паттерны – хорошая модель, потому что она проста. Эта модель доступна даже студенту. Или, скажем так, она гораздо доступнее, чем системное мышление или идеальность. Это – как приемы в ТРИЗ, которые всем доступны и всем понятны. Поэтому большинство людей и пользуются ими.

2. Казалось бы, раз приемы (паттерны) доступнее и понятнее, то нужно выявить как можно больше приемов, и, благодаря этому, получить возможность решать все новые и новые классы задач. Однако практика показалась тупиковость такого подхода. Скажем так, существует ограничения на качественный уровень задач, которые можно решить при помощи приемов. Поэтому в ТРИЗ и появились другие инструменты: стандарты, физические противоречия, физэффекты и т.п. Соответственно, и в нашем случае основная цель – это не переоткрыть паттерны, а создать инструментарий более высокого класса, который бы позволял решать более сложные и менее очевидные задачи.

3. Разумеется, более сложный инструментарий предъявляет и более высокие требования к квалификации того, кто им будет пользоваться. Конечно, проблему с датчиками можно устранить паттерном “Visitor” или двойной диспетчеризацией. Но лучше вообще так не проектировать. В ряде случаев паттерны выступают в роли «заплатки», которая закрывает архитектурные «глюки».

Соответственно, выгоднее не нашивать «заплатки», а проектировать качественно и безглючно с самого начала. А это требует повышенной квалификации, т.к. нужно думать и напрягаться.

Качественная архитектура должна быть расширяемой. Это означает, что разработчик должен спрогнозировать возможные направления развития системы. Для этого он должен не смотреть на систему в одиночестве (саму по себе), а желательно посмотреть на систему в контексте. Т.е. должен видеть и систему, и надсистему, и отдельные подсистемы. Желательно, еще и в развитии. Здесь мы вплотную подступаем к системному мышлению. А это – не такая уж простая штука, и простым набором паттернов здесь не обойдешься.

4. Все выше изложенное свидетельствует о том, что дискуссия вызвана не только и не столько разницей инструментария (паттерны, ТРИЗ), но и разницей в квалификациях. Можно, например, до посинения спорить, что трубка курительная и «трубка» телефонная суть разные вещи, и не понимать, что данное различие обусловлено избранным критерием – функцией системы или технологическими «наворотами». Те же самые предметы, но в иной системе отсчета, могут быть однородными, т.к. функциональные или технологические различия в ней не важны. В качестве примера такой системы я уже приводил опись имущества, принадлежащего конкретному человеку.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[10]: О правильных и неправильных классификациях...
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 19.03.06 14:15
Оценка: +1
Здравствуйте, Геннадий Васильев,

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

ГВ> Общепринятый смысл термина "идеальность", это, всё-таки, приближение к некоей идее, в нашем случае — идее решения некоторой задачи.


Процитирую еще раз определение идеальности, выделив пропущенные Вами места:

Идеальная система – это система, которой нет, а функция ее выполняется.

В данном случае функция как раз и есть та идея, к которой, в своем развитии, стремится система. И реализация этой функции (идеи, если Вам близок платонизм) тем ближе к идеалу, чем меньше ресурсов потрачено на ее (идеи) реализацию.

ГВ>Вы противоречите сами себе. Если уж система развивается, а "идеальность" тем выше, чем система меньше, то становится ясно, что система развивается всегда только в одном направлении — к не-идеальности.


Это не я противоречу сам себе, а Вы уподобляетесь схоласту, который, имея пару посылок, строит силлогизм и пытается, таким образом, вывести (дедуктивно) законы всего сущего. Или, наоборот, построить чисто формальное опровержение, основываясь на все тех же силлогизмах.

Но схоластика потерпела фиаско на рубеже 16 – 17 веков. С наиболее аргументированной критикой такого подхода выступил Фрэнсис Бэкон в своей работе «Новый Органон».

Оставаясь в рамках формальной логики, Вы вряд ли сможете постигнуть законы развития технических систем, как, собственно говоря, и любые другие законы, например, Закон Всемирного Тяготения или Второй Закон Ньютона, т.к. эти законы формально (при помощи силлогизмов) не выводятся.

Соответственно, для того чтобы понять, как происходит идеализация технических систем, нужно прекрасно понимать, что система состоит из разных системных уровней. И повышение идеальности на одном системном уровне может привести к снижению (часто незначительному) на другом системном уровне.

Еще удобнее рассматривать системы в развитии. Например, современный автомобиль гораздо идеальнее своего первого прототипа, т.к. ездит быстрее, а топливо жрет меньше. Т.е. выполняет функцию лучше, а ресурсов тратит меньше.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[9]: О правильных и неправильных классификациях...
От: Cyberax Марс  
Дата: 19.03.06 14:41
Оценка:
Кирилл Лебедев wrote:
> 1. Умение использовать для постановки и решения задач *различные
> модели*, разумеется, *благо*. И паттерны – хорошая модель, потому что
> она *проста*. Эта модель доступна даже студенту. Или, скажем так, она
> гораздо доступнее, чем *системное мышление* или *идеальность*.
Идеальности в программировании нет. Точнее, она относительная.

> 2. Казалось бы, раз приемы (паттерны) доступнее и понятнее, то нужно

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

> Качественная архитектура должна быть расширяемой. Это означает, что

> разработчик должен спрогнозировать возможные направления развития
> системы.
Сразу все возможные направления? Не подскажете, случайно, как это сделать?
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[11]: О правильных и неправильных классификациях...
От: Cyberax Марс  
Дата: 19.03.06 14:46
Оценка:
Кирилл Лебедев wrote:
> Это не я противоречу сам себе, а Вы уподобляетесь схоласту, который,
> имея пару посылок, строит силлогизм и пытается, таким образом, вывести
> (дедуктивно) законы всего сущего. Или, наоборот, построить чисто
> формальное опровержение, основываясь на все тех же силлогизмах.
Вам показали на противоречие в ваших собственных высказываниях.
Силлогизмы просто его упрощают для понимая.

С вашей стороны идет софистика.

> Соответственно, для того чтобы понять, как происходит идеализация

> технических систем, нужно прекрасно понимать, что система состоит из
> разных системных уровней. И повышение идеальности на одном системном
> уровне может привести к снижению (часто незначительному) на другом
> системном уровне.
Для развития системы нужно добавлять новую функциональность, а это в
любом случае уменьшает "идеальность".

> Еще удобнее рассматривать системы в развитии. Например, современный

> автомобиль гораздо идеальнее своего первого прототипа, т.к. ездит
> быстрее, а топливо жрет меньше. Т.е. выполняет функцию лучше, а ресурсов
> тратит меньше.
А вот стоимость производства "классики" и нового BMW различается на
порядок. Так что с этой точки зрения модель 70-х гораздо идеальньее
нового BMW.

По соотношению цена/качество новые (более совершенные технически) машины
тоже могут проигрывать подержаным.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[10]: О правильных и неправильных классификациях...
От: AVC Россия  
Дата: 19.03.06 14:58
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> Качественная архитектура должна быть расширяемой. Это означает, что

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

В принципе (на деталях не настаиваю) — как в Обероне.
В основе минимальный набор основных модулей.
Система расширяется добавлением новых модулей поверх предыдущих.
Возможна критика обероновского подхода в деталях, но сама идея, IMHO, превосходна.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.