OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 04:03
Оценка: 12 (4) +3 :))) :)
Многоуважаемый ALL!

Пишет тебе старый твой поклонник, скромный труженик клавиатуры, канаццкий программист Борис.

Вот уже много лет я являюсь тайным поклонником функционального программирования (FP). Чего-то там писал, чего-то там изучал, проникался. Наконец, решился написать в (максимально) функциональном стиле некую систему Х нетривиальной сложности.

Подновил свои знания в области Clojure, прикинул что и как можно сделать, из каких компонент система Х будет состоять. Мысленно сказал себе: "ну, давай, Доббс, действуй!".... и впал в кому.

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

Суть паралича в данном конкретном случае была в следующем:
1) Пациент хорошо владеет OOD (Object Oriented Design) и прекрасно представляет себе как спроектировать упомянутую систему Х используя ОО подход. Может разрисовать диаграммы сколь угодно глубокой детализации начиная от диаграмм классов и заканчивая sequence диаграммами.
2) Пациент имеет смутное представление о функциональном дизайне (SA/SD), а также помнит что данный способ разбиения систем на запчасти был признан убогим еще до его (пациента) рождения.
3) Пациент в состоянии пойти на компромисс с совестью и спроектировать систему Х крупноблочно в OOD стиле, а затем (закрыв глаза и очертя голову) реализовать каждую компоненту в функциональном стиле. Однако, такой подход кажется пациенту крайне неестественным. К тому же некоторые компоненты (в частности, компонента, реализующя persistence layer) настолько stateful что пациенту просто страшно представить как они будут выглядеть при чисто функциональном подходе. Уж лучше сразу махнуть рукой и сделать ОО компоненту чем так корячить FP.

Всвязи с этим пациенту требуется срочная госпитализация и помощь опытного хирурга по следующим главным направлениям:

4) У пациента складываетя прочное мнение что FP хорошо на микроуровне, там где модель поведения программы тривиальна либо заранее известна.
5) У пациента возникает ощущение что на глобальном архитектурном уровне FP не может решить его, пациента, проблем, а лишь добавит ему, пациенту, головной боли из-за попыток симулировать OOP на FP языке (да, дайте пациенту замыкания и он в три счета сделает вам из них ООП, но смысл?)
6) Пациент все больше разуверивается в FP как в парадигме, позволяющей ему, пациенту противостоять неизбежным изменениям в архитектуре, модели поведения, модели данных.
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 08:03
Оценка: 74 (9) :)
Здравствуйте, borisman3, Вы писали:

B>Вот уже много лет я являюсь тайным поклонником функционального программирования (FP). Чего-то там писал, чего-то там изучал, проникался. Наконец, решился написать в (максимально) функциональном стиле некую систему Х нетривиальной сложности.

B>Подновил свои знания в области Clojure, прикинул что и как можно сделать, из каких компонент система Х будет состоять. Мысленно сказал себе: "ну, давай, Доббс, действуй!".... и впал в кому.

Сразу — динамически типизированные языки требуют бОльших телодвижений при создании "систем нетривиальной сложности". Как минимум, необходимость писать огромное количество тестов. А в случае быстрого мутирования данных, о котором ты пишешь в следующем комментарии, так и вообще требуют особой внимательности.

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

Далее, для правильных систем типов работает т.н. Curry-Howard Isomorphism. А это значит помимо уверенности в том, что функция делает то, что заявляет в типе, что используя доказательства, мы часто можем код выводить сами из типа.

Подобные системы типов позволяют сильно ограничивать типы (читай — выражать больше, чем обычные типы). Это ведёт к таким интересным и полезным вещам, как
1. Parametricity. Схожий тип -> схожая семантика. Подробнее тут. Важные следствия — да и просто красиво рассказано — в знаменитой статье Theorems for free. deniok про это много писал и делал доклад на spbhug.
2. Значительная уверенность в проведённом equational reasoning, вызванная лёгкостью
Автор: lomeo
Дата: 19.06.07
его использования. Простота рефакторинга. Читаем классику. (и не надо в сотый раз мне говорить про перевёрнутые страницы! переверните в своём вьювере обратно.)

Дальше — больше. Читаем зависимые типы. Ссылок не дам, кажется, что ещё рано.

B>2) Пациент имеет смутное представление о функциональном дизайне (SA/SD), а также помнит что данный способ разбиения систем на запчасти был признан убогим еще до его (пациента) рождения.


Я не буду здесь вдаваться в споры. Просто приведу ссылки.

Semantic Design
Typeclass morphism. Там же статью можно найти с примерами.
adept показывает как писать программы.
Замечательный пример дизайна.

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

Второе, чистота и ленивость — единственно верный ФП Иначе от ФП мы просто получаем огрызки, сокращающие код (замыкания, паттерн матчинг), но важнейшие его преимущества остаются за бортом. Помимо перечисленного, ленивость ведёт к большей модульности
Автор: lomeo
Дата: 29.10.10
. Да и вообще нормальный порядок вычислений вычисляет выражение, если оно может быть вычисленно, всегда.

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

B>3) Пациент в состоянии пойти на компромисс с совестью и спроектировать систему Х крупноблочно в OOD стиле, а затем (закрыв глаза и очертя голову) реализовать каждую компоненту в функциональном стиле. Однако, такой подход кажется пациенту крайне неестественным. К тому же некоторые компоненты (в частности, компонента, реализующя persistence layer) настолько stateful что пациенту просто страшно представить как они будут выглядеть при чисто функциональном подходе. Уж лучше сразу махнуть рукой и сделать ОО компоненту чем так корячить FP.


Смешанный стиль (крупные абстракции — ОО, реализация методов — ФП) не даст тебе особых преимуществ, ну кроме как код сократит. Есть в Java, скажем Runnable или там Comparator — по сути замыкания. Кода чуть больше и только. В C# так и кода меньше. Паттерн-матчинг — вещь, конечно, удобная, но помогает тоже только на низком уровне. Да и детали открывает часто больше чем надо, правда, тут есть неплохие решения.

B>4) У пациента складываетя прочное мнение что FP хорошо на микроуровне, там где модель поведения программы тривиальна либо заранее известна.


Это не настоящий ФП, так, сахар.

B>5) У пациента возникает ощущение что на глобальном архитектурном уровне FP не может решить его, пациента, проблем, а лишь добавит ему, пациенту, головной боли из-за попыток симулировать OOP на FP языке (да, дайте пациенту замыкания и он в три счета сделает вам из них ООП, но смысл?)


У ОО свои проблемы. Самая главная — каждый его понимает как хочет. ОО сложнее, он менее формализован, чем ФП (см. мучения Луки Карделли). Все прочие проблемы вытекают из этого.

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


И снова я! "ленивость -> модульность -> проще делать изменения". Или вот "чистота и типы -> equational reasoning -> проще делать изменения". Ну и конечно "строгая типизация -> компилятор покажет места, где сломалось -> проще делать изменения".
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Mr.Cat  
Дата: 17.11.10 10:04
Оценка: 13 (3) +2
Мне понравилось, как Армстронг изложил подход к программированию (на Эрланге) в своей диссертации: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.408 . Вкратце:
— Отделяем функциональные требования от нефункциональных (ну и вообще разделяем все ортогональные требования).
— Функциональные требования реализуем в чистом функциональном стиле, преимущественно в виде автоматов, попутно содомируя себя тайпчекером.
— Максимум нефункциональных требований реализуем декларативно, с использованием встроенных возможностей OTP: применяем к автоматам поведения, строим иерархию супервизоров и кладем все это в "приложения" и "релизы".
— Если припрет, пишем свои поведения с применением максимального количества грязных хаков и оптимизаций. Покрываем тестами.
— Армстронг еще говорил что-то насчет интеграционного тестирования, но я пока не готов от себя пересказать его мысль — лучше прочитать оригинал.

Если вернуться к проектированию, то в таком сценарии вся функциональщина действительно отправляется на самое дно — на уровень деталей реализации. Остальная часть системы, по-моему, вполне может уложиться в твое видение ООП.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: IT Россия linq2db.com
Дата: 17.11.10 16:17
Оценка: +5
Здравствуйте, borisman3, Вы писали:

IT>>Именно. FP рулит внутри метода, ООП — вне.

B>А как же все заверения адептов что FP мол надо широко применять как отдельную (от ООП) парадигму ?

Заявлять можно что угодно, никто этого не запрещает. Только какой смысл отказываться от бенефитов которые даёт ООП. Так же нет смысла отказываться от бенефитов ФП. Тем более, что они между собой никак не конфликтуют и великолепно уживаются вместе.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 21:44
Оценка: 21 (2) +2
Здравствуйте, borisman3, Вы писали:

B>Мне главное понять КАК я должен строить АРХИТЕКТУРУ функциональных приложений и возможно ли это в принципе. Пока что (почитав примеры дизайна из Ваших ссылок) я вижу что для построения крупномасштабной архитектуры функциональщики вынуждены бить систему на модули с внутренним состоянием и передавать абстрактные типы данных. Все это очень хорошо, но это типичный OOD подход. Как он кореллирует с FP — я без понятия.


Первое, выделенное неверно. АТД и модули с состоянием — вещи известные задолго до появления ООП. Следовательно, это не только OOD-подход.
Второе, АТД и модули с состоянием — в ФП просто делаются по другому. Опять — это не только OOD-подход.
Третье, как именно можно построить ФП-дизайн — я пишу. Если что-то неясно — задавайте вопросы, обсудим.

Постараюсь ответить на последнее предложение. АТД выражается набором операций, для которых должна соблюдаться определённая семантика.

Простой пример. Абстрактный тип данных `Eq a` должен, скажем, поддерживать две операции — == и /=. Дополнительно, a == b означает, что a /= b — ложно и наоборот. Другой часто приводимый пример — стек. pop (push x stack) == (x, stack) — это должно соблюдаться для любого конкретного типа, представляющего АТД стек.

Дальше — модули с изменяемым состоянием. Функции a -> a, state-монада, continuation — вот три рабочих примера чистого ФП-стиля. Не OOD. Во многих языках можно просто наплевать и оставить грязь, изолировав её в отдельные модуля.

Надеюсь я ответил на вопрос о корреляции с FP.

Кстати, рекомендую — http://fprog.ru/2009/issue1/eugene-kirpichov-fighting-mutable-state/
Re[35]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 12:50
Оценка: 8 (2) +1
Здравствуйте, samius, Вы писали:

S>Здравствуйте, DarkGray, Вы писали:


S>>>Если объект можно изменить во внешнем коде через один из интерфейсов, то он не является иммутабельным.


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

S>Википедию писали фанатики?
S>

S>In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.

DarkGray, Undying! Приношу извинения , был неправ в отношении абсолютности свойства иммутабельности. Там так же написано:

An object can be either entirely immutable or some attributes in the object may be declared immutable; for example, using the const member data attribute in the C++ programming language. In some cases, an object is considered immutable even if some internally used attributes change but the object's state appears to be unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object. The initial state of an immutable object is usually set at its inception, but can also be set before actual use of the object.

Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.11.10 09:02
Оценка: 1 (1) +2
Здравствуйте, lomeo, Вы писали:

L>И снова я! "ленивость -> модульность -> проще делать изменения". Или вот "чистота и типы -> equational reasoning -> проще делать изменения". Ну и конечно "строгая типизация -> компилятор покажет места, где сломалось -> проще делать изменения".


Почти любая крупная состоит из нескольких частей:
1)UI может быть stateless (Web) или stateful (desktop), может быть interactive (консоль, веб) или reactive (формочки) или смесь.
2)Хранилище данных — файлы, бд (SQL), еще ченить
3)"Бизнес логика" — то что занимается преобразованием данных между UI и хранилищем
4)Application services — компоненты, не занимающиеся непосредственно данными, например отправка почты
5)Механизм увязывания всего этого межу собой, желательно чтобы можно было менять конфигурацию и состав компонент без пересборки приложения

То что я видел в примерах на haskell, это слабоинтерактивное (консольное) приложение со stateless бизнес-логикой.
Хотелось бы увидеть всетаки приложение на haskell, которое имеет как минимум все части, указанные выше, о чтобы весь код не был завернут в IO.

Хотябы один пример какой-нить записной книжки с двумя таблицами в БД и формочкой.
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 09:17
Оценка: +2 -1
Здравствуйте, borisman3, Вы писали:

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


Посмотри тут http://rsdn.ru/forum/decl/2720396.flat.aspx
Автор: Gaperton
Дата: 06.11.07
неплохой пример ФП дизайна на Эрланге.
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gbear Россия  
Дата: 18.11.10 06:06
Оценка: 17 (2)
Здравствуйте, borisman3, Вы писали:

B>1) Пациент хорошо владеет OOD (Object Oriented Design) и прекрасно представляет себе как спроектировать упомянутую систему Х используя ОО подход. Может разрисовать диаграммы сколь угодно глубокой детализации начиная от диаграмм классов и заканчивая sequence диаграммами.


Волею случая попал в похожую ситуацию где-то с год назад... перешел на проект, который пишется на Эрланге. Проект, мягко говоря, не маленький.
Тут же выяснилось, что _дизайна_ системы как такового не существует. Ну т.е. есть некоторый набор артефактов в виде "картинок" и "текста" который как-то поясняет "идею" системы. Но это все на уровне "три квадратика, две стрелочки".
Сказать что я был в шоке — не сказать ничего. А проект, повторюсь, именно что "нетривиальной сложности".

B>3) Пациент в состоянии пойти на компромисс с совестью и спроектировать систему Х крупноблочно в OOD стиле, а затем (закрыв глаза и очертя голову) реализовать каждую компоненту в функциональном стиле. Однако, такой подход кажется пациенту крайне неестественным. К тому же некоторые компоненты (в частности, компонента, реализующя persistence layer) настолько stateful что пациенту просто страшно представить как они будут выглядеть при чисто функциональном подходе. Уж лучше сразу махнуть рукой и сделать ОО компоненту чем так корячить FP.


Поиски какого-то специализированного инструмента для _проектирования_ или хотя бы сложившейся нотации не дали вообще ничего! Такое ощущение что этого нет вообще.

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

B>4) У пациента складываетя прочное мнение что FP хорошо на микроуровне, там где модель поведения программы тривиальна либо заранее известна.


Оно конечно так. В смысле, на микроуровне FP — действительно хорош . Проблема-то в том, что, как показывает мой опыт, если на макроуровне не закладываться на то, что на микроуровне у вас будет FP — ты получаешь такой макроуровень к которому FP, хорошо если таки хоть "прибивается"... со всеми вытекающими. Мой опыт, он конечно не показателен... т.к. ограничен и по времени (чуть больше года) и по инструменту (Эрланг)... но результат действительно гораздо лучше если проектируешь "специально под" Эрланг.

B>5) У пациента возникает ощущение что на глобальном архитектурном уровне FP не может решить его, пациента, проблем, а лишь добавит ему, пациенту, головной боли из-за попыток симулировать OOP на FP языке (да, дайте пациенту замыкания и он в три счета сделает вам из них ООП, но смысл?)


Тут как бы дело такое... "симулировать OOP на FP языке" — в смысле, добиваться однозначного соответствия между сущностями одной парадигмы, сущностям другой — смысла особого нет. Просто аналога OOD в FP в данный исторический момент вроде как не наблюдается (я плохо искал?). Но фундаментальный принципы дизайна — они фундаментальны жеж Просто как во времена оны приходится несколько извращаться, пытаясь формализовать идеи мыслимые в одной парадигме, инструментами "заточенными" под другую. Т.е. как бы "язык" уже есть, а "письменность" еще не изобрели

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


Та не... я вот за год не разуверился. Инструментов вот подходящих нет — это да
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 13:45
Оценка: 1 (1) +1
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, borisman3, Вы писали:


CS>Посыл не верный изначально. Причем еще на уровне противопоставления OOP и FP.


CS>Твое сообщение но как бэ другими словами:

CS>

CS>Люди, я аццкий специалист в области изготовления мебели стамесками.
CS>Но вот увидел в Канадской Шине еще рубанки. И появилось у меня желание сделать мебельный
CS>гарнитур X (большой) сугубо рубанком. Но что-то меня берут сомнения вырезания пазов оным инстрУментом.
CS>Я в отчаянии. Или у вас таки будет бальзам для меня или получается фигня этот ваш рубанок.


Все ПОЧТИ так как Вы описали. Только почему Вы воспринимаете все так негативно ? Ну умеет человек изготавливать мебель стаместками. Ну хочет попробовать рубанок. Ну объясните ему куда ему не следует совать руки.

И вообще, если можно — по существу. Вопрос был все таки не "Как мне писать функциональные программы ?". Вопрос (упрощенно) был : "Как мне создавать архитектуру функциональных программ ?"
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: IT Россия linq2db.com
Дата: 17.11.10 15:19
Оценка: 1 (1) +1
Здравствуйте, borisman3, Вы писали:

B>4) У пациента складываетя прочное мнение что FP хорошо на микроуровне, там где модель поведения программы тривиальна либо заранее известна.


Именно. FP рулит внутри метода, ООП — вне.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Mr.Cat  
Дата: 17.11.10 10:15
Оценка: +1 :)
Здравствуйте, lomeo, Вы писали:
L>Сразу — динамически типизированные языки требуют бОльших телодвижений при создании "систем нетривиальной сложности".
Существует мнение, что единственный ФЯ, на котором создана система нетривиальной сложности — это эрланг. Полностью с ним соглашаться, наверное, не стоит: тогда пришлось бы признать, например, ghc, тривиальной системой и попутно нагенерить с десяток страниц в КСВ. Но принять во внимание, наверное, стоило бы.
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 14:08
Оценка: +2
Вы уж простите, товарищ lomeo, что я выскажусь несколько огульно, но у меня складывается впечатление (очень надеюсь что ошибочное) что когда FP-программистам задаешь вопрос о крупномасштабной архитектуре (presentation tier + buisenss logic tier + integration/persistence tier + resource tier) они вместо прямого ответа начинают песню либо о типах, либо о монадах, т.е. о достаточно мелких детялях. Вас просили показать пример законченного многозвенного приложения выполненного в функциональном стиле, ну или хотя бы проектную документацию из который было бы ясно как построить такое приложение. А Вы нам про монады, уж извините.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: IT Россия linq2db.com
Дата: 17.11.10 17:50
Оценка: +2
Здравствуйте, borisman3, Вы писали:

B>Микшировать ООП и FP это тоже конечно жизнеенный подход, но хотелось как раз pure fp.


Зачем? Может проще относиться и к ООП и к ФП как к набору паттернов и практик, а не как к основам вселенского мироздания? Тогда не придётся впихивать невпихиваемое в невпихуемое. Просто берём наиболее подходящий инструмент для конкретного случая и используем.

Кстати, в ФП есть множество фишек вообще не имеющих отношения к функциям высшего порядка. Например, паттерн-матчинг, квази-цитирование, алгебраические типы, вывод типов, туплы. Да даже замыкания по большому счёту имеют весьма опосредованное отношение к ФВП. Всё этом можно и нужно использовать в приложениях неважно каким образом в них реализуется, например, компонентность, с помощью ФП или ООП.

В общем, забей Используй ФП там где оно даёт эффект тебе лично, а не там где про него рассказывают умные дядьки.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Что-то вроде заключения
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 17:43
Оценка: +2
Большое спасибо всем за проявленный интерес и обсуждение темы.

Хотелось бы выразить благодарность lomeo и FR за неустанные попытки отстоять функциональное программирование и вразумить больного на голову топикстартера .

Отдельное спасибо gbear за то что поделился рилворлдным опытом.

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

1) Используем OOD для разбиения системы на большие куски.
2) По возможности выделяем состояние в отдельные модули. При необходимости даже делим модуль пополам на два модуля. Первый содержит функции, второй — состояние.
3) Описываем контракты между частями системы в виде Java интерфейсов. Это, к сожалению, существенно лимитирует возможности языков реализации, особенно функциональных языков, но Java-интерфейсы в качестве контрактов были выбраны как lowest common denominator который поддерживается в том или ином виде всеми языками работающими на JVM.
3) Реализуем контракт внутри модуля на любом удобном для нас языке используюя любую удобную для нас парадигму.
4) ... PROFIT!

Если у кого-то есть комментарии к описанной схеме, с радостью выслушаю.
Re[15]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 18:13
Оценка: +1 :)
Здравствуйте, Sinix, Вы писали:

U>>В чем смысл const? Смысл reandonly в том, что показать, что ссылка на переменную не изменялась с момента создания экземпляра класса. Как я понимаю смысл const в том, чтобы показать что ссылка на переменную не менялась с момента компиляции. Объясни чем readonly static для этой цели хуже, чем const?


S>Забей. Пятница, вечер (по крайней мере у меня) Не лениво препираться по мелочам?


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

А если серьезно, то разницу между const и readonly static действительно мелочь, а вот сам принцип минимума сеттеров, равно как и более общий принцип бритвы Оккама позволяет кардинально повысить качество кода.
Re[59]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 15:00
Оценка: -1 :)
Здравствуйте, DarkGray, Вы писали:

DG>и да — какой оклад данному человеку стоит положить (например, для Москвы)?


Не знаю. Ты что ли пучок равшанов хочешь набрать вместо пары нормальных специалистов?
Re[62]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 30.11.10 05:51
Оценка: +2
Здравствуйте, DarkGray, Вы писали:

DG>откуда следует что для каждого алгоритма с техникой переиспользования памяти есть в инете его аналог без данной техники?


Из равной мощности языков. Из того, что задачи на таких языках решаются, а языки не заявляются как менее мощные.
Мало того я ранее давал тебе и конструктивное доказательство — простую технику сведения алгоритма с изменениями на алгоритм с рекурсивным вызовом в точках изменения. Ну это на крайний случай, чаще всего находятся более элегантные способы. Я применял такой способ всего однажды. Обычно алгоритм либо легко переводится, либо находится более подходящий для такого языка.
А вот если алгоритм новый, что случается часто при рисёчах — Haskell сильно выручает.

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


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

DG>зы

DG>напомню, что на практике — если задача имеет только экспонециальный алгоритм — то считается, что задача не имеет алгоритмического решения.

К теме замечание не относится, в связи с ложностью предыдущего заявления.
Re[19]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 01.12.10 07:54
Оценка: +2
Здравствуйте, samius, Вы писали:

S>Я не считаю что C# удобен для смешения ООП и функциональщины. Разве что однозначно удобнее чем C.

S>По поводу переписывания фреймворка — ну да, разработчики F#-а пошли этим путем и переписали часть фреймворка. Ты хочешь что бы нечто подобное делали на C# в рамках других проектов, скажем в рамках проекта разработки desktop приложения?

С практической точки зрения добиться нормальной иммутабельности в C#+.NET, конечно, тяжело. Но тут как ты сам говоришь, это вина больше самого фреймворка. Если рассматривать сам C# как язык, то в общем-то в нем не так все катастрофично. Собственно, если в неком C# x.0 добавят таки полноценные иммутабельные "переменные", то а) в глобальном плане это ничего не изменит, т.к. фреймворк останется ровно таким же, каким он и был, б) в плане языка по идее изменит не мало.

Принципиальных проблем с иммутабельностью в C# как раз нет. Это не С. Я и сейчас могу легко и просто убедиться, что вызываемая мной функция не изменяет переданные в нее значения — достаточно, чтобы сами передаваемые объекты были immutable, а записать что-либо более другое по их адресу функция не сможет, только если это явно не будет разрешено через модификатор ref. Т.е. система-то типов дотнета вообще для иммутабельности хорошо подходит. Это просто фреймворк писали индусы.
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 06.12.10 10:27
Оценка: +2
Здравствуйте, lomeo, Вы писали:

L>Угу! Потому что с объектами на Ocaml и F# работают столь же активно, как и на ОО-языках, я прав? А на C# и VB.NET в функциональном стиле разработка ведётся как минимум для большей части методов. Т.е. разработка на этих языках ведётся как ты описал — "абстракциях верхноего уровня — ООП, реализация — ФП + где надо ИП". Или всё таки эти слова применимы только к гибридным языкам?


Тут проблема в том, что ФП можно понимать очень сильно по-разному. То, что сейчас действительно происходит в мейнстриме — это на мой взгляд взгляд не популяризация ФП как такового, а популяризация ряда приемов, паттернов из ФП, отдельных концепций. Можно сказать проще — такие императивные языки как C#, VB.NET и иже с ними как были, так и остаются по сути глубоко императивными, просто в них добавили "фишек".

Взять вот тот же паттерн-матчинг. Мне кажется, ПМ сам по себе вообще ортогонален функциональщине. Но многие ПМ воспринимают именно как одну из ключевых фишек ФП. Вот и получается — добавили ПМ, какие-нибудь "компрехеншены" — и получаем на выходе "гибридный язык". Я не хочу сказать, что это плохо — фактически языки становятся реально лучше, когда заимствуют подобные концепции — но по-моему функциональными они от этого не становятся.

Я лично не видел кода, который успешно совмещал бы ООП и ФП, т.е. реальное ООП и реальное ФП. Да и, честно говоря, я вообще не представляю, как это должно выглядеть. Принцип "снаружи ООП, а внутри методов — ФП", который тут рекламируется, это по-моему какой-то бред. Какой ФП? Внутри каких методов? ФП как раз должен быть снаружи, а внутри хоть ассемблер.

Это опять же лишнее подтверждение тому, что ФП ассоциируется лишь с какими-то конкретными фишками, который в действительности имеют слабое отношение к ФП.
Re[72]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.12.10 13:11
Оценка: -1 :)
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


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


U>А если многоугольник невыпуклый?


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

U>Как будет выглядеть доказательство? Сколько у тебя займет запись этого доказательства? Что гарантирует, что в процессе доказательства не было допущено ошибок?


Боюсь, что ответы на эти вопросы будут сложнее, чем поиск окружности описывающей многоугольник.

U>Центр окружности где будет находится?

Ответ ищи где-то в школьной геометрии.

S>>и доказательство решения сводится к "очевидно".


U>И чем это "очевидно" отличается от "мамой клянусь, что в коде нет ошибок"?

Вообще говоря, правильность подхода не гарантирует отсутствие ошибок в коде, как и наоборот, отсутствие ошибок в коде не гарантирует корректность выбранного метода решения задачи.
Re[75]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 15:20
Оценка: 12 (1)
Здравствуйте, samius, Вы писали:

S>Меня этому не учили, но для меня это очевидно.


Для вытянутого ромба центр окружности минимального радиуса будет лежать на середине отрезка соединяющего две наиболее удаленные друг от друга вершины, и на этой окружности будет лежать всего две вершины. Если ты этого не смог понять даже с подсказкой, то мне страшно подумать чему учат в элитных вузах, похоже догматизму и апломбу.
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 18:51
Оценка: 9 (1)
Здравствуйте, Sinix, Вы писали:

S>Кмк вы чуть-чуть опередили время ФП пока не мэйнстрим, поэтому привычного "превед! вот тебе фреймворк, вот тру-книжка, вот форум с кучей фанатов, видишь как всё просто!" нет.


Я от веба далек, но вот это http://ocsigen.org/ по моему вполне веб фреймворк, притом написан в хорошем функциональном стиле (смотрел и немного использовал из него кусочки несвязанные с вебом, например http://ocsigen.org/lwt/ ) для автора топика как пример дизайна вполне должен подойти.
Re[62]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.12.10 15:19
Оценка: 8 (1)
U>Ты хоть одно решение, дающее такую гарантию, можешь показать? А то я еще не встречал ни одного человека, который был бы не согласен с тем, что хорошо быть и богатым, и здоровым. Проблема только в том, что непонятно как сие желание преобразовать в решение.

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

Можно выделить два направления: условно назовем их "языкостроение" и "платформостроение".
"Языкостроение" — направлено на развитие языков, которые обеспечивают доказательство правильности работы программ
"Платформостроение" — направлено на развитие платформ, уменьшаюших степень фатальности ошибки. Развитие идет через выделение подмножества средств, которые с одной стороны — дают гарантию, что их использование не может привести к фатальным ошибкам, а с другой стороны — достаточны мощны для решения данных классов задач

По первому направлению сильного продвижения нет, и пока оно больше остается нишевым, из которого идет перекачка в mainstream.
примером такой перекачки является, например, статическая типизация, которая усиливается от версии mainstream-языков к версии (например, в .net-4 в статическую типизацию добавили понятия covariance и contravariance, до этого в 3.5 добавился вывод типов)

Второе направление "платформостроение" получило большее распространие в mainstream-е, чем языкостроение, появились такие платформы как:
1. браузер/javascript — из языка убраны управление потоками и прямой доступ к памяти.
2. sql-движок/sql,xpath,xquery — из языка убраны циклы, убраны прямой доступ к памяти, управление потоками
3. .net, java/C#,java,vb.net — из языка поумолчанию(можно включить) убран прямой доступ к памяти, через CAS можно убрать управление потоками
4. Plc-платформа/языки IEC 61131-3 — из языка убран прямой доступ к памяти, убраны циклы (цикличность делается через глобальный цикл всей платформы)
и т.д.

именно эти средства убираются по следующим причинам:
1. прямой доступ к памяти убирается, потому что при его отсутствии каждый кусок кода имеет доступ только к данным, ссылки на которые ему явно переданы. это дает гарантию локальности ошибки.
2. убирание циклов — позволяет получить гарантию, что программа закончится за конечное время
3. убирание управления потоков — усиливает первую гарантию (два потока могут иметь несинхронизованный доступ к общей памяти и получить в том числе невалидные указатели, которые предоставят доступ к чужим данным), и усиливают гарантию законченности (два потока могут повиснуть на deadlock-ах)

U>Что касается решения такой задачи, то общий подход не будет принципиально отличаться от того, что я уже говорил, т.е. от представления сущностей зависящих от других сущностей в виде кэшей, выноса максимально возможной части логики в функции без побочных эффектов и минизации последствий непредвиденных ошибок.


забываешь самое главное: первая главная задача программиста доказать что обработаны все варианты поведения.
то, что ты зафиксировал — это лишь способ уменьшения кол-ва вариантов поведения программы, и этот способ лишь упрощает выполнение главной задачи.

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

для следующего примера не надо никаких тестов, в нем уже при простейшей статической проверки видно, что не обработан вариант с null-ом
void Q(string s)
{
   if (s.ToLower() == "a")
     ...
}


здесь видно что не обработан вариант, когда items — null и когда 5 находится на первом месте в массиве
void Q(int[] items)
{
  for (int i = 0; i < items.Length; ++i)
  {
    if (items[i] == 5 && items[i-1] == 4)
     ...
  }
}

и т.д.

U>Важность задачи кардинально поменяет лишь административную часть. А именно функции и тесты должны писаться в нескольких вариантах, людьми никак не связанными друг с другом, выполнение действий должно резервироваться, отдельные модули должны испытываться на реальных, но менее важных и дорогостоящих задачах.


и это подтверждает, что ты далек от программирования, которое занимается решением сложных и критических задач.

то, что ты написал — не дает никакой гарантии, и это подтверждает взрыв Ариана 5 — там использовалось ПО, которое уже даже успешно отработало на Ариан 4.
http://www.ci.ru/inform11_97/vzrv.htm
и что самое интересное, что при разборе причин аварии, было выяснено, что
1. во-первых, разработчики поленились в паре мест с доказательством гарантии работоспособности программы
вернее для обоснования доказательства использовался довод, что такого не бывает (таких высоких величин не бывает)

Комиссии сообщили, что не все преобразования были защищены, потому что для компьютера SRI была установлена максимальная рабочая нагрузка в 80%. Чтобы определить уязвимость незащищенного кода, при разработке выполнялся анализ для каждой операции, которая могла бы вызывать исключительное состояние, включая ошибку операнда. В частности, было проанализировано преобразование чисел с плавающей запятой в целые числа, и найдены семь переменных, действия с которыми могли привести к ошибкам операнда. В результате этого была добавлена защита для четырех переменных. Однако три переменные были оставлены незащищенными. Никаких прямых ссылок на оправдание этого решения не было найдена в исходном коде.

Три остающихся переменных, включая ту, что обозначала горизонтальное смещение, были не защищены. Это было сделано на основе рассуждений, которые показывали, что значения этих переменных были физически ограничены или имелся большой запас по безопасности — рассуждения, которые для переменной BH оказались ошибочными.

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

Хотя источник ошибки операнда был идентифицирован, само по себе это исключительное состояние не приводило к отказу. Отказу способствовала и специфика механизма обработки особых ситуаций: в случае любого вида исключительной ситуации, согласно спецификации системы, сбой должен быть отражен на шине данных, состояние системы на момент сбоя должно быть сохранено в памяти ЭСППЗУ (которое было найдено и прочитано в случае с Ariane 5) и, в заключение, процессор SRI должен быть остановлен.


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

Исключительная ситуация была обнаружена, но была обработана неподобающим образом, потому что было принято считать, что ПО должно рассматриваться, как правильное, пока не доказано обратное. Комиссия имеет основания предполагать, что этот же принцип лежит в основе и других разработок ПО для Ariane 5. Комиссия придерживается противоположной точки зрения — что ПО должно изначально считаться содержащим ошибки, пока использование принятых в настоящее время самых лучших практических методов не докажет, что оно правильное.

Re[40]: кэширование цены корзины в FP
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 18:41
Оценка: 6 (1)
Здравствуйте, Undying, Вы писали:

S>>Это займет какое-то время. Прямо сейчас я этим заниматься не буду. На днях...


U>Жду.


Начал на C# и припух. Тяжеловат он для чистого FP. Потому написал на F#. Если что непонятно — предлагаю скомпилировать и воспользоваться рефлектором с таргетингом в C#.

Цикл сообщений смоделировал в виде списка сообщений. Метод run вытаскивает из списка сообщение и реагирует на него соответствующим образом.
module CartPrice

type Product = { Key : string; Price : decimal }

type Cart = { ProductKeys : list<string> }

let calculateTotalPrice cart productMap =
    let priceByKey id =
        match Map.tryFind id productMap with None -> 0M | Some(p) -> p.Price
    printfn "calculating..."
    cart.ProductKeys |> List.map priceByKey |> List.sum

type CartPriceCache = { Cart : Cart; ProductMap : Map<string, Product>; Price : decimal }

let getPrice cart productMap cache = 
    if (cache.Cart = cart && cache.ProductMap = productMap) 
        then (cache.Price, cache)
        else let newPrice = calculateTotalPrice cart productMap
             (newPrice, { Cart = cart; ProductMap = productMap; Price = newPrice })

type Message =
    | SetProductPrice of string * decimal
    | AddProductToCart of string
    | PrintCartPrice

let rec run messages productMap cart cache =
    match messages with
    | []           -> ()
    | m::messages' ->
         match m with
         | SetProductPrice(name, price) ->
             let productMap' = Map.add name { Key = name; Price = price } productMap
             printfn "%A price setted to %A" name price
             run messages' productMap' cart cache
         | AddProductToCart(id) ->
             let cart' = { cart with ProductKeys = id :: cart.ProductKeys }
             printfn "%A placed to the cart" id
             run messages' productMap cart' cache
         | PrintCartPrice ->
             let (newPrice, newCache) = getPrice cart productMap cache
             printfn "cart total price = %A" newPrice
             run messages' productMap cart newCache

let messages = 
    [
        yield SetProductPrice("foo", 10M)
        yield SetProductPrice("bar", 5M)
        yield AddProductToCart("foo")
        yield PrintCartPrice
        yield PrintCartPrice
        yield AddProductToCart("bar")
        yield PrintCartPrice
        yield PrintCartPrice
        yield SetProductPrice("foo", 20M)
        yield PrintCartPrice
    ]

let emptyCart = { ProductKeys = [] }
let emptyCache = { Cart = emptyCart; ProductMap = Map.empty; Price = 0M } 
run messages Map.empty emptyCart emptyCache


на всякий случай выхлоп
"foo" price setted to 10M
"bar" price setted to 5M
"foo" placed to the cart
calculating...
cart total price = 10M
cart total price = 10M
"bar" placed to the cart
calculating...
cart total price = 15M
cart total price = 15M
"foo" price setted to 20M
calculating...
cart total price = 25M
Re[15]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 20.11.10 05:59
Оценка: 4 (1)
Здравствуйте, samius, Вы писали:

S>Речь о сonst из C++, который при должном подходе может навеять дымку иммутабельности целым графам объектов (после его создания).


Более менее нормальная иммутабельность (хотя есть и свои тараканы) в сиобразных языках реализованна в D http://www.digitalmars.com/d/2.0/const3.html
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 02:03
Оценка: 3 (1)
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, borisman3, Вы писали:


B>>Вы уж простите, товарищ lomeo, что я выскажусь несколько огульно, но у меня складывается впечатление (очень надеюсь что ошибочное) что когда FP-программистам задаешь вопрос о крупномасштабной архитектуре (presentation tier + buisenss logic tier + integration/persistence tier + resource tier) они вместо прямого ответа начинают песню либо о типах, либо о монадах, т.е. о достаточно мелких детялях.


L>Мелких? ОК, давай на примере. Для достижения каких целей нужен, например, persistance layer? Каким способом их можно добиться с помощью ОО?


Persistence layer предназначен для долговременного хранения данных приложения. С помощью ОО реализуется либо как DAO-паттерн, либо как ORM-слой.

Но не в этом суть. Почему Вы все время пытаетесь свести разговор о крупной многопомпонентной, многозвенной системе к какой-то одной ее компоненте ?


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


L>Я привёл кучу ссылок на то, как строятся подобные приложения. Это ссылки на то, как строить куски, и на то, как из кусков собираются приложения. Этого недостаточно?


Хорошо, давайте конкретно. Во первых, спасибо за массу интересного материала, проблема в что он совершенно не отвечает на вопрос "Как проектировать большие системы в функциональном стиле"
Ссылки:
http://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%B2%D0%BE%D0%B4_%D1%82%D0%B8%D0%BF%D0%BE%D0%B2#.D0.9C.D0.BE.D0.B4.D0.B5.D0.BB.D1.8C_.D1.82.D0.B8.D0.BF.D0.B8.D0.B7.D0.B0.D1.86.D0.B8.D0.B8_.D0.A5.D0.B8.D0.BD.D0.B4.D0.BB.D0.B8.C2.A0.E2.80.94_.D0.9C.D0.B8.D0.BB.D0.BD.D0.B5.D1.80.D0.B0
http://ru.wikipedia.org/wiki/%D0%9B%D1%8F%D0%BC%D0%B1%D0%B4%D0%B0-%D0%BA%D1%83%D0%B1
http://en.wikibooks.org/wiki/Haskell/The_Curry-Howard_isomorphism
http://coq.inria.fr/
http://lomeo.livejournal.com/24990.html
http://en.wikipedia.org/wiki/Parametricity
http://homepages.inf.ed.ac.uk/wadler/topics/parametricity.html
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.9875
http://spbhug.folding-maps.org/wiki/TheoremsForFree
http://www.rsdn.ru/forum/flame.comp/2549267.1.aspx
Автор: lomeo
Дата: 19.06.07

http://icfp06.cs.uchicago.edu/bird-talk.pdf

больше относятся к системе типов и к сожалению не дают ответа на вопрос.

http://lukepalmer.wordpress.com/2008/07/18/semantic-design/ — почти единственная ссылка, имеющая отношение к делу, однако речь идет не о методологии проектирования а лишь (в лучшем случае) о кусочке такой методологии. Ссылка http://conal.net/blog/tag/type-class-morphism/ предлагает некий пример, причем неясно каким боком семантический дизайн относится к FP. Согласно той же википедии OOD как раз и есть попытка замены функционального дизайна семантическим: смотрите тут: http://en.wikipedia.org/wiki/Shlaer-Mellor

http://fprog.ru/2009/issue1/dmitry-astapov-checkers/ — уже более конекретно, но, к сожалению, опять же (намеренно?) автор берет проблему с четким входом, четким выходом и без состояния (чтобы хорошо ложилось на ФП) и объясняет не методологию, а лишь рассматривает частный пример "как можно было бы" начать строить ПРОГРАММУ (заметьте, не систему, состоящую из многих компонент) сверху вниз.
http://research.microsoft.com/en-us/um/people/simonpj/papers/financial-contracts/contracts-icfp.htm — действительно, замечательный пример дизайна, однако опять же, методологией тут и не пахнет (либо я плохо читаю, это не исключено) и решается какая-то весьма частная и узкая проблема (мне как неспециалисту даже не вполне понятна ее суть, но что-то очень специфично-финансовое). Следует вчитываться подробнее ?
Re[28]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.10 17:57
Оценка: 3 (1)
Здравствуйте, Undying, Вы писали:

U>Ладно, давай рассмотрим одну из часто встречающихся проблем — а именно рассинхронизацию между кэшированным состоянием и текущим состоянием.


U>
U>class Cart {
U>        private Customer customer;
U>        private List<Product> products;
U>        private int totalPrice = -1;

U>        private int computeTotalPrice() {
U>                // Scary code here
U>        }

U>        public int getTotalPrice() {
U>                if(totalPrice == -1)
U>                        totalPrice = computeTotalPrice();
U>                return totalPrice;
U>        }
U>        public void addProduct(Product p) {
U>                products.add(p);
U>                totalPrice = -1;
U>        }
U>}
U>


U>Проблема в том, что при изменении цены товара кэшированное значение стоимости покупки не пересчитывается.


U>Объясни чем здесь поможет иммутабельный подход? Допустим, стал у тебя Product иммутабельным, что теперь нужно сделать при изменении цены на товар? Как будет решаться задача получения информации об этом изменении всеми заказами?


Попробую объяснить:
Product иммутабельный, потому изменить цену непосредственно в нем нельзя не пересоздав Product (а тогда придется вводить ключ продукта, чтобы найти обновленный продукт в каталоге). Что бы не вводить ключ для продуктов, набор цен магазина будет представлять ассоциативный контейнер отображающий продукты в ценники (PriceMap). Набор цен тоже иммутабелен, потому в результате обновления цены одного из продуктов получится новый контейнер.
Корзина в свою очередь тоже иммутабельна. В результате добавления товара получается новая корзина.
цена корзины — это функция от корзины и набора ценников продуктов.
totalPrice:: Cart -> PriceMap -> int
Но раз требуется кэш, то
totalPrice:: CachedPrice -> Cart -> PriceMap -> (int, CachedPrice)
где CachedPrice — это такой же иммутабельный объект, который кэширует 3 вещи:
* корзина, для которой рассчитана цена
* набор цен продуктов, для которых рассчитана цена корзины
* рассчитанную цену

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

U>Правильный подход такой, при изменении цены любого товара обновляем некий changeTick общий для всех товаров. Далее в Cart для вычисления итоговой цены используем автоматический кэш, зависящий от двух параметров: 1) от внутренненего changeTick'а, отвечающего за изменение коллекции products 2) от внешнего changeTick'а, отвечающего за изменение цены любого товара. Соответственно в месте изменения цены на товар нам не нужно ничего знать о том где этот товар используется, итоговая цена во всех заявках обновится автоматически, причем сделает это ленивым образом. Принципу минимума сеттеров это решение полностью соответствует, соответственно работает прекрасно — код получается простой, понятный и надежный.

В иммутабельном подходе вместо tick-ов используются сами объекты — корзина и набор цен. Остальное — то же самое, вплоть до ленивости. Правда еще логарифмический от числа продуктов штраф на обновление набора ценников.

А что за принцип минимума сеттеров, который ты неоднократно упоминаешь?

U>Теперь жду твое решение этой же задачи, использующее иммутабельные объекты.

Извиняюсь за долгий ответ, мотался в Челябинск.
Re[33]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 11:45
Оценка: 3 (1)
S>Если объект можно изменить во внешнем коде через один из интерфейсов, то он не является иммутабельным.

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

для того чтобы считать объект иммутабельным при работе с объектом через определенный интерфейс нам необходимо и достаточно соглашения, что:
1. и/или обращения через другие интерфейсы не изменяет состояние объекта доступное нам через интерфейс, через который мы работаем
2. и/или состояние объекта не меняется за время работы с ним

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

такой подход часто используется при lazy-создании объектов, прозрачном кэшировании и т.д.

в ранее приведенном примере со строкой видно, что это соглашение выполняется следующим образом:
строка меняется пока нам ее не передали, как только нам ее передали — она больше не меняется,
в примере с ссылками — через доступный интерфейс нельзя получить значение ссылки, поэтому ее изменение на нас никак не влияет.

частичная иммутабельность активно используется в существующих языках:
например, почти все mainstream-языки считают, что тип объекта иммутабелен (т.е. интерфейс состоящий из одной функции obj.GetType(), а так же сам тип — иммутабелен)
c/C++ — считают, что указатель на объект иммутабелен (интерфейс &obj — иммутабелен)

в однопоточных приложениях и в приложениях с кооперативной многозадачностью можно фиксировать соглашение, что при отработке тела одной функции состояния используемых объектов меняется только в ответ на наши явные вызовы по изменению состояния.
это позволяет использовать все плюсы иммутабельности для неиммутабельных объектов.
и соответственно это приводит к критерию про который упоминал undying: чем меньше setter-ов и чем реже их необходимо вызывать, тем более система иммутабельна в фиксированный промежуток времени (больше объектов можно считать иммутабельными за данный фиксированный промежуток времени)
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 12:08
Оценка: 1 (1)
K>Столько же или даже несколько больше, чем реальных проектов, написанных в 1985-ом году на ОО-языках.

и я хочу лишь зафиксировать, что на "чистых" языках, которые жестко придерживаются одной концепции и непозволяют ее нарушать — очень тяжело писать реальные проекты.
эта проблема есть и с процедурным программированием (тот же pascal), и с ОО-концепцией (с тем же smalltalk), и с ФЯ (с тем же lisp-ом и scheme-ой), и с логическим программированием (prolog)
Re[42]: кэширование цены корзины в FP
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 11:24
Оценка: 1 (1)
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>Как будет выглядеть код при увеличении числа уровней иерархии?


U>Например, список товаров является частью иммутабельного объекта магазин.


U>Я правильно понимаю, что в этом случае код станет примерно таким?


U>
U>         | SetProductPrice(name, price) ->
U>             let productMap' = Map.add name { Key = name; Price = price } shop.productMap
U>             let shop' = { shop with ProductMap = productMap' }
U>

да

U>И чем больше будет уровней иерархии тем больше строчек кода придется писать для того, чтобы изменить значение нижнего уровня?

верно.
Но это гораздо меньше, чем придется написать строчек кода, что бы обезопаситься от такого:
shop.Products["foo].Price = int.MinValue;
от модератора
От: WolfHound  
Дата: 17.11.10 05:58
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>Пишет тебе старый твой поклонник, скромный труженик клавиатуры, канаццкий программист Борис.

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

(C)
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 09:27
Оценка: +1
Здравствуйте, lomeo, Вы писали:

L>Сразу — динамически типизированные языки требуют бОльших телодвижений при создании "систем нетривиальной сложности". Как минимум, необходимость писать огромное количество тестов. А в случае быстрого мутирования данных, о котором ты пишешь в следующем комментарии, так и вообще требуют особой внимательности.


Ты тут не совсем прав, вернее совсем не прав. В прототипировании динамика гораздо лучше статики.
"Огромное" количество тестов в реальных системах оказывается вполне сопоставимым с количеством тестов
для статических языков.
Быстрое мутирование данных как раз проще в динамике за счет того что там эти данные более гибкие.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 10:07
Оценка: +1
Здравствуйте, FR, Вы писали:

FR>Ты тут не совсем прав, вернее совсем не прав. В прототипировании динамика гораздо лучше статики.


Я пробовал — длительное время прототипировал в python. Нет у динамики преимуществ, по сравнению со статическими языками, позволяющими так же кратко записывать мысль. Сейчас для прототипирования использую Haskell и Scala.

FR>"Огромное" количество тестов в реальных системах оказывается вполне сопоставимым с количеством тестов

FR>для статических языков.

Даже для Java с generics не надо писать столько тестов, сколько для python.

FR>Быстрое мутирование данных как раз проще в динамике за счет того что там эти данные более гибкие.


И огребаем кучу проблем, потому что expression problem никуда не девается, а компилятор уже не показывает ошибки Или покажи пример.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 17.11.10 14:11
Оценка: +1
Здравствуйте, lomeo, Вы писали:

FR>>Ты тут не совсем прав, вернее совсем не прав. В прототипировании динамика гораздо лучше статики.

L>Я пробовал — длительное время прототипировал в python. Нет у динамики преимуществ, по сравнению со статическими языками, позволяющими так же кратко записывать мысль. Сейчас для прототипирования использую Haskell и Scala.

Я думаю, надо сравнивать сравнимое. Когда речь заходит о динамике, все почему-то берут какой-нибудь популяризированный язык с динамической типизацией, будь то ДжаваСкрипт или тот же питон, и начинают сравнивать его с чистым ФЯ. Это не совсем корректно, мне кажется.

Вот последнее время ковыряю Pure. Это тоже динамика. И его вот уже более корректно с Хаскелем сравнивать. Кстати, expression problem там решен
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 15:36
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, borisman3, Вы писали:


S>Так вы объясните саму задачу и используемые технологии; у кого был соответствующий опыт — поделятся Смысл использовать ФП ради использования ФП?


Хорошо, мне хочется разработать обычное трехзвенное веб-приложение. Если бы я применял OOD я уже и без этой информации в точности знал бы с чего начать.

Смысл исполльзования ФП ради ФП состоит в том чтобы на примере научиться пользоваться этой парадигмой, причем желательно в крупном масштабе (не на уровне отдельного модуля).
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 16:47
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, borisman3, Вы писали:


B>>Хорошо, мне хочется разработать обычное трехзвенное веб-приложение. Если бы я применял OOD я уже и без этой информации в точности знал бы с чего начать.


S>Если неизвестно как сюда прикрутить ФП, не определились с технологиями/фреймворком/языком — зачем тут ФП?


Для того, чтобы определиться с фреймворком и языком СНАЧАЛА пишутся архитектурные документы. Т.е. СНАЧАЛА надо хотя бы примерно систему осмыслить и разбить на запчасти, а уж ПОТОМ определяться с тем на каком фреймворке/языке это будет сделано. Теоретически я могу взять на вооружение OOD, разрисовать модули, классы, диаграммы потоков, последовательностей — путь, прямой как палка и пройденный не раз. Но не могу себе представить куда в этом прямом пути уложится FP хоть убей. Для ООП существует разработанная методология, для FP — похоже нихрена не существует, так народ и топчется на уровне отдельных методов (в лучшем случае — модулей).
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 16:55
Оценка: +1
Здравствуйте, lomeo, Вы писали:

L>Я пробовал — длительное время прототипировал в python. Нет у динамики преимуществ, по сравнению со статическими языками, позволяющими так же кратко записывать мысль. Сейчас для прототипирования использую Haskell и Scala.


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

FR>>"Огромное" количество тестов в реальных системах оказывается вполне сопоставимым с количеством тестов

FR>>для статических языков.

L>Даже для Java с generics не надо писать столько тестов, сколько для python.


Сравнивали уже здесь несколько раз, очень близко получается, вот например нашел:

http://rsdn.ru/forum/philosophy/2011897.1.aspx
Автор: eao197
Дата: 19.07.06

http://rsdn.ru/forum/philosophy/2012235.1.aspx
Автор: FR
Дата: 19.07.06


Вполне сопоставимо.

Просто число тестов специально проверяющих типизацию в более-менее крупных проектах на динамике стремится к нулю,
"обычные" тесты вполне совмещают эту проверку.

FR>>Быстрое мутирование данных как раз проще в динамике за счет того что там эти данные более гибкие.


L>И огребаем кучу проблем, потому что expression problem никуда не девается, а компилятор уже не показывает ошибки Или покажи пример.


тесты показывают
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 17.11.10 16:59
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>Да, это удивительно, но не наковырял. Более того, не наковырял даже проектной документации ни для одного большого рилворлдного ФП приложения. Единственное что мне известно из подобных проектов — это Erlang, но по определенным причинам это не самый удачный пример.


Так используют же многие языки в индустрии, в тех же финансов. В основном ML-семейства. Для Хаскеля, наверное, посложнее будет реал ворлд найти, но тоже встречаются. Мне вот шутер какой-то попадался на Хаскеле.

В действительности ситуация довольно простая. Есть задачи, которые хорошо ложатся на ФП. Если задачу можно представить в виде: данные на входе — цепочка трансформаций — данные на выходе, то это как раз оно и есть. На веб в принципе такая схема неплохо ложится. А есть задачи, которые на ФП не ложатся. Вы их можете попробовать решать на ФЯ, но наверное получится хуже, чем на ООЯ. В большом проекте задач обычно много и разных. Разделяете все на отдельные модули — какие-то можно разрабатывать в рамках ФП, какие-то — с использованием ООП. Ну вот, собственно, и все.

Только это должны быть именно отдельные модули. Мешать ООП и ФП по принципу — снаружи классы, а "мясо" внутри методов на ФП не стоит. Вообще такие советы, мне кажется, происходят из-за банального непонимания того, что есть ФП.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 17:17
Оценка: -1
Здравствуйте, borisman3, Вы писали:

IT>>Именно. FP рулит внутри метода, ООП — вне.


B>А как же все заверения адептов что FP мол надо широко применять как отдельную (от ООП) парадигму ?


FP чтобы быть отдельной парадигмой ни в каком ООП не нуждается, достаточно модульности.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:39
Оценка: +1
Здравствуйте, FR, Вы писали:

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


FR>>>Посмотри тут http://rsdn.ru/forum/decl/2720396.flat.aspx
Автор: Gaperton
Дата: 06.11.07
неплохой пример ФП дизайна на Эрланге.


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


FR>Ну грязь там есть в виде IO и она изолирована в отдельный модуль.

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

"Грязь" как Вы изволили выразиться в виде IO это очень и очень мало. Это всего лишь ввод данных и вывод их. Изначально у программы не предусматривалось внутреннего состояния, так что между запусками ее можно рассмытривать как функциональный модуль (даже независимо от того в каком стиле она была написана). Эта программа ИЗНАЧАЛЬНО хорошо подходит для реализации в функциональном стиле.

Так бывает как минимум не всегда — в больших проектах всегда есть часть, отвечающая за персистентность. Представьте что у Ващей программы есть как минимум один модуль целиком посвящен хранению состояния. Допустим даже что остальные модули полностью stateless. Вы можете написать их используюя FP подход, но как вы поступите с тем самым грязным вредным модулем ? Скажете что это не задача для FP ?
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: IT Россия linq2db.com
Дата: 17.11.10 18:04
Оценка: +1
Здравствуйте, borisman3, Вы писали:

IT>>В общем, забей Используй ФП там где оно даёт эффект тебе лично, а не там где про него рассказывают умные дядьки.


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


У объектных дядек методология только вне методов доведена до совершенства. А внутри каменные топоры, бивни мамонтов и кремний — камень дающий огонь.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 18:14
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>Это все опять же хорошие слова. Но получается что другого выхода как начать дизайн архитектуры системы с OOD у меня нет ? Там дальше пытаться в этом дизайне выделить "грязный" модуль (что может быть совершенно противоестественно для дизайна, да и не всегда возможно).


Почему нет, ООД тут лишняя сущность вполне хватит обычной модульной декомпозиции.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 18:21
Оценка: :)
Здравствуйте, borisman3, Вы писали:

B>Постойте, постойте. Мне кажется, я знаю. Сначала Вы говорите модульность. Затем Вы скажете что у модулей МОЖЕТ быть состояние. Затем Вы скажете "абстрактные типы данных". Поправьте меня, где я ошибся ?


Нет затем я скажу ФВП и комбинаторы и только после них "абстрактные типы данных".
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 17.11.10 18:49
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>То есть Вы предлагаете мне мешать между собой обе парадигмы (пусть между модулями а не внутри) ? Теоретически оно конечно хорошо, а на практике попробуйте-ка скажем напишите кусок на Сlojure а кусок на Java (и это, поверьте не самый стращный пример, т.к. Clojure очень хорошо интегрируется с Java). Получится тот еще Франкенштейн. С практической точки зрения может выйти так что Вам проще было бы написать все в одном едином стиле.


Возьмите один гибридный язык и пишите на нем. Кстати, Scala, если JVM вам близок.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 22:04
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>Собстывенно 6 лет назад я уже поднимал похожую тему (http://rsdn.ru/forum/philosophy/930970.aspx
Автор: Borisman2
Дата: 04.12.04
). Вынужден констатировать что воз и поныне там: каждый кулик хвалит свое маленькое болотце, свои маленькие функции, классы, типы или монады, но никто не может охватить полностью (хотя бы приближенно) картину "с высоты птичьего полета" и объяснить как же все эти концепции (ООП, FP, event-driven, ...) увязать между собой построив высокоуровневую (в смысле детализации) архитектуру большой промышленной системы.


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

Ну что ж! Если вы за 8 лет ковыряния не удосужились использовать изучаемые практики, то, конечно же, на то, что другие примерно за такое же время ковыряния их применяли и применяют, можно просто закрыть глаза — ведь ФП дизайна нет. Это очень логично.
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 18.11.10 08:24
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>>То есть Вы предлагаете мне мешать между собой обе парадигмы (пусть между модулями а не внутри) ? Теоретически оно конечно хорошо, а на практике попробуйте-ка скажем напишите кусок на Сlojure а кусок на Java (и это, поверьте не самый стращный пример, т.к. Clojure очень хорошо интегрируется с Java). Получится тот еще Франкенштейн. С практической точки зрения может выйти так что Вам проще было бы написать все в одном едином стиле.


B>В любом случае получается так что я ВЫНУЖДЕН во главу угла ставить OOD (а, значит и OOP), а функциональные модули как-то подпиливать и подтачивать под общий знаменатель. Не нравится мне это. Будет кривое решение.


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

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

Это как с функциями. Скажем, если вы напишите такую функцию вычисления длины списка:

let length lst = 
   let mutable size = 0 in
   for e in lst do 
      size <- size + 1
   size


То программа ваша от этого менее функциональной не станет. Т.е. внутри функции — мутабельная переменная, цикл — сплошная императивщина. Но при этом — это чистая функция. И с т.з. клиента она ни чем не отличается от, скажем:

let length = 
    let rec length' i lst = 
        match lst with
        x::xs -> length' (i + 1) xs
        | [] -> i 
    in
    length' 0


Также и с модулями Если какая-то задача решается лучше в императивном, в ООП и т.д. стиле — то так ее и решайте. Но как раз именно ФП можно при желании поставить во главу дизайна. Главный принцип — работаем не с данными, а с функциями. И ему совершенно не мешает грязь в каком-то отдельном модуле.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: WolfHound  
Дата: 18.11.10 10:43
Оценка: +1
Здравствуйте, Воронков Василий, Вы писали:

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

Именно к этому они и приведут.
Ибо классы это просто очень навороченные модули.

ВВ>Не надо "обворачивать" программу в ИО. Выносите ИО в отдельный модуль, совершенно функциональный и пушистый снаружи — и грязный внутри.

Для DAL нужна IO. Ибо обращение к базе данных это как ни крути IO.
BL тоже нужна IO ибо BL использует DAL.
Логику можно сделать чистой. Но все обращения к DAL это IO.
И пошло поехало...
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 15:11
Оценка: +1
Здравствуйте, borisman3, Вы писали:

B>Я был бы счастлив если бы кто-то ткнул меня носом в методологию проектирования FP-систем, но, видно, таковой не существует.


Я считаю, что методология проектирования энтерпрайза на высоком уровне никаким образом не связана с тем, для FP- или для ОО-системы мы её используем. Представьте крайний случай — С, совсем не объектно-ориентированный язык, как вы будете проектировать систему для него? Будут ли отличия на уровне, о котором мы ведём речь?
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 18.11.10 15:44
Оценка: +1
Здравствуйте, gbear, Вы писали:

G>А там таки есть _дизайн_ в каком-то формальном виде?! Имхо, все что там есть — это реализация некоторой идеи (дизайна). Которая, кстати, формально не выражена, а описана на естественном языке.


По моему дизайн вообще не формализуется. Я что-то не видел нигде математических обоснований например ООД.
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 17:27
Оценка: +1
Здравствуйте, borisman3, Вы писали:

L>>Я считаю, что методология проектирования энтерпрайза на высоком уровне никаким образом не связана с тем, для FP- или для ОО-системы мы её используем. Представьте крайний случай — С, совсем не объектно-ориентированный язык, как вы будете проектировать систему для него? Будут ли отличия на уровне, о котором мы ведём речь?

B>Конечно будут! Например возникнут неизбежные module.init() и module.done() в контрактах модулей, будут по всей видимости фасады в виде функций (а не классов).

Мы, видимо, друг друга не понимаем. Ну какие init/done на таком высоком уровне? Или всё же уровень не такой высокий и мой пример с монадами был к месту?
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.11.10 11:27
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Sinix, Вы писали:


S>>Подозреваю, невозможность изменения mutable-значений


U>Ты о том что внутри функции нельзя объявлять иммутабельные переменные? Так внутри функции и так прекрасно видно кто мутабельный, а кто не мутабельный (при нормальном стиле кодирования, конечно), кода-то мало и он легко охватывается взглядом. На практике проблемы возникают только с переменными классов, но для них в шарпе есть readonly.


На практике меньше всего проблем с полями классов, т.к. запись в них можно контроллировать и без readonly. Но что толку от иммутабельного поля-ссылки на немутабельный класс в насквозь мутабельном фреймворке? Единственный способ гарантировать иммутабельность — обертки с исключениями. А readonly — это баловство для тех кто любит гарантировать себе невозможность записи в как правило приватные поля.
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.11.10 12:39
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Я же не настаиваю. Хочешь — пиши. Только если поля у класса скрыты, то что readonly есть, что его нет, все одно. В плане будущих изменений — да, помогает.


U>На самом деле readonly полезно и в этом случае, т.к. при чтении кода сразу видно, что класс иммутабельный и переданные в конструкторе значения никогда не изменяются. Чтение кода заметно упрощается.


readonly поля не делают класс иммутабельным и не помогают увидеть его иммутабельность.

S>>Попрошу сделать обертку для Dictionary<TKey, TValue>, что бы не кидала исключений, сохраняла интерфейс и вообще вела себя как IDictionary<TKey, TValue>. Может ответ сам найдется...


U>На практике для Dictionary меня устраивает следующее решение:


U>
U>  static public class DictionaryHlp3
U>  {
U>    public static TValue FindObject<TKey, TValue>(this IDictionary<TKey, TValue> dic
U>  }
U>


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

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

U>Но в целом я не понимаю смысла в сохранении поддержки IDictionary. Ведь все равно выставлять словари в публичном интерфейсе это плохой стиль, а внутри класса никто не мешает использовать какую-нибудь обертку, которая содержит только некидающие исключение методы, вроде bool Add(key, value) и тех же FindObject и FindValue.


Выставлять структуры данных фреймворка плохой стиль именно из-за их мутабельности. Выставлять IList<T> ведь никто не запрещает, если за него ReadOnlyCollection<T>. Наоборот, даже рекомендуют.

U>Какие плюсы дает поддержка IDictionary? Я вижу только один — привычность, т.е. как пользоваться IDictionary знает любой программист, а по поводу какого-нибудь SafeDictionary у нового программиста могут возникнуть вопросы. Но это очень небольшая проблема, все равно новому программисту нужно разбираться с классами бизнес-логики, которые он точно также видит в первый раз в жизни как и SafeDictionary.


Плюсы дает все то, с чем можно работать стандартными методами либо через стандартные интерфейсы. Но мутабельность стандартных классов мешает их использованию.
Re[22]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.10 05:01
Оценка: :)
Здравствуйте, Undying, Вы писали:

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

В таком случае предлагаю закруглиться.

S>>Уверен, что ты по IList<T> интерфейсу так же не поймешь, List<T> за ним скрывается или ReadOnlyCollection<T>. Как ты с этим работаешь-то?


U>Не использую IList в публичном интерфейсе. Именно по той причине, что с этим невозможно работать.

Тогда ничего бы не помешало НЕ использовать и другой IList, возвращающий новый IList в мутирующих методах.
Re[31]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 25.11.10 05:21
Оценка: -1
Здравствуйте, Ikemefula, Вы писали:

I>Ну вот в Linq плохо с самодокументируемостью ? Вроде как наоброт — все логично и просто.


Речь идет о хранении состояний, причем здесь Linq? Linq это низкоуровневое средство, которое можно использовать только внутри функций. В данном контексте, то на чем пишутся внутренности функций совершенно не интересно, т.к. архитектурная сложность кода внутри функций стремится к нулю.
Re[33]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 12:07
Оценка: +1
полезные характеристики иммутабельных объектов (которые с ходу пришли):
1. нет рассинхронизации состояния объекта при работе с ним
2. нет необходимости проверять валидность кэша
Re[35]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 12:50
Оценка: +1
> Википедию писали фанатики?

сейчас ты показываешь другое проявление фанатизма: отсылка к авторитетам вместо отсылки к доводам(логическим выводам)
это мне напоминает то, что долгое время считалось, что у мухи 8 ног т.к. все ссылались на авторитет Аристотеля


DG>>1. и/или обращения через другие интерфейсы не изменяет состояние объекта доступное нам через интерфейс, через который мы работаем

DG>>2. и/или состояние объекта не меняется за время работы с ним
S>И оно мне не понятно. Допустим, есть массив int[] и интерфейс IEnumerable<T>. Пункт 1 не выполняется, т.е изменение через другие интерфейсы возможно. А пункт 2 зависит от того, будет ли кто-то менять состояние массива, пока кто-то работает с ним через IEnumerable<T>, или нет. Т.е. ответа на то, является ли массив изменяемым или нет, такое определение не дает. Я им не буду пользоваться.

в данных кусках кода объект items иммутабелен или нет?
можно ли считать, что объект items иммутабелен? и почему?
int[] items = data.GetItems();
foreach (var item in items)
{
  //..bla-bla
}


int[] items = data.GetItems();
F(items as IEnumerable<int>)



S>Не понял. Изменилась цена продукта, корзина осталась неизменной, хотя при обращении к ней она изменит свою стоимость. Предлагается считать корзину иммутабельной в момент изменения цены продукта?


т.е. приложение имеет несколько несколько параллельных потоков управляющей логики?
один поток формирует корзину?
другой поток может менять цены продуктов?

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

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

зы
кстати если исходить из законов РФ, то цена продукта не может меняться после того, как его взяли с полки
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 15:17
Оценка: +1
FR>Конечно и это хорошо.

нет, конечно же.
язык делается для того, чтобы быстро и дешево решать проблемы, а не для того, чтобы дорого и долго переписывать весь имеющийся код.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 26.11.10 10:00
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>К тебе никаких претензий

FR>Просто весь тред вызывает у меня недоумение зачем так мучатся

Очевидно затем, что выбор у нас между мучиться так или мучиться гораздо сильнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 12:42
Оценка: +1
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, DarkGray, Вы писали:


DG>>вот только ОО-концепции в 85-ом было лет 5 от роду,


K>Наверное языки вроде Simula-67 и Smalltalk-72 имеют в названии случайно выбранные числа, с годами никак не связанные.


smalltalk точно не имеет, потому что публично он был предоставлен в 80-м

The unqualified word Smalltalk is often used to indicate the Smalltalk-80 language, the first version to be made publicly available and created in 1980.


а simula-у правильнее сравнивать с lisp-ом, чем с haskell-ем.
simula — это одна из самых ранних попыток реализовать ОО-концепцию, lisp — ранная попытка реализовать ФЯ-концепцию.
причем lisp появился на 10 лет ранее, чем simula, и тогда ФЯ-концепции вообще уже 50 лет.

и соответственно сравнение haskell-я со smalltalk-ом, имхо, является справедливым, также как сравнение simula с lisp-ом.

DG>>а тому же haskell-у уже 20 лет прошло.


K>И что с того? Есть какой-то фундаментальный закон, согласно которому все внедряется за постоянное время в n лет? С опытом это в любом случае не согласуется. Обычно, чем изменения революционнее, тем сроки внедрения выше.


фундаментального закона, но скорость внедрения является индикатором преимуществ того или иного подхода (того или иного языка).
Исходя из данного индикатора можно сделать вывод, что haskell может быть и хорош, но не настолько сильно, что необходимо все бросать и переходить на него. в тоже время раз он еще не умер, а развивается, то можно сделать вывод: что у него есть плюсы важные для определенного круга людей, но в тоже время — есть существенные минусы, которые не позволяют остальным на него перейти.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 27.11.10 18:50
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>и я хочу лишь зафиксировать, что на "чистых" языках, которые жестко придерживаются одной концепции и непозволяют ее нарушать — очень тяжело писать реальные проекты.

DG>эта проблема есть и с процедурным программированием (тот же pascal), и с ОО-концепцией (с тем же smalltalk), и с ФЯ (с тем же lisp-ом и scheme-ой), и с логическим программированием (prolog)

Lisp отсюда точно вычеркивай, он практически все парадигмы поддерживает.
На Smalltalk было написано немало реальных и немаленьких проектов и его погубила не "чистота" а жадность производителей компиляторов.
Re[16]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.11.10 06:22
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:

S>>А так же убрать Remove(TKey) и изменяющие методы ICollection<T> (Add, Remove, Clear).
S>Не убрать. Заменить их на методы, возвращающие новый экземпляр словаря.
Да, но заменить мы их не можем. Можем "спрятать" и добавить новые. Спрятанные же придется реализовывать выкидывая исключения. Об этом я и писал.

S>>Но отказавшись от стандартных интерфейсов мы потеряем возможность использовать свою коллекцию в методах фреймворка и не только, например там где могла бы пролезть ICollection<T> (Enumerable.Count, Last, ... для нее сработали бы с O(1)).

S>Это другой вопрос. Весь фреймворк построен на интерфейсах, подразумевающих mutable-объекты. Что является вторым основным препятствием для массового применения immutable — после отсутствия поддержки в языке.
согласен.

S>Ну и само это решение тоже не самостоятельное — это следствие отстутствия в среде исполнения эффективных реализаций подобных интерфейсов. Насколько я понимаю, реализовать произвольные методы модификации через порождение новых экземпляров с приемлемой производительностью не так-то просто. Ну то есть я легко представляю метод Dictionary Dictionary.Clear(), работающий за O(1). С .Remove() я бы не справился.

Dictionary.Clear() не нужен. За него будет Dictionary<TKey,TValue>.Empty.
С Remove несколько сложнее. Реализация Dictionary<TKey,TValue> не предназначена для реюза в иммутабельных коллекциях без полного копирования как минимум области памяти самой таблицы.
Думаю, что сделать реализацию с сегментированной таблицей, где при построении измененного словаря было бы необходимо изменять данные лишь в одном сегменте (а остальные сохранить) — вполне реально. В рамках такой структуры данных Remove был бы несложен.

Но не собираюсь я предлагать делать такую структуру в 5-м фреймворке. Я вообще сюда влез только что бы сказать что модификатора readonly недостаточно для создания иммутабельных структур данных.
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 06:26
Оценка: :)
Здравствуйте, Klapaucius, Вы писали:

K>Они не лишние — они обеспечивают ссылочную прозрачность, которая в свою очередь снимает необходимость в "протаскивании информации об изменении".


Ссылочная прозрачность мне даром не нужна. Мне нужно 1) чтобы ссылок было минимально возможное количество, т.е. чтобы объекты не создавались без необходимости 2) чтобы по коду легко было определить какие ссылки по условию задачи являются неизменяемыми, а какие нет. Мутабельный подход легко позволяет создавать решения удовлетворяющие и первому, и второму условию, чисто иммутабельный подход противоречит обоим условиям.
Re[57]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 13:30
Оценка: :)
L>3 — практикой не подтверждается, практически для любой задачи найдётся алгоритм сравнительно или столь же эффективный и более или столь же удобный как и в случае императивного подхода.

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

самое фиговое что большинство фундаментальных алгоритмов записана именно в терминах переиспользования памяти:
кнут,
вычмат,
алгоритмы над графами,
алгоритмы над матрицами,
графические алгоритмы
и т.д.

и ты предлагаешь все алгоритмы которые в универе только рассказывали пару лет, обычному программисту в одиночку за пару дней переосмыслить как их эффективно записать без переиспользования памяти?

т.е. ты действительно считаешь, что возможности отдельного программиста равны возможностям ученых всего мира, которые думали над алгоритмами последние 100 лет?
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 14:42
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

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

DG>каждая концепция привносит определенный набор ограничений.

DG>язык академический — если не рассматривается и не решается задача в которой нарушаются ограничения концепции.


Мне такие языки не известны. Такие задачи так или иначе всегда ставятся и решаются. Даже в Прологе есть (!) что уж про другие "академические" языки говорить?

DG>например, нарушением концепции "все есть объект" является введение атомарных типов (числа, булы, строки и т.д.) как не совсем объектов.

DG>исходя из этого критерия — smalltalk — академический, Java, C++, C# — не академические.

Какой-то странный пример. Какие ограничения у чисел-"объектов"? И почему в C# число — "не совсем объект"?
Т.е. я и сам думаю, что "иммутабельный объект" — это не объект. Но это не специфика "атомарных типов".
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[58]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 14:58
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

L>>Я же написал другие алгоритмы. Хороший пример — зиппер.

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

Какой процент программистов и за какое время осилит более сложную статью — про конкретную реализацию balanced trees, например? Или чего-нибудь из threadsafe структур возьмём.

Я считаю сложность зиппера примерно эквивалентным, ну скажем hashmap-у. Даже чуть проще. hashmap какой процент осилит?

DG>или даже спрошу по другому: какие требования в резюме необходимо выставить, чтобы пришедший человек, удовлетворяющий этим требованиям, гарантировано хотя бы за пару дней въехал в данный подход?


Для зиппера-то? Не знаю, базовых знаний по структурам должно быть достаточно — такого, чтобы понимал что такое деревья и как они устроены. Как можно бегать по ним. Неплохо было бы также уметь думать и желание учиться.
Re[60]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 16:23
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>тебе понятно — что задача переписывание с псевдоязыка на Java есть алгоритмическая задача?

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

Выдумки какие-то. С чего ты взял, что нужно переписывать алгоритм с техникой переиспользования памяти? Нужно просто взять другой алгоритм. Третий раз курсивом выделяю. Их полно в инете. Если взять одну из сложнейших областей — алгоритмы на графах, то посмотри на inductive graphs как на пример.

То, что им не учили в институте — не оправдание. Это алгоритмы легко находятся в гугле. Большинство же алгоритмов с переиспользованием памяти тривиально переписываются на ФП. Если мы назовём это неалгоритмической задачей, это всего лишь значит, что мы будем играть словами.

В частности, если тебя так интересует формализация (для сведения задачи к алгоритмической) — используй изменяемые значения и текущее положение как аругменты — и алгоритм с переиспользованием памяти превратится в алгоритм без переиспользования
Re[61]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 16:28
Оценка: :)
Здравствуйте, DarkGray, Вы писали:

DG>>>и да — какой оклад данному человеку стоит положить (например, для Москвы)?

L>>Не знаю. Ты что ли пучок равшанов хочешь набрать вместо пары нормальных специалистов?
DG>не уходи от ответа — а назови цену.

Я не ухожу от ответа. Я не знаю. Это и есть ответ. Мало того, я считаю что выбирать один-единственный критерий и по нему оценивать стоимость специалиста совершенно неверно. По-моему опыту стоимость вообще вещь сильно субъективная, поэтому вопросы типа сколько стоит С++ программист со знанием STL считаю абсолютно дилетантскими.

DG>зы

DG>я знаю, что для того, чтобы все вышеуказанные алгоритмы достаточно эффективно в один один реализовать на C#, Java и т.д. — можно брать человека и за 30-50 тыс. в москве.
DG>пару месяцев его понадобится поднатаскать, а дальше это он будет делать это сам.

А я вот не уверен. Я вообще плохо понимаю, почему здесь разговор перешёл не менеджерские рельсы. Мы же вроде о программировании, нет?
Re[62]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 30.11.10 13:45
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>в том-то и дело, что вмешивается опосредованно


Где разница между непосредственно и опосредовано тогда?

Я считаю, что опосредованно человек вмешивается в процесс когда пишет декларативную программу на Прологе. А когда человек определяет, куда прологовский решатель пойдет в первую очередь, куда во вторую, а откуда ему запрещено возвращаться — это самое что ни на есть прямое вмешательство и все это зайдет/выйдет именно "внутренний" уровень Пролога, потому что снаружи никто никуда не ходит — там совершенно декларативные дизъюнкты Хорна.

DG>пролог у себя внутри оперирует одним набором операций, а человек снаружи другим

DG>и первое — не эквивалентно второму.

И чем в данном случае Пролог отличается от любого другого языка? Смысл любого языка в том, чтобы внутри было одно — а снаружи что-то другое. Если снаружи в точности то же, что и внутри, то языка просто нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 00:19
Оценка: -1
Здравствуйте, FR, Вы писали:

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


B>>Постойте, постойте. Мне кажется, я знаю. Сначала Вы говорите модульность. Затем Вы скажете что у модулей МОЖЕТ быть состояние. Затем Вы скажете "абстрактные типы данных". Поправьте меня, где я ошибся ?


FR>Нет затем я скажу ФВП и комбинаторы и только после них "абстрактные типы данных".


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

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

А ведь если бы к в нем убрать догмы и добавить удобные для людей конструкции описания тех самых объектов мог бы получиться хороший гибрид.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 07:23
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Есть только действующий ФП-язык — Хакель, который предлагает для оных вещей приемлемые "функциональные" аналоги — классы типов.


Обсуждали уже. Классы типов — всего лишь сахар для естественного в мире ФП приёма. Так что это не аналог. Это просто сахар для своего чисто ФП-шного приёма абстракции. Который с успехом можно применять в любом ФЯ.
Re[66]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 01.12.10 09:33
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>см. примечание про иерархию исполнителей.


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

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

DG>какой-то доступ есть только к самому верхнему.

Ну вы же не можете не понимать, что доступ можно встроить к любому вашему "уровню", если это доступ через API. В Прологе как языке есть два уровня: декларативный и императивный. Доступ для программиста к обоим уровням поддерживается конструкциями языка.

DG>опиши своими словами, что делает прологовский движок — когда выполняет еще одну команду (для начала в самой краткой форме)


Упрощенно это выглядит так: движок обходит дерево; листья дерева — решения, узлы — условия, которые движок проверяет. Программист может указать в какие ветви заходить в первую очередь, в какие во вторую и т.д. Также, если, например, условие в узле противоположные (жив и мертв, например), то программист может поставить метку, которая будет движком интерпретирована так: если выполняется условие "жив", то поддерево с корнем в "мертв" движок уже обходить не будет. Каких тут еще способов контроля движка не хватает? Ни и для того, что не укладывается в обход таких вот деревьев есть "предикаты" совершающие императивные действия.

DG>примеры чего?


Примеры языков без такого доступа. Потому, что это фантастика. Ну вот представьте, что вы реализуете экспериментальный язык. Компилируемый. Вам для него нужна стандартная библиотека. В которой будет ввод/вывод. Для этого вам нужно как то взаимодействовать с ОС. Т.е. нужен интероп с C, ну вы и добавляете в язык FFI — не будете же вы все это в компиляторе хардкодить. Т.е. мы получаем доступ на другой уровень вашей иерархии. И не важно, собираетесь вы использовать язык для исследований или для индустриального применения — с проблемой вы столкнетесь и решить ее придется. К тому же, в исследовательских языках как раз любят двавать возможность управлять компиляцией, т.е. доступ к другому уровню по вашей терминологии. В том же Хаскеле есть доступ к AST через Тemplate Haskell, есть доступ к преобразованиям в промежуточное представление через rewriting rules, понятное дело, что есть элементарщина вроде директив inline/noinline и т.д. О таком в индустриальных C++ и C# можно только мечтать. Есть интроспекция через Typable, есть FFI — доступ к C и через C ниже. Какой тут из ваших уровней не охвачен?

DG>тебе понятно в чем отличие между прямым доступом и опосредованным?

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

В общем случае прямой доступ не может поддерживать более полный комплект операций. Будут некоторые операции, которые недоступны при опосредованном доступе, а некоторых операций, доступных из опосредованного не будет в прямом. Иначе языки прогрммирования не имели бы смысла.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 11:30
Оценка: +1
Здравствуйте, VladD2, Вы писали:

L>>Обсуждали уже. Классы типов — всего лишь сахар для естественного в мире ФП приёма. Так что это не аналог. Это просто сахар для своего чисто ФП-шного приёма абстракции. Который с успехом можно применять в любом ФЯ.

VD>Я не знаю кто и где это обсуждал, но точно знаю, что классы типов есть только в одном языке. Так что обсуждать тут нечего.

http://www.rsdn.ru/forum/decl/4035631.1.aspx
Автор: lomeo
Дата: 12.11.10


Это ответ на твоё сообщение, также ниже по треду ты отметился тоже. Так что пропустить это сообщение ты не мог.

Ещё раз — классы типов может и есть только в одном языке, но сахарят они стандартный dictionary-passing style. Твоё желание свести абстракцию к миру ОО вполне понятно, вот только идёт оно в разрез с реальностью.
Re[66]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.10 05:46
Оценка: :)
Здравствуйте, Undying, Вы писали:

DG>>базовые операции a+b, if, for и т.д. считаются верными на фиксированном классе значений, а дальше вперед:

DG>>для каждого куска кода фиксируется pre/post-условия, инвариант.

U>Что это дает-то? Что ты вообще собрался доказывать для функции контроля расписания? Соответствие ответа чему?


Если ответ ничему не должен соответствовать, то нафик он нужен?
return 42;
и все счастливы.
Re[70]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.12.10 11:33
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Видимо ты хотел подставить координаты многоугольника в формулу, выражающую центр окружности?


U>Разумеется я этого не хотел.


Тогда я не вижу в чем проблема

S>>В остальном у математики нет проблем с этой задачей.


U>И каково решение этой задачи? Как выглядит доказательство этого решения?

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

Единственный неочевидный момент в доказательстве будет лишь тот, который будет доказывать что вершина с максимально острым углом ВО будет лежать на искомой окружности. Я думаю что это не составит проблемы.

Хотя, ВО нужна лишь для того, что бы уменьшить число итераций и зафиксировать первую вершину.
В остальном задача решается полным перебором троек вершин и доказательство решения сводится к "очевидно".
Re[74]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.12.10 15:14
Оценка: :)
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Назови мне ВУЗ, который ты заканчивал. Буду рекомендовать его некоторым знакомым, которые боятся перегрузить голову.


U>Тебя, как и Darkgray'я, тоже в элитном вузе учили, что окружность минимального радиуса описывающая многоугольник должна проходить не менее чем через три точки?


Меня этому не учили, но для меня это очевидно.
Re[76]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 15:39
Оценка: :)
U>Правда? И для вытянутого ромба тоже? Через какие такие три вершины будет проходить центр минимальной описывающей окружности в этом случае?

через две реальных и одну виртуальную

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

зы
этим бывает хороши строгие доказательства, там явно всплывают все вырожденные случаи.
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 05:14
Оценка:
И вот если только можно то поясните канкретна простому канаццкому парню вот че делать ? Вот откуда начинать архитектурить приложение ?

Следует ли ему выкорчевать все состояние из всех компонент приложения и сконцентрироваться на функциях ? Но ведь это приведет к известным проблемам (see http://www.slac.stanford.edu/BFROOT/www/doc/workbook_kiwi/coding/OOvsSASD.html), свзяанным с тем что структуры данных могут мутировать ОЧЕНЬ быстро и непредсказуемо в процессе разработки.

И как тут быть ? Откуда взяться ?
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 17.11.10 05:42
Оценка:
Здравствуйте, borisman3, Вы писали:

B>И вот если только можно то поясните канкретна простому канаццкому парню вот че делать ? Вот откуда начинать архитектурить приложение ?


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

B>Следует ли ему выкорчевать все состояние из всех компонент приложения и сконцентрироваться на функциях ?

Ради чего?
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: c-smile Канада http://terrainformatica.com
Дата: 17.11.10 07:06
Оценка:
Здравствуйте, borisman3, Вы писали:

Посыл не верный изначально. Причем еще на уровне противопоставления OOP и FP.

Твое сообщение но как бэ другими словами:

Люди, я аццкий специалист в области изготовления мебели стамесками.
Но вот увидел в Канадской Шине еще рубанки. И появилось у меня желание сделать мебельный
гарнитур X (большой) сугубо рубанком. Но что-то меня берут сомнения вырезания пазов оным инстрУментом.
Я в отчаянии. Или у вас таки будет бальзам для меня или получается фигня этот ваш рубанок.


Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 09:37
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Следует ли ему выкорчевать все состояние из всех компонент приложения и сконцентрироваться на функциях ? Но ведь это приведет к известным проблемам (see http://www.slac.stanford.edu/BFROOT/www/doc/workbook_kiwi/coding/OOvsSASD.html), свзяанным с тем что структуры данных могут мутировать ОЧЕНЬ быстро и непредсказуемо в процессе разработки.


Ему следует стараться минимизировать число компонент с изменяемым состоянием.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 10:02
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>То что я видел в примерах на haskell, это слабоинтерактивное (консольное) приложение со stateless бизнес-логикой.

G>Хотелось бы увидеть всетаки приложение на haskell, которое имеет как минимум все части, указанные выше, о чтобы весь код не был завернут в IO.

G>Хотябы один пример какой-нить записной книжки с двумя таблицами в БД и формочкой.


Хм.. gitit? Вообще на happstack периодически встречал приложения. Ну web и web. Всё перечисленное присутствует. Неинтересно же.

С десктопным UI встречал чисто функционального мало, обычно это что-то на gtk2hs.

Если неважно, чтобы было всё и сразу, то есть куча проектов с замечательным кодом (см. например, xmonad).

Вообще, чего хочется? Приложений, написанных на Haskell, или увидеть, как писать код на Haskell, разбивая на куски?

Если первое, то

http://www.haskell.org/haskellwiki/Applications_and_libraries
http://www.haskell.org/haskellwiki/Applications

Но это грубо. Если второе, то зачем "минимум все части"? Достаточно понять как пишется каждая часть и как они объединяются. Каждая часть — см. RWH. Объединять — я уже говорил про трансформеры.

Монады — всего лишь удобный в Haskell механизм декомпозиции. Сама типизация позволяет уже делать многое. Написал ты, например,
newtype ConnectionMonad a = ConnectionMonad { runConnection :: ReaderT DB.Connection IO a }
    deriving (Functor, Monad)

и конструктор закрыл. Теперь внутри этой монады ты можешь использовать только функции работающие с ней. А ими ты ограничиваешь то, что тебе нужно. Например, не даёшь доступ к смене соединения. Или позволяешь запускать запросы только в транзакции (определив монаду транзакции и написав, метод, грубо — TransactionMonad a -> ConnectionMonad a). Если последнее неважно, то можно определить метод inTransaction :: ConnectionMonad a -> ConnectionMonad a.

То же с сетью, обработкой ошибок, своим протоколом, ui, бизнес-логикой. Монада может использовать другую монаду, они могут нанизываться друг на друга с помощью трансформеров, не зная о том, какая конкретно монада используется.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 10:26
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

L>>Сразу — динамически типизированные языки требуют бОльших телодвижений при создании "систем нетривиальной сложности".

MC>Существует мнение, что единственный ФЯ, на котором создана система нетривиальной сложности — это эрланг.

Не противоречит.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 17.11.10 10:33
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>То что я видел в примерах на haskell, это слабоинтерактивное (консольное) приложение со stateless бизнес-логикой.

G>>Хотелось бы увидеть всетаки приложение на haskell, которое имеет как минимум все части, указанные выше, о чтобы весь код не был завернут в IO.

G>>Хотябы один пример какой-нить записной книжки с двумя таблицами в БД и формочкой.


L>Хм.. gitit? Вообще на happstack периодически встречал приложения. Ну web и web. Всё перечисленное присутствует. Неинтересно же.

(после беглого просмотра) Конечно неинтересно, там все завернуто в IO. Все описанные выше преимущества идут лесом. Остается чистое ФП на уровне тел методов.

L>С десктопным UI встречал чисто функционального мало, обычно это что-то на gtk2hs.

Ну а ссылки на пример?

L>Если неважно, чтобы было всё и сразу, то есть куча проектов с замечательным кодом (см. например, xmonad).

Там далеко не все к сожалению.

L>Вообще, чего хочется? Приложений, написанных на Haskell, или увидеть, как писать код на Haskell, разбивая на куски?

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

L>Если второе, то зачем "минимум все части"? Достаточно понять как пишется каждая часть и как они объединяются.

Важно все вместе. Потому что иначе получается "ФП на уровне тел методов". Посмотри форум по архитектуре. Самые интересные вопросы возникают не в том как написать BL, а в том как совместить BL, DAL и много другие аббривеатур из умных книжек.

L>Монады — всего лишь удобный в Haskell механизм декомпозиции. Сама типизация позволяет уже делать многое. Написал ты, например,

L>
L>newtype ConnectionMonad a = ConnectionMonad { runConnection :: ReaderT DB.Connection IO a }
L>    deriving (Functor, Monad)
L>

L>и конструктор закрыл. Теперь внутри этой монады ты можешь использовать только функции работающие с ней. А ими ты ограничиваешь то, что тебе нужно. Например, не даёшь доступ к смене соединения. Или позволяешь запускать запросы только в транзакции (определив монаду транзакции и написав, метод, грубо — TransactionMonad a -> ConnectionMonad a). Если последнее неважно, то можно определить метод inTransaction :: ConnectionMonad a -> ConnectionMonad a.

L>То же с сетью, обработкой ошибок, своим протоколом, ui, бизнес-логикой. Монада может использовать другую монаду, они могут нанизываться друг на друга с помощью трансформеров, не зная о том, какая конкретно монада используется.

Ну это теория, нужен прмиер. Что-то вроде MVC Music Store или Nerd Dinner
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 11:59
Оценка:
Здравствуйте, gandjustas, Вы писали:

L>>Хм.. gitit? Вообще на happstack периодически встречал приложения. Ну web и web. Всё перечисленное присутствует. Неинтересно же.

G>(после беглого просмотра) Конечно неинтересно, там все завернуто в IO. Все описанные выше преимущества идут лесом. Остается чистое ФП на уровне тел методов.

Ты про gitit или happstack? В gitit используются свои монады. В happstack, кажется, для обработчиков тоже были свои. Плюс посмотри на другие фреймворки — turbinado, snap.

L>>С десктопным UI встречал чисто функционального мало, обычно это что-то на gtk2hs.

G>Ну а ссылки на пример?

Зачем тебе это? Там обычный код, как и в других приложениях с использованием qt/wx/gtk.
Я не могу тебе в этом помочь. Встречающийся мне код ничем не отличался от, например, питоновского. Потом, я не сильно интересуюсь GUI, у меня из GUI-шных прог то только оракловый клиент, im, да браузер.

L>>Вообще, чего хочется? Приложений, написанных на Haskell, или увидеть, как писать код на Haskell, разбивая на куски?

G>Ну я написал выше какие части хочется увидеть. Без них ни одно крупное приложение не существует.

Это я понял. Цель какая?

L>>Если второе, то зачем "минимум все части"? Достаточно понять как пишется каждая часть и как они объединяются.

G>Важно все вместе. Потому что иначе получается "ФП на уровне тел методов". Посмотри форум по архитектуре. Самые интересные вопросы возникают не в том как написать BL, а в том как совместить BL, DAL и много другие аббривеатур из умных книжек.

Можно пример, сходу не нашёл интересного вопроса.

Насчёт DAL — посмотри как эта проблема решается в happs-state:
http://hackage.haskell.org/package/happstack-state

Это, правда, не обычная СУБД.

G>Ну это теория, нужен прмиер. Что-то вроде MVC Music Store или Nerd Dinner


Это из практики Послушай, хорошо, что вообще веб-фреймворки есть для haskell, pet store для них, видимо, ещё не написали.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 13:42
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Я бы сначала сосредоточился на задаче и на наиболее подходящих инструментах, а уж затем использовал выбранные инструменты общепринятым способом.


Вот и объясните какой общепринятый способ архитектурного дизайна для функциональных программ. А уж сосредоточиться на задаче — это моя забота.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 13:50
Оценка:
Спасибо за развернутый ответ, но, к сожалению, Вы в основном отвечали не на мой вопрос. Уж извините.

Мне главное понять КАК я должен строить АРХИТЕКТУРУ функциональных приложений и возможно ли это в принципе. Пока что (почитав примеры дизайна из Ваших ссылок) я вижу что для построения крупномасштабной архитектуры функциональщики вынуждены бить систему на модули с внутренним состоянием и передавать абстрактные типы данных. Все это очень хорошо, но это типичный OOD подход. Как он кореллирует с FP — я без понятия.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 13:55
Оценка:
Здравствуйте, FR, Вы писали:

FR>Посмотри тут http://rsdn.ru/forum/decl/2720396.flat.aspx
Автор: Gaperton
Дата: 06.11.07
неплохой пример ФП дизайна на Эрланге.


Там описан пример решения маленькой задачи с строго определенным входом, строго определенным выходом и без внутреннего состояния. Это совершенно никак не похоже на крупномасштабные (ну ладно уж крупномасштабные, даже просто среднемасштабные) проекты в которых внутренее состояние системы является значимым.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 13:59
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Мне понравилось, как Армстронг изложил подход к программированию (на Эрланге) в своей диссертации: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.408 . Вкратце:


Да, спасибо, упомянутую работу я читал несколько лет назад. Но, насколько я помню, товарищ Армстронг таки толком не останавливался на конкретике и на хранении состояния (mnesia она априори под рукой). Впрочем я могу и ошибаться. Стоит перечитать ?
Re: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 14:14
Оценка:
Собстывенно 6 лет назад я уже поднимал похожую тему (http://rsdn.ru/forum/philosophy/930970.aspx
Автор: Borisman2
Дата: 04.12.04
). Вынужден констатировать что воз и поныне там: каждый кулик хвалит свое маленькое болотце, свои маленькие функции, классы, типы или монады, но никто не может охватить полностью (хотя бы приближенно) картину "с высоты птичьего полета" и объяснить как же все эти концепции (ООП, FP, event-driven, ...) увязать между собой построив высокоуровневую (в смысле детализации) архитектуру большой промышленной системы.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 14:17
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ему следует стараться минимизировать число компонент с изменяемым состоянием.


Это хорошие, верные, но слишком общие слова. Мне такжке следует разрабатывать хорошие программы. И вообще, правильно жить.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 14:20
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Вот последнее время ковыряю Pure. Это тоже динамика. И его вот уже более корректно с Хаскелем сравнивать. Кстати, expression problem там решен


Задумайтейсь о том что случится когда Вам надоест "ковырять" и захочется что-то реальное написать. Вы столкнетесь с теми же проблемами что и я. "Ковырял" я довольно долго, лет примерно 8. Теперь хочется применить.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 17.11.10 14:30
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Вот и объясните какой общепринятый способ архитектурного дизайна для функциональных программ. А уж сосредоточиться на задаче — это моя забота.


Так вы объясните саму задачу и используемые технологии; у кого был соответствующий опыт — поделятся Смысл использовать ФП ради использования ФП?
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 17.11.10 14:54
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Задумайтейсь о том что случится когда Вам надоест "ковырять" и захочется что-то реальное написать. Вы столкнетесь с теми же проблемами что и я. "Ковырял" я довольно долго, лет примерно 8. Теперь хочется применить.


И за 8 лет вы "не наковыряли" ни одного real world приложения на ФЯ?
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 15:39
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>И за 8 лет вы "не наковыряли" ни одного real world приложения на ФЯ?


Да, это удивительно, но не наковырял. Более того, не наковырял даже проектной документации ни для одного большого рилворлдного ФП приложения. Единственное что мне известно из подобных проектов — это Erlang, но по определенным причинам это не самый удачный пример.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 15:40
Оценка:
Здравствуйте, IT, Вы писали:

IT>Именно. FP рулит внутри метода, ООП — вне.


А как же все заверения адептов что FP мол надо широко применять как отдельную (от ООП) парадигму ?
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 17.11.10 16:27
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Хорошо, мне хочется разработать обычное трехзвенное веб-приложение. Если бы я применял OOD я уже и без этой информации в точности знал бы с чего начать.


Если неизвестно как сюда прикрутить ФП, не определились с технологиями/фреймворком/языком — зачем тут ФП?

B>Смысл исполльзования ФП ради ФП состоит в том чтобы на примере научиться пользоваться этой парадигмой, причем желательно в крупном масштабе (не на уровне отдельного модуля).

Кмк вы чуть-чуть опередили время ФП пока не мэйнстрим, поэтому привычного "превед! вот тебе фреймворк, вот тру-книжка, вот форум с кучей фанатов, видишь как всё просто!" нет.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 17:07
Оценка:
Здравствуйте, borisman3, Вы писали:

FR>>Посмотри тут http://rsdn.ru/forum/decl/2720396.flat.aspx
Автор: Gaperton
Дата: 06.11.07
неплохой пример ФП дизайна на Эрланге.


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


Ну грязь там есть в виде IO и она изолирована в отдельный модуль.
Ну и там вполне продемонстрировано то, что применяется и при декомпозиции больших программ: модульность, абстрактные типы данных,
функциональные интерфейсы. Да все это взято из модульного структурного программирования, как и в случае ООД/ООП.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 17:10
Оценка:
Здравствуйте, borisman3, Вы писали:


B>Это хорошие, верные, но слишком общие слова. Мне такжке следует разрабатывать хорошие программы. И вообще, правильно жить.


Нет не общие слова, а один из базовых паттернов, во всяком случае в строгих гибридных ФЯ.
Основная масса программы должна быть функционально чистой, вся грязь изолироваться в небольших отдельных
модулях/функциях.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:30
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, borisman3, Вы писали:


IT>Заявлять можно что угодно, никто этого не запрещает. Только какой смысл отказываться от бенефитов которые даёт ООП. Так же нет смысла отказываться от бенефитов ФП. Тем более, что они между собой никак не конфликтуют и великолепно уживаются вместе.


Для ООП существует отработанная методология разработки архитектуры — OOD. Теоретически она настолько общая, что, конечно, не предполагает на чем конкретно и в каком конкретно стиле будет написан тот или иной модуль. Но практически она заточена на ООП, классы, поведение, состояния. Я надеялся что есть некая альтернативная методология более подходящая для FP, но увы.

Микшировать ООП и FP это тоже конечно жизнеенный подход, но хотелось как раз pure fp.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:32
Оценка:
Здравствуйте, FR, Вы писали:

FR>FP чтобы быть отдельной парадигмой ни в каком ООП не нуждается, достаточно модульности.


Постойте, постойте. Мне кажется, я знаю. Сначала Вы говорите модульность. Затем Вы скажете что у модулей МОЖЕТ быть состояние. Затем Вы скажете "абстрактные типы данных". Поправьте меня, где я ошибся ?
Re[9]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:43
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

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

ВВ>В действительности ситуация довольно простая. Есть задачи, которые хорошо ложатся на ФП. Если задачу можно представить в виде: данные на входе — цепочка трансформаций — данные на выходе, то это как раз оно и есть. На веб в принципе такая схема неплохо ложится. А есть задачи, которые на ФП не ложатся. Вы их можете попробовать решать на ФЯ, но наверное получится хуже, чем на ООЯ. В большом проекте задач обычно много и разных. Разделяете все на отдельные модули — какие-то можно разрабатывать в рамках ФП, какие-то — с использованием ООП. Ну вот, собственно, и все.

То есть Вы предлагаете мне мешать между собой обе парадигмы (пусть между модулями а не внутри) ? Теоретически оно конечно хорошо, а на практике попробуйте-ка скажем напишите кусок на Сlojure а кусок на Java (и это, поверьте не самый стращный пример, т.к. Clojure очень хорошо интегрируется с Java). Получится тот еще Франкенштейн. С практической точки зрения может выйти так что Вам проще было бы написать все в одном едином стиле.
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:45
Оценка:
B>То есть Вы предлагаете мне мешать между собой обе парадигмы (пусть между модулями а не внутри) ? Теоретически оно конечно хорошо, а на практике попробуйте-ка скажем напишите кусок на Сlojure а кусок на Java (и это, поверьте не самый стращный пример, т.к. Clojure очень хорошо интегрируется с Java). Получится тот еще Франкенштейн. С практической точки зрения может выйти так что Вам проще было бы написать все в одном едином стиле.

В любом случае получается так что я ВЫНУЖДЕН во главу угла ставить OOD (а, значит и OOP), а функциональные модули как-то подпиливать и подтачивать под общий знаменатель. Не нравится мне это. Будет кривое решение.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:50
Оценка:
Здравствуйте, FR, Вы писали:

FR>Нет не общие слова, а один из базовых паттернов, во всяком случае в строгих гибридных ФЯ.

FR>Основная масса программы должна быть функционально чистой, вся грязь изолироваться в небольших отдельных
FR>модулях/функциях.

Это все опять же хорошие слова. Но получается что другого выхода как начать дизайн архитектуры системы с OOD у меня нет ? Там дальше пытаться в этом дизайне выделить "грязный" модуль (что может быть совершенно противоестественно для дизайна, да и не всегда возможно).
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 17.11.10 17:55
Оценка:
Здравствуйте, IT, Вы писали:

IT>В общем, забей Используй ФП там где оно даёт эффект тебе лично, а не там где про него рассказывают умные дядьки.


Да так оно скорее всего и случится. Просто была надежда что найдется умный дядька у которого есть готовое решение на все случаи жизни. Вон ведь, у объектных дядек оно ведь есть, даже целая методология под него подведена, думал мож и у функциональных есть... эх, мечты, мечты...
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 18:05
Оценка:
Здравствуйте, borisman3, Вы писали:

S>>Я бы сначала сосредоточился на задаче и на наиболее подходящих инструментах, а уж затем использовал выбранные инструменты общепринятым способом.


B>Вот и объясните какой общепринятый способ архитектурного дизайна для функциональных программ. А уж сосредоточиться на задаче — это моя забота.


Для строгих языков все просто, верхний уровень, также как и в структурном программировании, модули, притом модули не на уровне
си/паскаля а более развитые, поддерживающие параметризацию http://en.wikipedia.org/wiki/Standard_ML#Module_system
Чуть ниже коренные отличия от структурного программирования, основными кирпичиками служат не связка типы данных + функции (
Виртовское алгоритмы + структуры данных = программы) а ФВП и комбинаторы, они обеспечивают гораздо большую инкапсуляцию, повторное использование
и декомпозицию чем средства традиционного императивного структурного программирования, ну и плюс потоки или ленивость. Как пример можно
посмотреть http://thelema.github.com/batteries-included/hdoc/BatEnum.html где все это используется.

Вообще для высокоуровневого дизайна используется та же структурная декомпозиция как и в модульном структурном программировании
или в ООД. Вот кирпичики для нее разные получаются:

В модульном структурном программировании:
. модули
. функции и несложные типы данных.

В функциональном строгом
. параметризованные модули
. ФВП и комбинаторы
. сложные вариантные типы

В ООД
. модули
. классы и объекты
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 17.11.10 18:13
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Так бывает как минимум не всегда — в больших проектах всегда есть часть, отвечающая за персистентность. Представьте что у Ващей программы есть как минимум один модуль целиком посвящен хранению состояния. Допустим даже что остальные модули полностью stateless. Вы можете написать их используюя FP подход, но как вы поступите с тем самым грязным вредным модулем ? Скажете что это не задача для FP ?


Никак ни поступлю, в строгих ФЯ грязные модули будут всегда. В ленивых стараются делать вид что их нет
Ну и из этого следует цель не избавится от грязи, в строгих языках это невозможно, а минимизировать и
изолировать эту грязь.
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 17.11.10 18:26
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Вы уж простите, товарищ lomeo, что я выскажусь несколько огульно, но у меня складывается впечатление (очень надеюсь что ошибочное) что когда FP-программистам задаешь вопрос о крупномасштабной архитектуре (presentation tier + buisenss logic tier + integration/persistence tier + resource tier) они вместо прямого ответа начинают песню либо о типах, либо о монадах, т.е. о достаточно мелких детялях.


Мелких? ОК, давай на примере. Для достижения каких целей нужен, например, persistance layer? Каким способом их можно добиться с помощью ОО?

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


Я привёл кучу ссылок на то, как строятся подобные приложения. Это ссылки на то, как строить куски, и на то, как из кусков собираются приложения. Этого недостаточно?
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gbear Россия  
Дата: 18.11.10 05:02
Оценка:
Здравствуйте, FR, Вы писали:

FR>Посмотри тут http://rsdn.ru/forum/decl/2720396.flat.aspx
Автор: Gaperton
Дата: 06.11.07
неплохой пример ФП дизайна на Эрланге.


А там таки есть _дизайн_ в каком-то формальном виде?! Имхо, все что там есть — это реализация некоторой идеи (дизайна). Которая, кстати, формально не выражена, а описана на естественном языке.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 18.11.10 05:28
Оценка:
Здравствуйте, FR, Вы писали:

FR>Нет не общие слова, а один из базовых паттернов, во всяком случае в строгих гибридных ФЯ.

FR>Основная масса программы должна быть функционально чистой, вся грязь изолироваться в небольших отдельных
FR>модулях/функциях.

Так этот подход и в ООП прекрасно работает. Основная часть логики реализуется в виде статических функций без побочных эффектов, а классы кода логики практически не содержат и используются для хранения данных и вызова этих статических функций. Только не понятно какое отношение утверждение, что в программе должно быть минимум сеттеров и сеттеры должны изолироваться от остального кода, имеет к вопросу топик-стартера. Архитектура приложения в этом случае остается вполне ООП, а на функции возлагается только черновая работа.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 18.11.10 05:35
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Так бывает как минимум не всегда — в больших проектах всегда есть часть, отвечающая за персистентность. Представьте что у Ващей программы есть как минимум один модуль целиком посвящен хранению состояния. Допустим даже что остальные модули полностью stateless. Вы можете написать их используюя FP подход, но как вы поступите с тем самым грязным вредным модулем ? Скажете что это не задача для FP ?


В этом случае модуль имеющий состояний реализуем в ООП-стиле, остальные модули в виде статических функций без побочных эффектов. В результате получаем код высочайшего качества, т.е. такой с которым в дальнейшем очень просто работать. И естественно никаких супер-пупер функциональных языков для такой реализации не нужно, вполне достаточно языка, который позволяет легко совмещать ООП-стиль и функциональный стиль, т.е. того же С#.
Re[9]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 08:01
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Но не в этом суть. Почему Вы все время пытаетесь свести разговор о крупной многопомпонентной, многозвенной системе к какой-то одной ее компоненте ?


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

Чтобы всё было описано в одном месте (как, например, для J2EE) — не встречал. Поэтому даю ссылки по отдельным частям (слои, связи, паттерны).

Надеюсь, я ответил на вопрос.
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gbear Россия  
Дата: 18.11.10 08:51
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Теперь я не понимаю. В случае ФП слои будут другими что-ли?


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

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


Не-не... понятно, что "и данные надо хранить, и бизнес-логика у нас есть". Ключевой момент в том, что с "точки зрения" парадигмы FP есть слой (layer)? Или слой это понятие настолько фундаментальное что оно вне какой-либо парадигмы?
Второй момент, характер взаимодействия (т.е. отношений между сущностями) в FP все таки другой. Точнее даже так... он может быть совершенно другим... не укладываться в "классику".

Например, почему "классически" BL и DL не взаимодействуют? Т.е. отношения между ними ассоциативные. Почему?
Нет... я осознаю disadvantage взаимодействия DL и DL... но таки в терминах OOD
А вот если хоть какой-то advantage от ассоциативности отношения BL/DL при условии что и BL, и DL, "на пальцах", реализованы на FP — я не уверен.
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 09:15
Оценка:
Здравствуйте, gbear, Вы писали:

G>А вот что бы ответить на этот вопрос, нужно ответить на другой. А именно, чем вызвано именно _такое_ ("классическое") разделение на слои? А вдруг выяснится, что оно вызвано применением OOD


Есть принцип — разделяй и властвуй. Одна штука (объект, процесс, функция) — одна функциональность. Почему именно такие подзадачи? Ну так задача такая — написать опердень.

G>Не-не... понятно, что "и данные надо хранить, и бизнес-логика у нас есть". Ключевой момент в том, что с "точки зрения" парадигмы FP есть слой (layer)? Или слой это понятие настолько фундаментальное что оно вне какой-либо парадигмы?


Я думаю вне. FP — это же всего лишь инструмент. Слой — абстракция, она только в голове у программиста. Какое воплощение она получит в коде зависит от программиста и инструмента.

G>Второй момент, характер взаимодействия (т.е. отношений между сущностями) в FP все таки другой. Точнее даже так... он может быть совершенно другим... не укладываться в "классику".

G>Например, почему "классически" BL и DL не взаимодействуют? Т.е. отношения между ними ассоциативные. Почему?

Не понял ни мысль о характере взаимодействия, ни пример. BL строится над интерфейсом DL. Зачем здесь говорить о FP/OO не понимаю — пояснишь?

G>Нет... я осознаю disadvantage взаимодействия DL и DL... но таки в терминах OOD

G>А вот если хоть какой-то advantage от ассоциативности отношения BL/DL при условии что и BL, и DL, "на пальцах", реализованы на FP — я не уверен.

Тоже не понял. Разверни, пожалуйста.
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 09:33
Оценка:
Здравствуйте, gbear, Вы писали:

Поясню своё поведение Изначально я думал, что речь идёт о дизайне и применимости ФП в нём. Затем всё скатилось к multitier — декомпозиции гораздо более высокого уровня. Реализация отдельных слоёв в OO/FP/whatever не поменяет само разбиение на эти слои — абстракция от деталей работает. А значит смысла их связывать просто нет.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gbear Россия  
Дата: 18.11.10 09:57
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, gbear, Вы писали:


G>>А вот что бы ответить на этот вопрос, нужно ответить на другой. А именно, чем вызвано именно _такое_ ("классическое") разделение на слои? А вдруг выяснится, что оно вызвано применением OOD

L>Есть принцип — разделяй и властвуй. Одна штука (объект, процесс, функция) — одна функциональность. Почему именно такие подзадачи? Ну так задача такая — написать опердень.

Именно что "почему именно такие подзадачи?"... потому, что от того _как_ (условно, каким методом) мы будем решать основную задачу, будет сильно зависеть и набор подзадач. Разве нет?!

G>>Не-не... понятно, что "и данные надо хранить, и бизнес-логика у нас есть". Ключевой момент в том, что с "точки зрения" парадигмы FP есть слой (layer)? Или слой это понятие настолько фундаментальное что оно вне какой-либо парадигмы?

L>Я думаю вне. FP — это же всего лишь инструмент. Слой — абстракция, она только в голове у программиста. Какое воплощение она получит в коде зависит от программиста и инструмента.
Да это-то понятно В смысле, что "в голове у программиста". Важны принципы, по которым мы принимаем решение о наличие/отсутствии того или иного слоя в системе.

G>>Например, почему "классически" BL и DL не взаимодействуют? Т.е. отношения между ними ассоциативные. Почему?

L>Не понял ни мысль о характере взаимодействия, ни пример. BL строится над интерфейсом DL. Зачем здесь говорить о FP/OO не понимаю — пояснишь?

"Классически" между BL и DL "лежит" еще один слой... о нем вы с Борисом говорили двумя постами выше. Наличие этого слоя определено характером взаимодействий между сущностями, допускаемого в "классике". Так понятней?

G>>Нет... я осознаю disadvantage взаимодействия DL и DL... но таки в терминах OOD

G>>А вот если хоть какой-то advantage от ассоциативности отношения BL/DL при условии что и BL, и DL, "на пальцах", реализованы на FP — я не уверен.

L>Тоже не понял. Разверни, пожалуйста.


На пальцах, как вы себе представляете, например, "DAO" в FP И самое главное, какую задачу оно будет решать в описанных выше условиях.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gbear Россия  
Дата: 18.11.10 10:05
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Поясню своё поведение Изначально я думал, что речь идёт о дизайне и применимости ФП в нём. Затем всё скатилось к multitier — декомпозиции гораздо более высокого уровня. Реализация отдельных слоёв в OO/FP/whatever не поменяет само разбиение на эти слои — абстракция от деталей работает. А значит смысла их связывать просто нет.


Ну как бы, имхо, оно и сейчас идет от дизайне. Просто то, с чем я столкнулся в последний год, наводит меня на мысль, что "тупой" перенос "классического" макроуровня архитектуры системы — не работает.
Re[13]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 12:31
Оценка:
Здравствуйте, gbear, Вы писали:

G>Именно что "почему именно такие подзадачи?"... потому, что от того _как_ (условно, каким методом) мы будем решать основную задачу, будет сильно зависеть и набор подзадач. Разве нет?!


На таком уровне, мне кажется, нет.

G>>>Например, почему "классически" BL и DL не взаимодействуют? Т.е. отношения между ними ассоциативные. Почему?

L>>Не понял ни мысль о характере взаимодействия, ни пример. BL строится над интерфейсом DL. Зачем здесь говорить о FP/OO не понимаю — пояснишь?
G>"Классически" между BL и DL "лежит" еще один слой... о нем вы с Борисом говорили двумя постами выше. Наличие этого слоя определено характером взаимодействий между сущностями, допускаемого в "классике". Так понятней?

Э... О терминах — для меня persistence layer и DAL — синонимы. Ну может PL мы используем, когда больше говорим о транзакциях.

В любом случае — я не до сих пор не понимаю. Что такое "характер взаимодействий между сущностями"? Как он относится к слоям и как к реализации? Имеют ли эти отношения связь?

L>>Тоже не понял. Разверни, пожалуйста.

G>На пальцах, как вы себе представляете, например, "DAO" в FP И самое главное, какую задачу оно будет решать в описанных выше условиях.

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

Пример
data UserDAO m a = ...
instance (Monad m) => Monad (UserDAO m)
instance MonadTrans UserDAO

getOrRegisterUser :: String -> UserDAO m a -- "получаем" доступ к DAO
-- или так :: String -> m UserDAO a -- зависит от организации трансформера
getOrRegisterUser name = do
    user <- getUser name
    case user of
        Just existentUser -> return existentUser
        Nothing ->
            let newUser = makeUser name in do
                registerUser newUser
                return newUser
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 14:30
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, borisman3, Вы писали:


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


Нет, отчего же пофлеймить, я достаточно редко пишу на этот форум и только по тем вопросам которые действительно никак не могу самолично разрешить. Непонимание же это не моя цель, это моя беда. Что же касается моего комментария по поводу предыдущего (6ти летней давности) поста — дак это не камень в Ваш ошород, вопрос-то тоже был не из простых и ответа вразумительного я не получил скорее всего по той простой причины что нет его, ответа и вовсе. И никого я ни разу не пытался принизить, что Вы. Если Вам так показалось, прошу прощения, даже в мыслях не было.

L>Ну что ж! Если вы за 8 лет ковыряния не удосужились использовать изучаемые практики, то, конечно же, на то, что другие примерно за такое же время ковыряния их применяли и применяют, можно просто закрыть глаза — ведь ФП дизайна нет. Это очень логично.


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

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

В случае если Вы будете проектировать систему исходя из OOD методологии, подразумевая что на уровне реализвации все это будет реализовано в виде ООП программы Вы твердо знаете что и в какой последовательности делать. В случае если Вы хотите чтобы проектируемая система была более функциональной ( в смылсе FP) у Вас сразу возникнет масса вопросов: а возможно ли ? ... а не будет проще ли?... а если ли общепринятые методики ?...
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 14:35
Оценка:
Спасибо. Собственно ради Вашего ответа уже стоило открывать тему.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 14:51
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Здравствуйте, lomeo, Вы писали:


L>>Здравствуйте, borisman3, Вы писали:


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


Вы поймите, оттого что Вы закидаете меня ссылками на системы типов в FP и как это хорошо Вы не ответите на мой вопрос. Не надо также доказывать мне преимущества FP я вроде как в них и так верю. Я был бы счастлив если бы кто-то ткнул меня носом в методологию проектирования FP-систем, но, видно, таковой не существует.
Re[4]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 15:07
Оценка:
Здравствуйте, borisman3, Вы писали:

B>В случае если Вы будете проектировать систему исходя из OOD методологии, подразумевая что на уровне реализвации все это будет реализовано в виде ООП программы Вы твердо знаете что и в какой последовательности делать. В случае если Вы хотите чтобы проектируемая система была более функциональной ( в смылсе FP) у Вас сразу возникнет масса вопросов: а возможно ли ? ... а не будет проще ли?... а если ли общепринятые методики ?...


Я не писал энтерпрайз на Haskell, вряд ли тут кто-то вообще писал. Из известных мне проектов такого уровня я могу вспомнить только galois.

Тем не менее я до сих пор не пойму, что не так с теми предложениями, которые я сделал. У меня не возникает вопросов, я примерно представляю как бить задачу. Так же, как и в случае OOD — абстракции рулят. Вы видите проблему? В чём? Нет методологии? Есть практики — соберите их в свою методологию и пробуйте.

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

сеть <- библиотека для описания протокола <- протокол -> обработчики комманд
работа с БД <- data layer <- BL <- обработчики комманд
работа с конф. файлами <- абстрактная настройка <- BL

Каждая часть отдельна от других, некоторые так вообще были вынесены в отдельные библиотеки. Зависимостей мало. Наибольший интерес представляет собой BL — и вот его декомпозицию я и называю дизайном, а всё остальное архитектура, которая снаружи могла бы выглядеть точно так же и с другими инструментами.
Re[2]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 15:18
Оценка:
Здравствуйте, gbear, Вы писали:

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


Я такие проекты встречал и на ОО, это не показатель.

G>Тут как бы дело такое... "симулировать OOP на FP языке" — в смысле, добиваться однозначного соответствия между сущностями одной парадигмы, сущностям другой — смысла особого нет. Просто аналога OOD в FP в данный исторический момент вроде как не наблюдается (я плохо искал?). Но фундаментальный принципы дизайна — они фундаментальны жеж Просто как во времена оны приходится несколько извращаться, пытаясь формализовать идеи мыслимые в одной парадигме, инструментами "заточенными" под другую. Т.е. как бы "язык" уже есть, а "письменность" еще не изобрели


Я вот что подумал, может начнём спускаться вниз, на тот уровень, на котором буковки OO в OOD начинают работать, и посмотрим на разницу? Ну вот DAL, например, будет и там и там, а вот DAO будут уже выглядеть по разному
Re: Всем
От: Wolverrum Ниоткуда  
Дата: 18.11.10 15:35
Оценка:
спасибо за очень полезные ссылки
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 18.11.10 15:48
Оценка:
Здравствуйте, Undying, Вы писали:

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


Конечно "работает" также как например функциональное программирование в C++ или ОО в Си.
Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля
и не представляют контроля компилятором иммутабельности (кроме убого const в С++).
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Mr.Cat  
Дата: 18.11.10 16:14
Оценка:
Здравствуйте, borisman3, Вы писали:
B>товарищ Армстронг таки толком не останавливался на конкретике и на хранении состояния
Под хранением состояния, емнип, Армстронг понимал "хранение состояния процесса", без детализации, из чего именно оно состоит. Ты под состоянием понимаешь вроде как нечто другое: данные о сущностях предметной области, отображаемые на некие записи в хранилище данных. В таком случае твой вопрос касается того, как на ФЯ выразить предметную область и реализовать нечто, аналогичное ORM. Я тебя правильно понял? А то без взаимопонимания мы долго будем кругами ходить.

В целом, мне кажется, что многое из ООП пригодится тебе и, например, в эрланге (хаскеле, кложе и пр.). Например, эрлангоподобные системы (с процессами/агентами/актерами и прочей атрибутикой) иногда называют object-based и от object-oriented отличают только отсутствием механизма наследования. Ну т.е. процесс — это объект с identity, модуль — объектоподобная сущность без identity (как оно там в ООП называется?), tuple — объект без поведения. Соответственно, пригодится весь опыт работы с ОО-языками.
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 17:10
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Я считаю, что методология проектирования энтерпрайза на высоком уровне никаким образом не связана с тем, для FP- или для ОО-системы мы её используем. Представьте крайний случай — С, совсем не объектно-ориентированный язык, как вы будете проектировать систему для него? Будут ли отличия на уровне, о котором мы ведём речь?


Конечно будут! Например возникнут неизбежные module.init() и module.done() в контрактах модулей, будут по всей видимости фасады в виде функций (а не классов).

Только архитектор-астронавт может позволить себе полностью оторваться от реализации и не думать какое бремя он возлагает на разработчиков. Если я разработаю систему обмена сообщениями в виде классов, а людям придется эмулировать классы в виде С структур, то, значит, я сделал не очень хорошую работу...
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 18.11.10 17:16
Оценка:
Здравствуйте, lomeo, Вы писали:


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


L>сеть <- библиотека для описания протокола <- протокол -> обработчики комманд

L>работа с БД <- data layer <- BL <- обработчики комманд
L>работа с конф. файлами <- абстрактная настройка <- BL

Как Вы описывали контракты между кусками ? Просто как набор функций (возможно, высшего порядка) + абстрактные типы ? Формально ? Неформально ?
Re[6]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 18.11.10 17:34
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Как Вы описывали контракты между кусками ? Просто как набор функций (возможно, высшего порядка) + абстрактные типы ? Формально ? Неформально ?


Зависит от кусков. Активно пользовался стеком своих монад. В случае библиотеки для создания протокола — набор комбинаторов. Старался сводить свои типы к категориальным. Формально/неформально здесь означает что?
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 08:50
Оценка:
Здравствуйте, FR, Вы писали:

FR>Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля

FR>и не представляют контроля компилятором иммутабельности (кроме убого const в С++).

Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 19.11.10 09:08
Оценка:
Здравствуйте, Undying, Вы писали:

FR>>Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля

FR>>и не представляют контроля компилятором иммутабельности (кроме убого const в С++).

U>Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?


Ничего ни нужно также как и в си для работы в ООП стиле есть все что нужно и структуры и указатели на функции.
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 19.11.10 09:12
Оценка:
Здравствуйте, Undying, Вы писали:

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


FR>>Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля

FR>>и не представляют контроля компилятором иммутабельности (кроме убого const в С++).

U>Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?

Подозреваю, невозможность изменения mutable-значений В принципе можно сделать на коленке (через Code Analysis custom rules), само по себе несложно, но immutable-код получится довольно убогим (никаких виртуальных вызовов/делегатов).
Re[9]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 11:11
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Подозреваю, невозможность изменения mutable-значений


Ты о том что внутри функции нельзя объявлять иммутабельные переменные? Так внутри функции и так прекрасно видно кто мутабельный, а кто не мутабельный (при нормальном стиле кодирования, конечно), кода-то мало и он легко охватывается взглядом. На практике проблемы возникают только с переменными классов, но для них в шарпе есть readonly.

S>В принципе можно сделать на коленке (через Code Analysis custom rules), само по себе несложно, но immutable-код получится довольно убогим (никаких виртуальных вызовов/делегатов).


Не понял какое отношение виртуальные вызовы и делегаты имеют к мутабельности/иммутабельности кода. Разве это не ортогональные вещи?
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 11:46
Оценка:
Здравствуйте, samius, Вы писали:

S>На практике меньше всего проблем с полями классов, т.к. запись в них можно контроллировать и без readonly.


И как это можно гарантировать? На каждый чих жать "Find All Reference" и смотреть глазами точно ли переменная нигде не менялась? Если заняться не чем можно и так, но гораздо правильнее использовать readonly.

S>Но что толку от иммутабельного поля-ссылки на немутабельный класс в насквозь мутабельном фреймворке?


Какое отношение написание, к примеру, бизнес-логики имеет к фрамеворку? У вас что основной код это использование фрамеворка что ли?

S>Единственный способ гарантировать иммутабельность — обертки с исключениями.


Исключения-то в обертках зачем? Ну есть во фрамеворке класс с getter'ами и setter'ами, мы поверх этого класса написали обертку и все сеттеры из публичного интерфейса убрали. Зачем здесь исключения?
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 19.11.10 11:48
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Sinix, Вы писали:


S>>Подозреваю, невозможность изменения mutable-значений


U>Ты о том что внутри функции нельзя объявлять иммутабельные переменные?


Нет, я о таком:
    // Data types.
    [Immutable]
    class ImmutableSample
    {
      public ImmutableSample(int i)
      {
        I = i;
      }

      public int I { get; set; }
      
      public void A()
      {
        I++; // Warning.
      }
    }

    class MutableSample
    {
      public ImmutableSample(int i)
      {
        I = i;
      }

      public int I { get; set; }
      
      public void A()
      {
        I++;
      }
    }

    // Samples.
    void Test()
    {
      ImmutableSample a = new ImmutableSample(42);

      a.I = 10; // Warning.
      a.A(); // Warning.
    }

    void Test([Immutable]MutableSample sample)
    {
      sample.I = 123; // Warning.
      sample.A(); // Warning.
    }

    int i;
    [Immutable(ImmutableState = true)]
    void Test2()
    {
      i = 10; // Warning,
    }

    [Immutable(NoSideEffects = true)]
    void Test3(Action callback)
    {
      Environment.CurrentDirectory = "blabla"; // Warning, but a lot of false positives;

      int i = GetHashCode(); // Virtual call warning, but a lot of false positives;

      callback(); // Delegate call warning, but a lot of false positives;
    }

Технически ничего сложного, но весьма муторно в реализации и абсолютно бесполезно на практике.

S>>В принципе можно сделать на коленке (через Code Analysis custom rules), само по себе несложно, но immutable-код получится довольно убогим (никаких виртуальных вызовов/делегатов).


U>Не понял какое отношение виртуальные вызовы и делегаты имеют к мутабельности/иммутабельности кода. Разве это не ортогональные вещи?


Нет, просто проверки наподобие показанных выше не могут гарантировать, что делегаты/виртуальные вызовы не поменяют состояние объекта.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.11.10 11:54
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>На практике меньше всего проблем с полями классов, т.к. запись в них можно контроллировать и без readonly.


U>И как это можно гарантировать? На каждый чих жать "Find All Reference" и смотреть глазами точно ли переменная нигде не менялась? Если заняться не чем можно и так, но гораздо правильнее использовать readonly.


Я же не настаиваю. Хочешь — пиши. Только если поля у класса скрыты, то что readonly есть, что его нет, все одно. В плане будущих изменений — да, помогает.

S>>Но что толку от иммутабельного поля-ссылки на немутабельный класс в насквозь мутабельном фреймворке?


U>Какое отношение написание, к примеру, бизнес-логики имеет к фрамеворку? У вас что основной код это использование фрамеворка что ли?

да, грешен. Использую структуры данных из фреймворка.

S>>Единственный способ гарантировать иммутабельность — обертки с исключениями.


U>Исключения-то в обертках зачем? Ну есть во фрамеворке класс с getter'ами и setter'ами, мы поверх этого класса написали обертку и все сеттеры из публичного интерфейса убрали. Зачем здесь исключения?


Попрошу сделать обертку для Dictionary<TKey, TValue>, что бы не кидала исключений, сохраняла интерфейс и вообще вела себя как IDictionary<TKey, TValue>. Может ответ сам найдется...
Re[13]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 12:27
Оценка:
Здравствуйте, samius, Вы писали:

S>Я же не настаиваю. Хочешь — пиши. Только если поля у класса скрыты, то что readonly есть, что его нет, все одно. В плане будущих изменений — да, помогает.


На самом деле readonly полезно и в этом случае, т.к. при чтении кода сразу видно, что класс иммутабельный и переданные в конструкторе значения никогда не изменяются. Чтение кода заметно упрощается.

S>Попрошу сделать обертку для Dictionary<TKey, TValue>, что бы не кидала исключений, сохраняла интерфейс и вообще вела себя как IDictionary<TKey, TValue>. Может ответ сам найдется...


На практике для Dictionary меня устраивает следующее решение:

  static public class DictionaryHlp3
  {
    public static TValue FindObject<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TValue : class
    {
      if (key != null)
      {
        TValue value;
        if (dictionary.TryGetValue(key, out value))
          return value;
      }
      return default(TValue);
    }
    public static TValue? FindValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TValue : struct
    {
      if (key != null)
      {
        TValue value;
        if (dictionary.TryGetValue(key, out value))
          return value;
      }
      return null;
    }
  }


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

Но в целом я не понимаю смысла в сохранении поддержки IDictionary. Ведь все равно выставлять словари в публичном интерфейсе это плохой стиль, а внутри класса никто не мешает использовать какую-нибудь обертку, которая содержит только некидающие исключение методы, вроде bool Add(key, value) и тех же FindObject и FindValue.

Какие плюсы дает поддержка IDictionary? Я вижу только один — привычность, т.е. как пользоваться IDictionary знает любой программист, а по поводу какого-нибудь SafeDictionary у нового программиста могут возникнуть вопросы. Но это очень небольшая проблема, все равно новому программисту нужно разбираться с классами бизнес-логики, которые он точно также видит в первый раз в жизни как и SafeDictionary.
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 12:31
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Технически ничего сложного, но весьма муторно в реализации и абсолютно бесполезно на практике.


Если честно, то я не понял зачем нужно так извращаться, вместо того, чтобы просто пометить переменную readonly.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 19.11.10 12:37
Оценка:
Здравствуйте, Undying, Вы писали:

U>Если честно, то я не понял зачем нужно так извращаться, вместо того, чтобы просто пометить переменную readonly.

readonly — эт только поле, а сам объект вполне может быть mutable

Кроме того, стоит завести разговор о readonly, как тут же кто-то да ответит, что "в шарпе нет const".
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 19.11.10 13:51
Оценка:
U>Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?

при работе с кодом всегда есть как минимум три мета-операции:
1. выразить мысли разработчика с помощью кода (имеющегося языка программирования)
2. имея код восстановить замысел разработчика
3*. автоматически имея код восстановить замысел разработчика

и соответственно нужно, чтобы:
1. требовалось минимум кода для выражения замысла разработчика
2. требовалось минимум действий, чтобы восстановить замысел разработчика как автоматически, так и в ручную

*автоматический разбор кода требуется из необходимости минимизировать код, который пишется вручную

обеспечить иммутабельность на C#, исходя из п.1 и п.2. просто, хотя бы просто договориться и записать в комментариях, что такие-то массивы и переменные являются иммутабельными.
но обеспечить п.3 на C# очень тяжело, как минимум из-за того, что ни сам фрейморк, ни язык не знает что это такое, и не предоставляет инструментов для работы с иммутабельностью
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: borisman3 Канада http://paskoboris.blogspot.com/
Дата: 19.11.10 14:31
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, borisman3, Вы писали:


B>>Как Вы описывали контракты между кусками ? Просто как набор функций (возможно, высшего порядка) + абстрактные типы ? Формально ? Неформально ?


L>Зависит от кусков. Активно пользовался стеком своих монад. В случае библиотеки для создания протокола — набор комбинаторов. Старался сводить свои типы к категориальным. Формально/неформально здесь означает что?


Прошу прощения за неудобную терминологию.

"формально" — означает что Вы использовали какие-то инструментальные средства контролирующие контракты, причем писали их ДО того как приступить к реализации (в идеале контракты были описаны средствами самого языка, например в виде интерфейсов), т.е. больше в top-down стиле.

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

Я так понял так что Вы выбрали первый подход ?
Re[13]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 17:16
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Кроме того, стоит завести разговор о readonly, как тут же кто-то да ответит, что "в шарпе нет const".


В чем смысл const? Смысл reandonly в том, что показать, что ссылка на переменную не изменялась с момента создания экземпляра класса. Как я понимаю смысл const в том, чтобы показать что ссылка на переменную не менялась с момента компиляции. Объясни чем readonly static для этой цели хуже, чем const?
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinix  
Дата: 19.11.10 17:51
Оценка:
Здравствуйте, Undying, Вы писали:

U>В чем смысл const? Смысл reandonly в том, что показать, что ссылка на переменную не изменялась с момента создания экземпляра класса. Как я понимаю смысл const в том, чтобы показать что ссылка на переменную не менялась с момента компиляции. Объясни чем readonly static для этой цели хуже, чем const?


Забей. Пятница, вечер (по крайней мере у меня) Не лениво препираться по мелочам?
Re[15]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 17:51
Оценка:
Здравствуйте, samius, Вы писали:

S>readonly поля не делают класс иммутабельным и не помогают увидеть его иммутабельность.


Это легко решается административно. Оформляй код класса так, чтобы переменные были объявлены в одном месте и одного взгляда будет достаточно, чтобы понять, что все переменные класса readonly. Хотя в принципе я согласен, что ключевое слово говорящее, что все переменные класса являются immutable было бы полезным, но это не принципиально.

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


Кто мешает создать интерфейс IReadonlySafeDictionary и IMutableSafeDictionary? Лень? В чем проблема-то, неужели средства C# этого не позволяют?

S>Выставлять структуры данных фреймворка плохой стиль именно из-за их мутабельности. Выставлять IList<T> ведь никто не запрещает, если за него ReadOnlyCollection<T>. Наоборот, даже рекомендуют.


Вообще-то это костыль, т.к. видя в публичном интерфейсе IList достаточно сложно понять, что на самом деле коллекция не модифицируема. По уму да в шарпе нужен тот же readonly массив, но на практике это опять же легко решается административно, путем разрешения модификации поля-коллекции объекта только через методы самого объекта, а не коллекции. Но если административный метод по каким-то причинам затруднителен, то никто не мешает создать свои интерфейсы для доступа к коллекциям, которые разрешают только чтение. Опять же средства шарпа это вполне позволяют.

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


Я не понимаю, если это создает проблемы, то в чем проблема отказаться от стандартных интерфейсов? Стандартные решения они что самоценность что ли? Например, выглядел тот же биндинг кривым решением, вместо него написали нормальное иммутабельное, и вот уже лет пять горя не знаем. Если видишь, что на данном классе задач иммутабельные решения работают лучше стандартных, отказываешься от стандартных и реализуешь свои иммутабельные.
й
Re[9]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 19.11.10 18:30
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>*автоматический разбор кода требуется из необходимости минимизировать код, который пишется вручную


Что ты под этим понимаешь? То что ты показывал касалось оптимизаций, в некоторых случаях это, конечно, важно, но в общем случае это второстепенная задача. Решение каких задач, кроме оптимизаций, нам облегчает запись кода в стиле, упрощающем автоматический разбор кода?
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 19.11.10 19:01
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Все ПОЧТИ так как Вы описали. Только почему Вы воспринимаете все так негативно ? Ну умеет человек изготавливать мебель стаместками. Ну хочет попробовать рубанок. Ну объясните ему куда ему не следует совать руки.


Для начала человеку нужно осознать свою болезнь, а уже потом можно подсказывать лечение

Если человек не осознал, то чем быстрее переломает пальцы, тем ему же и лучше.
Re[16]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.11.10 20:25
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>readonly поля не делают класс иммутабельным и не помогают увидеть его иммутабельность.


U>Это легко решается административно. Оформляй код класса так, чтобы переменные были объявлены в одном месте и одного взгляда будет достаточно, чтобы понять, что все переменные класса readonly. Хотя в принципе я согласен, что ключевое слово говорящее, что все переменные класса являются immutable было бы полезным, но это не принципиально.


readonly — лишь тень иммутабельности, административно оно требуется или нет.

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


U>Кто мешает создать интерфейс IReadonlySafeDictionary и IMutableSafeDictionary? Лень? В чем проблема-то, неужели средства C# этого не позволяют?


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

S>>Выставлять структуры данных фреймворка плохой стиль именно из-за их мутабельности. Выставлять IList<T> ведь никто не запрещает, если за него ReadOnlyCollection<T>. Наоборот, даже рекомендуют.


U>Вообще-то это костыль, т.к. видя в публичном интерфейсе IList достаточно сложно понять, что на самом деле коллекция не модифицируема. По уму да в шарпе нужен тот же readonly массив, но на практике это опять же легко решается административно, путем разрешения модификации поля-коллекции объекта только через методы самого объекта, а не коллекции.

Т.е. ты предлагаешь запретить изменять содержимое массива административно?
U>Но если административный метод по каким-то причинам затруднителен, то никто не мешает создать свои интерфейсы для доступа к коллекциям, которые разрешают только чтение. Опять же средства шарпа это вполне позволяют.
Ну вот создал ты свой IMyReadOnlyArray. Ни один метод фреймворка не сможет взять элемент по индексу, если этот интерфейс не расширяет IList. Если расширяет — значит мутирующие методы IList-а должны кидать исключения.

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


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

Напомню, с чего я всрял:

FR>Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля
FR>и не представляют контроля компилятором иммутабельности (кроме убого const в С++).

Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?

Теперь с твоих слов оказалось, что кроме readonly, требуется отказ от классов фреймворка и реализация своих. Компилятор C# однако в этом подвиге не может ничем помочь, кроме как проверки на присвоение полей, которые как-правило private, т.е. под контролем разработчика конкретного класса (который и без того должен быть нацелен на то что бы смопедить класс с невозможностью изменения любых данных, торчащих из него, а не только скрытых полей).
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.11.10 20:40
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Sinix, Вы писали:


S>>Кроме того, стоит завести разговор о readonly, как тут же кто-то да ответит, что "в шарпе нет const".


U>В чем смысл const? Смысл reandonly в том, что показать, что ссылка на переменную не изменялась с момента создания экземпляра класса. Как я понимаю смысл const в том, чтобы показать что ссылка на переменную не менялась с момента компиляции. Объясни чем readonly static для этой цели хуже, чем const?


Речь о сonst из C++, который при должном подходе может навеять дымку иммутабельности целым графам объектов (после его создания).
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 19.11.10 21:30
Оценка:
U>Решение каких задач, кроме оптимизаций, нам облегчает запись кода в стиле, упрощающем автоматический разбор кода?

как минимум все те, что делает C#/.net:
1. перевод на язык исполнителя (процессор): подбор инструкций процессора, раскладка на регистры
2. выбор нужной функции из перегруженных, вывод и подгонка типов
3. генерация кода для частных случаев
4. intellisense
5. run-time линковка
6. reflection
7. совместимость даже между измененными версиями
8. jit
9. gc
10. code access security
11. разруливание циклических зависимостей

и тот же C/C++ не может предложить решений п. 5, п.6, п.8, п.9, п.10, п.11, как раз из-за того, что C/C++-код гораздо хуже поддается автоматическому анализу
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 20.11.10 05:56
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>и тот же C/C++ не может предложить решений п. 5, п.6, п.8, п.9, п.10, п.11, как раз из-за того, что C/C++-код гораздо хуже поддается автоматическому анализу


Тут не только от языка (хотя разбор C++ да кошмар) зависит, а больше от среды исполнения тот же Clang
под LLVM многое из этого умеет хотя это и разновидность C++.
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 20.11.10 06:26
Оценка:
Здравствуйте, Undying, Вы писали:

U>В чем смысл const? Смысл reandonly в том, что показать, что ссылка на переменную не изменялась с момента создания экземпляра класса. Как я понимаю смысл const в том, чтобы показать что ссылка на переменную не менялась с момента компиляции. Объясни чем readonly static для этой цели хуже, чем const?


Смысл const в том что контролируется компилятором и позволят пользоваться как глобально так и локально.
Re[17]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 21.11.10 11:07
Оценка:
Здравствуйте, samius, Вы писали:

S>Напомню, с чего я встрял:

S>

FR>>Но я бы не назвал это "прекрасно работающим" так как мейнстримные ОО языки очень неудобны для такого стиля
FR>>и не представляют контроля компилятором иммутабельности (кроме убого const в С++).

S>Для контроля иммутабельности в C# есть readonly. Что еще нужно-то?

S>Теперь с твоих слов оказалось, что кроме readonly, требуется отказ от классов фреймворка и реализация своих.

S>>>readonly поля не делают класс иммутабельным и не помогают увидеть его иммутабельность.


Речь о чем шла? О языках или фрамеворках? Судя по выделенному, я полагал, что о языках. Как язык C# вполне удобен для смешения ООП и функциональщины. Но фрамеворк С# разрабатывался на волне моды на ООП, поэтому является морально устаревшим. Но так как в фрамеворке нет почти ничего магического, то наиболее проблемные куски из него легко может переписать средствами языка.

S>readonly — лишь тень иммутабельности, административно оно требуется или нет.


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

S>Словарем проблема не ограничивается. А создавать по 2 обертки на каждый мутабельный тип платформы, который может понадобиться в проекте, довольно трудоемко.


Типов, которые используются активно, в шарпе очень не много, по большому счету это только коллекции. Если же говорить о прикладных типах, вроде классов WinForms, то они в большинстве случаев по определению мутабельные, соответственно в лоб сделать их иммутабельными все равно не получится. Но при этом иммутабельная архитектура инкапсулирующуя тот же WinForms пишется не сложно, и объектность контролов там не мешает, и возможно даже более того — для нижнего и соответственно наиболее универсального уровня мутабельные объекты являются наилучшим решением.

S>Т.е. ты предлагаешь запретить изменять содержимое массива административно?


Выставленного в публичном интерфейсе, да. Собственно я всегда так и делаю и ни разу не сталкивался с проблемами.

S>Ну вот создал ты свой IMyReadOnlyArray. Ни один метод фреймворка не сможет взять элемент по индексу, если этот интерфейс не расширяет IList. Если расширяет — значит мутирующие методы IList-а должны кидать исключения.


Это косяк фрамеворка, причем не имеющий никакого отношения к его ООП-оности. Просто разработчики не додумали, и создав толковый IEnumerable и очень жирный IList, не создали ничего промежуточного. А всего-то нужно было в ICollection добавить возможность доступа по индексу на чтение, чтобы он из практически бесполезного типа превратился в один из самых часто используемых.

S>Компилятор C# однако в этом подвиге не может ничем помочь, кроме как проверки на присвоение полей, которые как-правило private, т.е. под контролем разработчика конкретного класса (который и без того должен быть нацелен на то что бы смопедить класс с невозможностью изменения любых данных, торчащих из него, а не только скрытых полей).


Во-первых, readonly поля у меня обычно публичные. И в сеттеры я их если заворачиваю, то только по той причине, что тупой компилятор шарпа не понимает, что поля могут реализовывать интерфейс.

Во-вторых, не понял почему разработчик должен быть "нацелен на то что бы смопедить класс с невозможностью изменения любых данных, торчащих из него, а не только скрытых полей". Разработчик должен решить задачу с минимумом сеттеров, соответственно если по условию задачи от определенного количества сеттеров никуда не деться, то полная иммутабельность невозможна и стремление к ней не нужно.
Re[18]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.11.10 14:02
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Теперь с твоих слов оказалось, что кроме readonly, требуется отказ от классов фреймворка и реализация своих.


U>Речь о чем шла? О языках или фрамеворках? Судя по выделенному, я полагал, что о языках. Как язык C# вполне удобен для смешения ООП и функциональщины. Но фрамеворк С# разрабатывался на волне моды на ООП, поэтому является морально устаревшим. Но так как в фрамеворке нет почти ничего магического, то наиболее проблемные куски из него легко может переписать средствами языка.


Я не считаю что C# удобен для смешения ООП и функциональщины. Разве что однозначно удобнее чем C.
По поводу переписывания фреймворка — ну да, разработчики F#-а пошли этим путем и переписали часть фреймворка. Ты хочешь что бы нечто подобное делали на C# в рамках других проектов, скажем в рамках проекта разработки desktop приложения?

S>>readonly — лишь тень иммутабельности, административно оно требуется или нет.


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

"Позволял" — неудачный термин для иммутабельности. Чистый "C" позволяет создавать иммутабельные структуры данных даже без модификаторов видимости (например на барьерах абстракции).
Языковая поддержка иммутабельности заключается в том, что создавать иммутабельные структуры должно быть легко, никак не тяжелее чем мутабельные.
Как язык C# позволяет создавать иммутабельные структуры. Как на языке в рамках платформы — создавать иммутабельные структуры тяжело. Причем readonly перекрывает собой такую узкую часть иммутабельности, что если бы его и небыло, разница была бы невелика.

U>Типов, которые используются активно, в шарпе очень не много, по большому счету это только коллекции. Если же говорить о прикладных типах, вроде классов WinForms, то они в большинстве случаев по определению мутабельные, соответственно в лоб сделать их иммутабельными все равно не получится. Но при этом иммутабельная архитектура инкапсулирующуя тот же WinForms пишется не сложно, и объектность контролов там не мешает, и возможно даже более того — для нижнего и соответственно наиболее универсального уровня мутабельные объекты являются наилучшим решением.

Тем не менее, создание достаточного набора иммутабельных структур данных на C# — дело небыстрое, потому вряд ли будет оправдано в рамках большинства проектов.

S>>Т.е. ты предлагаешь запретить изменять содержимое массива административно?


U>Выставленного в публичном интерфейсе, да. Собственно я всегда так и делаю и ни разу не сталкивался с проблемами.

Что-то я сомневаюсь, что ты административно можешь запретить изменять содержимое массива, безотносительно того, где он выставлен. Одна из бетта версий второго фреймворка, если мне не изменяет склероз, при приведении типа массива к IList<T> делала его иммутабельным. Но имеющему ссылку на массив запретить его менять нельзя.

U>Это косяк фрамеворка, причем не имеющий никакого отношения к его ООП-оности. Просто разработчики не додумали, и создав толковый IEnumerable и очень жирный IList, не создали ничего промежуточного. А всего-то нужно было в ICollection добавить возможность доступа по индексу на чтение, чтобы он из практически бесполезного типа превратился в один из самых часто используемых.

Я согласен в том что интерфейсы коллекций во фреймворке косячные. Но от идеи добавления доступа по индексу к ICollection не в восторге. Если уж чего и менять (в рамках темы разговора), то это следовало сделать модифицирующие методы не void, а возвращающие ICollection, так что бы мутабельные реализации могли бы возвращать себя же, а иммутабельные — новые структуры. Однако 10 лет назад сложно было предположить о том что массы будут интересоваться FP.

U>Во-первых, readonly поля у меня обычно публичные. И в сеттеры я их если заворачиваю, то только по той причине, что тупой компилятор шарпа не понимает, что поля могут реализовывать интерфейс.

Есть соображения, по которым свойства предпочтительнее readonly полей. И действительно, поля не могут реализовывать интерфейс.

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

Я подразумевал разработчика, нацеленного на создание иммутабельных структур.
Да и в рамках разговора об иммутабельных структурах говорить о минимизации сеттеров неуместно. Ни их, ни модифицирующих методов быть не должно вообще.
Термин "полная иммутабельность" меня улыбнул. Объект не может быть "немножко иммутабельным". Он или иммутабелен, или нет.
Re[19]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 21.11.10 18:50
Оценка:
Здравствуйте, samius, Вы писали:

S>Я подразумевал разработчика, нацеленного на создание иммутабельных структур.

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

Иммутабельность это всего лишь средство, зачем средство превращать в самоцель? Чем код создающий пять иммутабельных экземпляров лучше кода, в котором пять раз меняется поле одного и того же экземляра объекта? Наверное, лучше тем что менее естественен и медленнее работает? Ты вот когда в жизни в чайник воду наливаешь, ты меняешь состояние имеющегося объекта или создаешь новый чайник?

S>Если уж чего и менять (в рамках темы разговора), то это следовало сделать модифицирующие методы не void, а возвращающие ICollection, так что бы мутабельные реализации могли бы возвращать себя же, а иммутабельные — новые структуры.


Кошмар. Зачем для мутабельных и иммутабельных объектов делать общий интерфейс? Чтобы потом по интерфейсу нельзя было понять мутабельный или иммутабельный объект за ним скрывается? Как с этим работать-то?

Слава богу, что разработчики фрамеворка были адептами ООП, потому как адепты функциональщины гораздо хуже.
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 21.11.10 20:05
Оценка:
Здравствуйте, borisman3, Вы писали:

B>"формально" — означает что Вы использовали какие-то инструментальные средства контролирующие контракты, причем писали их ДО того как приступить к реализации (в идеале контракты были описаны средствами самого языка, например в виде интерфейсов), т.е. больше в top-down стиле.


Инструментальные средства не использовал. Писал в top-down стиле — стабы в Haskell писать легко. Интерфейсы выписывал в виде типов, т.к. они обычно чётко декларируют семантику, плюс стараюсь сделать так, чтобы их неправильное использование было невозможным, либо правильное очевидным. В Haskell первое обычно делается очень удобным способом (помимо обычных полиморфных типов — GADTS, RankNTypes, TypeFamilies etc).
Re[20]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.10 03:41
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Я подразумевал разработчика, нацеленного на создание иммутабельных структур.

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

U>Иммутабельность это всего лишь средство, зачем средство превращать в самоцель?

Я ее не превращаю в самоцель. См. выделенное выше.
U>Чем код создающий пять иммутабельных экземпляров лучше кода, в котором пять раз меняется поле одного и того же экземляра объекта?
Я думал что ты знаешь ответ на этот вопрос. http://fprog.ru/2009/issue1/eugene-kirpichov-fighting-mutable-state/
U> Наверное, лучше тем что менее естественен и медленнее работает? Ты вот когда в жизни в чайник воду наливаешь, ты меняешь состояние имеющегося объекта или создаешь новый чайник?
В жизни я использую один чайник. В коде — зависит от задачи. Если требуется вскипятить воду и только — это может быть один чайник. Если требуется узнать была ли вода в чайнике час назад, либо гарантировать что после вызова некоторого кода состояние чайника не изменится, то чайник с изменяемым состоянием мне не подойдет в общем случае. Тогда иммутабельный чайник будет более простым и ясным решением, чем логирующий чайник с запираемым от несанкционированного изменения состоянием.

S>>Если уж чего и менять (в рамках темы разговора), то это следовало сделать модифицирующие методы не void, а возвращающие ICollection, так что бы мутабельные реализации могли бы возвращать себя же, а иммутабельные — новые структуры.


U>Кошмар. Зачем для мутабельных и иммутабельных объектов делать общий интерфейс? Чтобы потом по интерфейсу нельзя было понять мутабельный или иммутабельный объект за ним скрывается? Как с этим работать-то?


Уверен, что ты по IList<T> интерфейсу так же не поймешь, List<T> за ним скрывается или ReadOnlyCollection<T>. Как ты с этим работаешь-то?

U>Слава богу, что разработчики фрамеворка были адептами ООП, потому как адепты функциональщины гораздо хуже.

Ты мне льстишь.
Re[21]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 22.11.10 04:47
Оценка:
Здравствуйте, samius, Вы писали:

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


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

S>Уверен, что ты по IList<T> интерфейсу так же не поймешь, List<T> за ним скрывается или ReadOnlyCollection<T>. Как ты с этим работаешь-то?


Не использую IList в публичном интерфейсе. Именно по той причине, что с этим невозможно работать.
Re[23]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 22.11.10 05:40
Оценка:
Здравствуйте, samius, Вы писали:

U>> Соответственно мне не понятен круг задач, в котором эмуляция мутабельности с помощью пересоздания иммутабельных объектов, работает лучше чем использование мутабельных объектов.

S>В таком случае предлагаю закруглиться.

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

U>>Не использую IList в публичном интерфейсе. Именно по той причине, что с этим невозможно работать.

S>Тогда ничего бы не помешало НЕ использовать и другой IList, возвращающий новый IList в мутирующих методах.

Во-первых, такой подход это прекрасный способ превратить язык и стандартный фрамеворк в набор слабо связанных фич, постепенно разваливающийся под собственной тяжестью. C++ тому наглядный пример.

Во-вторых, интерфейс мутабельного списка (а я только такие и использую) станет менее очевидным, что как-то сложно считать добродетелью.
Re[24]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.10 06:16
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>>> Соответственно мне не понятен круг задач, в котором эмуляция мутабельности с помощью пересоздания иммутабельных объектов, работает лучше чем использование мутабельных объектов.

S>>В таком случае предлагаю закруглиться.

U>Т.е. ты не можешь привести пример, в котором использование цепочки иммутабельных объектов для эмуляции мутабельности выгоднее использования мутабельного объекта?

Не надо брать меня на понт. Я приводил пример и давал ссылку. То что тебе что-то не очевидна выгода — это не мои проблемы.

U>>>Не использую IList в публичном интерфейсе. Именно по той причине, что с этим невозможно работать.

S>>Тогда ничего бы не помешало НЕ использовать и другой IList, возвращающий новый IList в мутирующих методах.

U>Во-первых, такой подход это прекрасный способ превратить язык и стандартный фрамеворк в набор слабо связанных фич, постепенно разваливающийся под собственной тяжестью. C++ тому наглядный пример.

Разве не ты начал о том что интерфейсы коллекций косячные? Мое предложение позволило бы работать с мутабельными и иммутабельными коллекциями прозрачно. В С++ подобного ничего не видел, так что если он и плох, то не от моего предложения.

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

Речь ведь не о тебе, а об иммутабельности языка/фреймворка. Тебе, кстати, можно не беспокоиться о том что мои предложения попадут в фреймворк.
Re[25]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 22.11.10 06:21
Оценка:
Здравствуйте, samius, Вы писали:

S>Не надо брать меня на понт. Я приводил пример и давал ссылку. То что тебе что-то не очевидна выгода — это не мои проблемы.


Ты про эту ссылку http://fprog.ru/2009/issue1/eugene-kirpichov-fighting-mutable-state/ ? В ней куча примеров, какой, конкретно, смотреть?
Re[26]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.10 06:29
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Не надо брать меня на понт. Я приводил пример и давал ссылку. То что тебе что-то не очевидна выгода — это не мои проблемы.


U>Ты про эту ссылку http://fprog.ru/2009/issue1/eugene-kirpichov-fighting-mutable-state/ ? В ней куча примеров, какой, конкретно, смотреть?


В той статье все примеры про недостатки изменяемого состояния в разных аспектах. Может ты с каким-то не согласен?
Re[27]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 22.11.10 08:58
Оценка:
Здравствуйте, samius, Вы писали:

S>В той статье все примеры про недостатки изменяемого состояния в разных аспектах. Может ты с каким-то не согласен?


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

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

class Cart {
        private Customer customer;
        private List<Product> products;
        private int totalPrice = -1;

        private int computeTotalPrice() {
                // Scary code here
        }

        public int getTotalPrice() {
                if(totalPrice == -1)
                        totalPrice = computeTotalPrice();
                return totalPrice;
        }
        public void addProduct(Product p) {
                products.add(p);
                totalPrice = -1;
        }
}


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

Объясни чем здесь поможет иммутабельный подход? Допустим, стал у тебя Product иммутабельным, что теперь нужно сделать при изменении цены на товар? Как будет решаться задача получения информации об этом изменении всеми заказами?

Правильный подход такой, при изменении цены любого товара обновляем некий changeTick общий для всех товаров. Далее в Cart для вычисления итоговой цены используем автоматический кэш, зависящий от двух параметров: 1) от внутренненего changeTick'а, отвечающего за изменение коллекции products 2) от внешнего changeTick'а, отвечающего за изменение цены любого товара. Соответственно в месте изменения цены на товар нам не нужно ничего знать о том где этот товар используется, итоговая цена во всех заявках обновится автоматически, причем сделает это ленивым образом. Принципу минимума сеттеров это решение полностью соответствует, соответственно работает прекрасно — код получается простой, понятный и надежный.

Теперь жду твое решение этой же задачи, использующее иммутабельные объекты.
Re[29]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 24.11.10 12:31
Оценка:
Здравствуйте, samius, Вы писали:

S>В иммутабельном подходе вместо tick-ов используются сами объекты — корзина и набор цен. Остальное — то же самое, вплоть до ленивости. Правда еще логарифмический от числа продуктов штраф на обновление набора ценников.


Зачем для такого подхода нужна иммутабельность всех объектов? Какие плюсы дает использование только иммутабельных объектов по сравнению с использованием частично мутабельных объектов в рамках этого же подхода?

При использовании только иммутабельных объектов получается, что при любом изменении необходимо пересоздавать весь мир. Это плохо, во-первых, с точки зрения производительности, во-вторых, это плохо с точки зрения самодокументируемости кода.

Насчет самодокументируемости объясню подробнее. Есть вот такой код:

class Car
{
  readonly Tank tank;
}

class Tank
{
  readonly double FuelVolumeMax;
  double FuelVolume;  
}


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

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

S>Если мы обратимся повторно к методу вычисления цены, передав тот же набор цен и ту же корзину, то он вернет пару (закэшированное значение, себя). Если ему передали другую корзину либо набор цен, то рассчет будет произведен заново, вернется пара (новое значение цены, новая структура с запомненными сущностями).


S>А что за принцип минимума сеттеров, который ты неоднократно упоминаешь?


Ты о том где о нем можно почитать? Не знаю. Я об этом принципе узнал от http://rsdn.ru/Users/3655.aspx

Если же просто интересует более развернутое определение, то его можно сформулировать следующим образом: изменение определенной сущности не должно требовать явного изменения других сущностей.

К примеру, в задаче с кэшированной ценой решение с кэшем и changeTick'ом близко к идеальному, т.к. при изменении цены дополнительно нужно поменять только changeTick, т.е. на 1 изменение сущности приходится два сеттера. Решение этой же задачи в лоб, т.е. вызов при изменении цены для всех корзин товаров функции Update сбрасывающей кэш, требует на 1 изменение сущности (1 + N) сеттеров, где N — количество заявок. Соответственно это плохое решение.

S>Извиняюсь за долгий ответ, мотался в Челябинск.


Долгие ответы это хорошо. Быстрые ответы отрицательно сказываются на рабочем процессе.
Re[30]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 24.11.10 21:35
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>В иммутабельном подходе вместо tick-ов используются сами объекты — корзина и набор цен. Остальное — то же самое, вплоть до ленивости. Правда еще логарифмический от числа продуктов штраф на обновление набора ценников.


U>Зачем для такого подхода нужна иммутабельность всех объектов? Какие плюсы дает использование только иммутабельных объектов по сравнению с использованием частично мутабельных объектов в рамках этого же подхода?


Возражаю против термина "частичная мутабельность объекта". Или объект абсолютно иммутабелен и никакие действия над ним не способны изменить поведение системы, либо объект меняет свое (либо чужое состояние), а значит мутабелен. Значит существуют ограничения на то, кто, когда и для чего должен менять состояния мутабельных объектов. Следовательно, требуется защита от несанкционированного изменения состояний объектов.
В большой команде есть риск что найдется доброжелатель, который не зная об особенностях каких-то кэшей и tick-ов, использует класс продукта из каталога продуктов в некоторой задаче, выполняющейся фоном. Если продукт изменяет changeTick кэша неявно, то производительность кэша просела. Если изменение tick-а требуется явное (и оно не было сделано), то произойдет нарушение инварианта и рассогласование ценников корзин с актуальными ценами продуктов.
Кроме того, для того чтобы мутабельный класс продукта можно было бы использовать в публичном API, требуется разделение интерфейсов для чтения и изменения состояния продукта (ReadOnly обертки или неизменяемые копии, реализующие интерфейс продукта)...

С иммутабельными объектами все горзадо проще, т.к. нет опасности его несанкционированного изменения и рассогласования состояний. Можно смело дать подержать 3им лицам целый "мир", торчащий из API.


U>При использовании только иммутабельных объектов получается, что при любом изменении необходимо пересоздавать весь мир. Это плохо, во-первых, с точки зрения производительности, во-вторых, это плохо с точки зрения самодокументируемости кода.

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

U>Насчет самодокументируемости объясню подробнее. Есть вот такой код:


U>
U>class Car
U>{
U>  readonly Tank tank;
U>}

U>class Tank
U>{
U>  readonly double FuelVolumeMax;
U>  double FuelVolume;  
U>}
U>


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

Очень просто. Выделить незименные характеристики в отдельную сущность и расшарить ее между различными экземплярами Car-а.

U>Т.е. при неиммутабельном подходе все честно, если параметр (ссылка на него) иммутабельный, он записывается как readonly, если — мутабельный, то записывается как изменяемый, если вычисляется на основе других параметров, то записывается как кэш. Что дает отказ от этой честности в пользу полной иммутабельности?

Автоматическую гарантию того что FuelVolume не рассогласуется с остальным миром. Полный контроль того, кто, когда и для чего обновляет сущности без модификаторов видимости, двойных интерфейсов для чтения/записи, const, friend и т.п.

U>Если же просто интересует более развернутое определение, то его можно сформулировать следующим образом: изменение определенной сущности не должно требовать явного изменения других сущностей.


U>К примеру, в задаче с кэшированной ценой решение с кэшем и changeTick'ом близко к идеальному, т.к. при изменении цены дополнительно нужно поменять только changeTick, т.е. на 1 изменение сущности приходится два сеттера. Решение этой же задачи в лоб, т.е. вызов при изменении цены для всех корзин товаров функции Update сбрасывающей кэш, требует на 1 изменение сущности (1 + N) сеттеров, где N — количество заявок. Соответственно это плохое решение.

Однако, противоречие формулировке: изменение цены продукта требует явного изменения changeTick-а. Чтобы удовлетворить формулировке требуется в сеттере цены продукта неявно менять глобальный changeTick. А это фактически запрет на использование сущности продукта в других местах системы.

U>Долгие ответы это хорошо. Быстрые ответы отрицательно сказываются на рабочем процессе.

+1
Re[31]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 24.11.10 22:53
Оценка:
S>Возражаю против термина "частичная мутабельность объекта". Или объект абсолютно иммутабелен и никакие действия над ним не способны изменить поведение системы, либо объект меняет свое (либо чужое состояние), а значит мутабелен.

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

1. в том же .net-е строка иммутабельна, но при этом класс string имеет кучу internal методов с названием AppendInPlace:
internal unsafe void AppendInPlace(char value, int currentLength)
{
    fixed (char* chRef = &this.m_firstChar)
    {
        chRef[currentLength] = value;
        currentLength++;
        chRef[currentLength] = '\0';
        this.m_stringLength = currentLength;
    }
}

которые использует в своих целях StringBuilder.

2. ссылки на объекты по смыслу иммутабельны, но при этом они меняются GC

и т.д.

т.е. в реальном коде иммутабельность часто используется только при взаимодействие с одной из гранью объекта(с одним из интерфейсов объекта)
Re[30]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 25.11.10 03:51
Оценка:
Здравствуйте, Undying, Вы писали:

U>При использовании только иммутабельных объектов получается, что при любом изменении необходимо пересоздавать весь мир. Это плохо, во-первых, с точки зрения производительности, во-вторых, это плохо с

точки зрения самодокументируемости кода.

Ну вот в Linq плохо с самодокументируемостью ? Вроде как наоброт — все логично и просто.
Re[32]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 05:21
Оценка:
Здравствуйте, DarkGray, Вы писали:


S>>Возражаю против термина "частичная мутабельность объекта". Или объект абсолютно иммутабелен и никакие действия над ним не способны изменить поведение системы, либо объект меняет свое (либо чужое состояние), а значит мутабелен.


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


DG>1. в том же .net-е строка иммутабельна, но при этом класс string имеет кучу internal методов с названием AppendInPlace:

Не нашел с разбегу в 4м фреймворке такого метода.

DG>2. ссылки на объекты по смыслу иммутабельны, но при этом они меняются GC


DG>и т.д.


В главе 3 этой статьи приведена классификация изменяемых состояний и степени опасности их использования.
Случай 1 можно классифицировать как инкапсулированное изменяемое состояние (если строка действительно содержит такой метод), а случай 2 как невидимое программисту изменяемое состояние.
Случай 2 вообще безобиден, а 1 — тут можно говорить о некоторой уверенности в том, что целостность объекта не рарушится.

DG>т.е. в реальном коде иммутабельность часто используется только при взаимодействие с одной из гранью объекта(с одним из интерфейсов объекта)

Если объект можно изменить во внешнем коде через один из интерфейсов, то он не является иммутабельным.
Re[32]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.11.10 05:41
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Ikemefula, Вы писали:


I>>Ну вот в Linq плохо с самодокументируемостью ? Вроде как наоброт — все логично и просто.


U>Речь идет о хранении состояний, причем здесь Linq? Linq это низкоуровневое средство, которое можно использовать только внутри функций. В данном контексте, то на чем пишутся внутренности функций совершенно не интересно, т.к. архитектурная сложность кода внутри функций стремится к нулю.


1)Linq позволяет связывать высокоуровневые вычисления (ибо монады)
2)Linq позволяет уменьшить архитектурную сложность за счет декомпозиции.
Re[34]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 12:06
Оценка:
Здравствуйте, DarkGray, Вы писали:

S>>Если объект можно изменить во внешнем коде через один из интерфейсов, то он не является иммутабельным.


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

Википедию писали фанатики?

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.


DG>для того чтобы считать объект иммутабельным при работе с объектом через определенный интерфейс нам необходимо и достаточно соглашения, что:

Это другое понятие.
DG>1. и/или обращения через другие интерфейсы не изменяет состояние объекта доступное нам через интерфейс, через который мы работаем
DG>2. и/или состояние объекта не меняется за время работы с ним
И оно мне не понятно. Допустим, есть массив int[] и интерфейс IEnumerable<T>. Пункт 1 не выполняется, т.е изменение через другие интерфейсы возможно. А пункт 2 зависит от того, будет ли кто-то менять состояние массива, пока кто-то работает с ним через IEnumerable<T>, или нет. Т.е. ответа на то, является ли массив изменяемым или нет, такое определение не дает. Я им не буду пользоваться.

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


DG>такой подход часто используется при lazy-создании объектов, прозрачном кэшировании и т.д.

Я понимаю, о чем речь. Но с формулировкой не согласен.

DG>в ранее приведенном примере со строкой видно, что это соглашение выполняется следующим образом:

DG>строка меняется пока нам ее не передали, как только нам ее передали — она больше не меняется,
DG>в примере с ссылками — через доступный интерфейс нельзя получить значение ссылки, поэтому ее изменение на нас никак не влияет.

DG>частичная иммутабельность активно используется в существующих языках:

DG>например, почти все mainstream-языки считают, что тип объекта иммутабелен (т.е. интерфейс состоящий из одной функции obj.GetType(), а так же сам тип — иммутабелен)
DG>c/C++ — считают, что указатель на объект иммутабелен (интерфейс &obj — иммутабелен)
Нет вопросов, пока не переопределен оператор &.

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

DG>это позволяет использовать все плюсы иммутабельности для неиммутабельных объектов.
DG>и соответственно это приводит к критерию про который упоминал undying: чем меньше setter-ов и чем реже их необходимо вызывать, тем более система иммутабельна в фиксированный промежуток времени (больше объектов можно считать иммутабельными за данный фиксированный промежуток времени)
Не понял. Изменилась цена продукта, корзина осталась неизменной, хотя при обращении к ней она изменит свою стоимость. Предлагается считать корзину иммутабельной в момент изменения цены продукта?
Re[31]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 25.11.10 12:52
Оценка:
Здравствуйте, samius, Вы писали:

Для того, чтобы разговор был предметным, можешь привести чисто иммутабельный код решения задачи с корзиной товаров? А то я даже модификацию элемента коллекции в иммутабельном стиле с трудом себе представляю, не говоря уже о чем-то более сложном.
Re[32]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:05
Оценка:
U> А то я даже модификацию элемента коллекции в иммутабельном стиле с трудом себе представляю, не говоря уже о чем-то более сложном.

иммутабельное удаление элемента коллекции
ReadOnlyCollection<int> items = ...
items = ReadOnlyCollection<int>(items.where((item,index) => index != 5));


соответственно иммутабельная корзина, это когда при изменении корзины корзина заново пересоздается с нуля (и соответственно желательно чтобы пересоздание корзины было где-то в одном месте)
Re[36]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 13:10
Оценка:
Здравствуйте, DarkGray, Вы писали:

>> Википедию писали фанатики?


DG>сейчас ты показываешь другое проявление фанатизма: отсылка к авторитетам вместо отсылки к доводам(логическим выводам)

DG>это мне напоминает то, что долгое время считалось, что у мухи 8 ног т.к. все ссылались на авторитет Аристотеля
Нет, я проявил невнимательность при чтении авторитетов.

DG>>>1. и/или обращения через другие интерфейсы не изменяет состояние объекта доступное нам через интерфейс, через который мы работаем

DG>>>2. и/или состояние объекта не меняется за время работы с ним
S>>И оно мне не понятно. Допустим, есть массив int[] и интерфейс IEnumerable<T>. Пункт 1 не выполняется, т.е изменение через другие интерфейсы возможно. А пункт 2 зависит от того, будет ли кто-то менять состояние массива, пока кто-то работает с ним через IEnumerable<T>, или нет. Т.е. ответа на то, является ли массив изменяемым или нет, такое определение не дает. Я им не буду пользоваться.

DG>в данных кусках кода объект items иммутабелен или нет?

DG>можно ли считать, что объект items иммутабелен? и почему?
DG>
DG>int[] items = data.GetItems();
DG>foreach (var item in items)
DG>{
DG>  //..bla-bla
DG>}
DG>

нет, потому что вместо //bla-bla может быть items[0] = -1;

DG>
DG>int[] items = data.GetItems();
DG>F(items as IEnumerable<int>)
DG>

Тоже нет.
Понятий иммутабельности в контексте и иммутабельности через интерфейс я не знаю.

S>>Не понял. Изменилась цена продукта, корзина осталась неизменной, хотя при обращении к ней она изменит свою стоимость. Предлагается считать корзину иммутабельной в момент изменения цены продукта?


DG>т.е. приложение имеет несколько несколько параллельных потоков управляющей логики?

DG>один поток формирует корзину?
DG>другой поток может менять цены продуктов?
тот же поток
var price1 = cart.TotalPrice();
someProductCollection[0].Price = newPrice;
var price2 = cart.TotalPrice();

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

DG>1. ничего (транзакцией является обращение к базе)
DG>2. ссылка на продукт (транзакция наполнения корзины захватывает продукты, но не цены к ним)
DG>3. ссылка на продукт + цена (наполнение корзины есть одна транзакция)

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

DG> но внутри одного обращения (например, при генерации html-страницы) можно считать, что корзина иммутабельна
DG>для последнего варианта — корзина иммутабельна на все время ее заполнения, пока мы сами ее не меняем
корзину не меняем? ссылки на продукты не менялись, цена изменилась.

DG>зы

DG>кстати если исходить из законов РФ, то цена продукта не может меняться после того, как его взяли с полки
познавательно.
Re[32]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 13:18
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


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


Позже, когда будет время.
Модификация иммутабельной коллекции невозможна. Правда в FP не всегда пересоздается полностью. Так, добавление и удаление элементов в/из начала энергичного списка — почти бесплатное O(1). Работа с концом списка требует пересоздания всех элементов. Сложность получения обновленного дерева в среднем не превышает его высоты (логарифм от числа элементов).
Re[37]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:28
Оценка:
DG>>
DG>>int[] items = data.GetItems();
DG>>F(items as IEnumerable<int>)
DG>>

S>Тоже нет.

но ты понимаешь что нет никакой разницы со следующим кодом?:
ReadOnlyCollection<int> items = data.GetItems();
F(items)

где F делает
void F(ReadOnlyCollection<int> list)
{
   int[] items = list.GetType().GetField("items", Private).GetValue(list);
   items[i] = 0;
}


т.е. в обоих случаях нет гарантии что объект не поменяют, но есть соглашение что объект не будет меняться во вне рамок переданного интерфейса

и соответственно мне не понятно, на основании какого критерия ты отличаешь одно соглашение от другого.
почему соглашение с readonlycollection — правильно соглашение, а в варианте с IEnumerable<int> — неправильное соглашение?
Re[37]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:33
Оценка:
S>тот же поток
S>var price1 = cart.TotalPrice();
S>someProductCollection[0].Price = newPrice;
S>var price2 = cart.TotalPrice();

если этот тот же поток, то внутри функции заполнения корзины есть гарантия что цена не меняется (если конечно не рассматривать вариант — что мы ССЗБ)
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 13:36
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>но ты понимаешь что нет никакой разницы со следующим кодом?:

DG>
DG>ReadOnlyCollection<int> items = data.GetItems();
DG>F(items)
DG>

DG>где F делает
DG>
DG>void F(ReadOnlyCollection<int> list)
DG>{
DG>   int[] items = list.GetType().GetField("items", Private).GetValue(list);
DG>   items[i] = 0;
DG>}
DG>



DG>т.е. в обоих случаях нет гарантии что объект не поменяют, но есть соглашение что объект не будет меняться во вне рамок переданного интерфейса

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

DG>и соответственно мне не понятно, на основании какого критерия ты отличаешь одно соглашение от другого.

DG>почему соглашение с readonlycollection — правильно соглашение, а в варианте с IEnumerable<int> — неправильное соглашение?

Соглашение с ReadonlyCollection может удовлетворить критерию иммутабельности только в том случае, когда есть гарантия, что реальную коллекцию никто и никогда не изменит.
Т.е. если объект при создании своей коллекции сразу же заворачивает ее в RC<T> и не меняет сам оригинальную коллекцию и не позволяет прямо либо косвенно менять ее другим сущностям — я согласен считать такой объект иммутабельным в отношении атрибута-коллекции.
Но и это весьма условно, т.к. всегда можно подлезть рефлекшном.
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 13:37
Оценка:
Здравствуйте, DarkGray, Вы писали:

S>>тот же поток

S>>var price1 = cart.TotalPrice();
S>>someProductCollection[0].Price = newPrice;
S>>var price2 = cart.TotalPrice();

DG>если этот тот же поток, то внутри функции заполнения корзины есть гарантия что цена не меняется (если конечно не рассматривать вариант — что мы ССЗБ)

после повторного обращения к TotalPrice, изменится некий changeTick (поле корзины), после чего корзина начнет выдавать новый результат TotalPrice().
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 13:42
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>т.е. в обоих случаях нет гарантии что объект не поменяют, но есть соглашение что объект не будет меняться во вне рамок переданного интерфейса


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

В том же императивном D в котором также есть жесткая иммутабельность http://www.digitalmars.com/d/2.0/const3.html
гарантии не менее важны, но по другой причине compile-time и многопоточность.
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:46
Оценка:
S>соглашение — вещь весьма условная. Сегодня я согласился, а завтра поменял. Если компилятор не может поддержать это соглашение, то я не буду считать такое соглашение надежным.
S>Все равно что создать глобальную переменную, и написать комментарий — "не менять". А кто-то этот комментарий не увидит.

во-первых, написание хорошего кода держится только на соглашениях
никакой компилятор не гарантирует, что безобидная функция Sum не создает ненужных глобальных переменных, не форматирует винт и т.д.
во-вторых, компилятор помогает поддерживать соглашения, а не заменяет их
в-третьих, кроме компилятора есть еще утилиты вида FxCop которые помогают отслеживать выполнение соглашений
в-четвертых, для отслеживания выполнения соглашения делаются code review.

S>Соглашение с ReadonlyCollection может удовлетворить критерию иммутабельности только в том случае, когда есть гарантия, что реальную коллекцию никто и никогда не изменит.


вот только это real life и real code — и ни в первом, ни во втором — нет никаких абсолютных гарантий
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:47
Оценка:
S>после повторного обращения к TotalPrice, изменится некий changeTick (поле корзины), после чего корзина начнет выдавать новый результат TotalPrice().

и это есть плохой код с плохой архитектурой — и такой код и такую архитектуру стоит вычеркивать из жизни
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.11.10 13:54
Оценка:
Здравствуйте, DarkGray, Вы писали:

S>>после повторного обращения к TotalPrice, изменится некий changeTick (поле корзины), после чего корзина начнет выдавать новый результат TotalPrice().


DG>и это есть плохой код с плохой архитектурой — и такой код и такую архитектуру стоит вычеркивать из жизни

Я только за.
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 13:55
Оценка:
FR>Не знаю как у вас в NET, но в функциональщине важны именно гарантии, немножко беременное не прокатывает.
FR>Эти гарантии обеспечивают основный плюс и базис функциональщины — прозрачность по ссылкам.

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

замкнутый круг однако
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 13:59
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>как только появляется динамическая типизация (а тем более рантайм подгрузка кода) то все гарантии пропадают

DG>а разработка реальных программ без динамической типизации почти невозможна

Динамическая типизация ортогональна функциональности. Эрланг и Схема например являются одновременно и ФЯ и ДЯ.
Типизация вообще не важна главное обеспечить эту самую прозрачность по ссылкам, как не важно.
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 14:00
Оценка:
DG>>и это есть плохой код с плохой архитектурой — и такой код и такую архитектуру стоит вычеркивать из жизни
S>Я только за.

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

на практике обычно решается 2 задача, и только в критических точках (например, песочница в браузере) решается 1 задача.
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 14:04
Оценка:
FR>Динамическая типизация ортогональна функциональности. Эрланг и Схема например являются одновременно и ФЯ и ДЯ.
FR>Типизация вообще не важна главное обеспечить эту самую прозрачность по ссылкам, как не важно.

и каким образом обеспечивается гарантия иммутабельности при динамической типизации?
тем что мы в языке вообще не можем делать мутабельные объекты? но это сильно сужает круг решаемых задач.
например, тот же самый quicksort плохо реализуется поверх только иммутабельных объектов.
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 14:12
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>и каким образом обеспечивается гарантия иммутабельности при динамической типизации?

DG>тем что мы в языке вообще не можем делать мутабельные объекты? но это сильно сужает круг решаемых задач.
DG>например, тот же самый quicksort плохо реализуется поверх только иммутабельных объектов.

Вообще можем, в энергичных языках совсем без мутабельности сложно обойтись, но по умолчанию все иммутабельно
и эта иммутабельность гарантируется компилятором и рантаймом.
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 14:27
Оценка:
FR>В том же императивном D в котором также есть жесткая иммутабельность http://www.digitalmars.com/d/2.0/const3.html

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

If a ClassDeclaration has a const, immutable or shared storage class, then it is as if each member of the class was declared with that storage class. If a base class is const, immutable or shared, then all classes derived from it are also const, immutable or shared.


зы
"проблема заражения" — если в одном месте требуется что-то (например, иммутабельность), то необходимо сделать чтобы весь код, который из этого места используется то же был иммутабельный
в C++, например, для борьбы с этим вводили обратное слово mutable

в реальном коде, когда используется большое кол-во чужих библиотек — проблема заражения очень критична.
если код использует внешную либу, которая в явном виде не использует данное соглашение (по смыслу, например, либа иммутабельна, но не помечена данным аттрибутом) — то "проблема заражения" требует переписывания такой внешней либы.
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 14:33
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>зы

DG>"проблема заражения" — если в одном месте требуется что-то (например, иммутабельность), то необходимо сделать чтобы весь код, который из этого места используется то же был иммутабельный
DG>в C++, например, для борьбы с этим вводили обратное слово mutable

Ну в C++ как всегда одной рукой даем другой забираем
Но даже там "вирусность" const считается плюсом а не минусом.

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


Да в С++ очень помогает делать правильные библиотеки.

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


Конечно и это хорошо.
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 14:52
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

DG>в C++, например, для борьбы с этим вводили обратное слово mutable

Да и ввели его уж точно не для борьбы с заразностью, а только для того чтобы была возможность из константных методов
менять некоторые неважные для инварианта класса члены.
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 15:02
Оценка:
FR>Да и ввели его уж точно не для борьбы с заразностью, а только для того чтобы была возможность из константных методов
FR>менять некоторые неважные для инварианта класса члены.

mutable слово позволяет сделать преобразование mutable -> immutable, что позволяет хотя бы сделать обертку на legacy кодом или чужим кодом без immutable-пометки

т.е. есть например legacy-код без immutable-пометки, тогда можно сделать свой класс, который дальше и используется
immutable class ImmutableMutableWrapper:IImmutableInterface
{
  [mutable]
  IMutableInterface obj;

  public immutable int GetData()
  {
      return obj.GetData();
  }
}
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 15:34
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

FR>>менять некоторые неважные для инварианта класса члены.

DG>mutable слово позволяет сделать преобразование mutable -> immutable, что позволяет хотя бы сделать обертку на legacy кодом или чужим кодом без immutable-пометки


В C++ не для этого.

DG>т.е. есть например legacy-код без immutable-пометки, тогда можно сделать свой класс, который дальше и используется

DG>
DG>immutable class ImmutableMutableWrapper:IImmutableInterface
DG>{
DG>  [mutable]
DG>  IMutableInterface obj;

DG>  public immutable int GetData()
DG>  {
DG>      return obj.GetData();
DG>  }
DG>}
DG>


Тут не понял вообще к чему это, точно не C++.
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 15:35
Оценка:
Здравствуйте, DarkGray, Вы писали:


FR>>Конечно и это хорошо.


DG>нет, конечно же.

DG>язык делается для того, чтобы быстро и дешево решать проблемы, а не для того, чтобы дорого и долго переписывать весь имеющийся код.

Зачем переписывать код если в нем иммутабле есть с самого рождения.
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 25.11.10 17:29
Оценка:
FR>Зачем переписывать код если в нем иммутабле есть с самого рождения.

речь шла про D. а там во-первых, immutable — нет от рождения, а во-вторых — не по умолчанию. immutable надо явно проставлять.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 25.11.10 20:02
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>речь шла про D. а там во-первых, immutable — нет от рождения, а во-вторых — не по умолчанию. immutable надо явно проставлять.


В D одна из основных причин выделения новой не совместимой версии (2.0) языка именно ввод иммутабельности.
Ну и учитывая что 1.0 очень мало популярен и кода на нем практически и нет можно сказать что от рождения.
Re[33]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 04:40
Оценка:
Здравствуйте, DarkGray, Вы писали:

U>> А то я даже модификацию элемента коллекции в иммутабельном стиле с трудом себе представляю, не говоря уже о чем-то более сложном.


DG>иммутабельное удаление элемента коллекции


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

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


Это мне тоже интересно, где храним корзину, где храним коллекцию всех товаров, каким образом предоставляем к ним доступ, позволяющий их пересоздавать.
Re[34]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 26.11.10 05:27
Оценка:
Здравствуйте, Undying, Вы писали:

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


Зависит от структуры. Если она на деревьях — то там обычно логарифмическая сложность. Пересоздаётся не такой уж большой участок, остальное копируется неизменным (ссылки) в новую структуру.
Re[34]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 05:34
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, DarkGray, Вы писали:


U>>> А то я даже модификацию элемента коллекции в иммутабельном стиле с трудом себе представляю, не говоря уже о чем-то более сложном.


DG>>иммутабельное удаление элемента коллекции


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

Модификации элемента в чистом иммутабельном стиле нет, но есть замена — удаление старого + добавление нового с получением новой коллекции на каждом этапе.
ReadOnlyCollection<T> Remove<T>(ReadOnlyCollection<T>, T) { ... }
ReadOnlyCollection<T> Add<T>(ReadOnlyCollection<T>, T) { ... }
ReadOnlyCollection<T> Replace<T>(ReadOnlyCollection<T>, T oldValue, T newValue) 
{ return Add(Remove(coll, oldValue), newValue));  }

Технически замену элемента можно сделать и за один проход.

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


U>Это мне тоже интересно, где храним корзину, где храним коллекцию всех товаров, каким образом предоставляем к ним доступ, позволяющий их пересоздавать.


В стиле FP это может выглядеть как передача обновленного мира рекурсивной функции, которая занимается в том числе диспетчеризацией сообщений:

int Run(World world)
{
   var msg = GetMessage();
   
   return Run(DispatchMessage(world, msg));
}
int Main()
{
    return Run(new World());
}

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

Но т.к. в рантайме дотнета нельзя рассчитывать на хвостовую оптимизацию рекурсии (поддерживается весьма мало в ограниченных сценариях и по разному на разных архитектурах), то в C# такой подход грозит переполнением стека. Выход — преобразование рекурсии в цикл с мутабельной переменной (так делает компилятор F#).
Еще пара шагов и world оказывается мутабельным полем формы приложения со стандартным дотнетовским циклом сообщений.
Re[35]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 05:58
Оценка:
Здравствуйте, samius, Вы писали:

S>Модификации элемента в чистом иммутабельном стиле нет, но есть замена — удаление старого + добавление нового с получением новой коллекции на каждом этапе.

S>
S>ReadOnlyCollection<T> Replace<T>(ReadOnlyCollection<T>, T oldValue, T newValue) 
S>{ return Add(Remove(coll, oldValue), newValue));  }
S>

S>Технически замену элемента можно сделать и за один проход.

А как произвести замену с сохранением позиции элемента?

В общем случае, если у нас есть объект с полями Property1 и Property2, как мы производим в нем замену Property1, а как Property2?

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


Можно увидеть конкретный пример решающий реальную задачу? Например, ту же самую корзину товаров.
Re[36]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 06:12
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Технически замену элемента можно сделать и за один проход.


U>А как произвести замену с сохранением позиции элемента?

Удалить элемент в заданной позиции, как показывал DarkGray, потом в ту же позицию вставить новый элемент.

U>В общем случае, если у нас есть объект с полями Property1 и Property2, как мы производим в нем замену Property1, а как Property2?

Мы создаем новый объект с новыми значениями свойств.

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


U>Можно увидеть конкретный пример решающий реальную задачу? Например, ту же самую корзину товаров.

В смысле от корки до корки? Или конкретную функцию создания новой корзины по старой с изменением набора продуктов?
Re[37]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 06:28
Оценка:
Здравствуйте, samius, Вы писали:

U>>В общем случае, если у нас есть объект с полями Property1 и Property2, как мы производим в нем замену Property1, а как Property2?

S>Мы создаем новый объект с новыми значениями свойств.

Т.е. если у меня есть объект с десятком свойств, то я должен написать для него конструктор все эти десять свойств принимающий, а затем при модификации объекта вызывать этот конструктор, руками набивая в него 9 неизменившихся свойств и 1 изменившееся?

U>>Можно увидеть конкретный пример решающий реальную задачу? Например, ту же самую корзину товаров.

S>В смысле от корки до корки? Или конкретную функцию создания новой корзины по старой с изменением набора продуктов?

Хотелось бы видеть следующее: сущность — продукт с ценой, сущность — список всех продуктов, сущность — корзина со списком находящихся в ней товаров, сущность — кэш цены товара. И взаимодействие между этими сущностями в случае изменения цены товара.
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 26.11.10 07:19
Оценка:
Здравствуйте, Undying, Вы писали:

U>Хотелось бы видеть следующее: сущность — продукт с ценой, сущность — список всех продуктов, сущность — корзина со списком находящихся в ней товаров, сущность — кэш цены товара. И взаимодействие между этими сущностями в случае изменения цены товара.


Как пример: корзину можно не менять, если она хранит ProductId, а список всех продуктов — это отображение ProductId -> Product.
Что такое кэш цены товара?
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 07:29
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Здравствуйте, Undying, Вы писали:


U>>Хотелось бы видеть следующее: сущность — продукт с ценой, сущность — список всех продуктов, сущность — корзина со списком находящихся в ней товаров, сущность — кэш цены товара. И взаимодействие между этими сущностями в случае изменения цены товара.


L>Что такое кэш цены товара?

Речь о FP реализации примера из раздела 2.2 этой статьи.

Я приводил описание решения здесь
Автор: samius
Дата: 22.11.10
.
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 07:36
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>Т.е. если у меня есть объект с десятком свойств, то я должен написать для него конструктор все эти десять свойств принимающий, а затем при модификации объекта вызывать этот конструктор, руками набивая в него 9 неизменившихся свойств и 1 изменившееся?


В C#-е да в общем случае. Но можно создать один конструктор с параметрами по умолчанию. Идею подсмотрел у desco.

S>>В смысле от корки до корки? Или конкретную функцию создания новой корзины по старой с изменением набора продуктов?


U>Хотелось бы видеть следующее: сущность — продукт с ценой, сущность — список всех продуктов, сущность — корзина со списком находящихся в ней товаров, сущность — кэш цены товара. И взаимодействие между этими сущностями в случае изменения цены товара.

Это займет какое-то время. Прямо сейчас я этим заниматься не буду. На днях...
Re[39]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 08:28
Оценка:
Здравствуйте, samius, Вы писали:

S>В C#-е да в общем случае. Но можно создать один конструктор с параметрами по умолчанию. Идею подсмотрел у desco.


В таком виде более-менее нормально.

S>Удалить элемент в заданной позиции, как показывал DarkGray, потом в ту же позицию вставить новый элемент.


Сколько строчек кода нужно, чтобы это сделать?

S>Это займет какое-то время. Прямо сейчас я этим заниматься не буду. На днях...


Жду.
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 08:58
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>В C#-е да в общем случае. Но можно создать один конструктор с параметрами по умолчанию. Идею подсмотрел у desco.


U>В таком виде более-менее нормально.


S>>Удалить элемент в заданной позиции, как показывал DarkGray, потом в ту же позицию вставить новый элемент.


U>Сколько строчек кода нужно, чтобы это сделать?

IEnumerable<T> ReplaceAt(this IEnumerable<T> source, int index, T newValue)
{
    return source.Take(index).Concat(new T[]{ newValue }).Concat(source.Skip(index + 1));
}

С проверками аргументов — побольше.


S>>Это займет какое-то время. Прямо сейчас я этим заниматься не буду. На днях...


U>Жду.

ок
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 26.11.10 09:20
Оценка:
Здравствуйте, samius, Вы писали:


U>>Сколько строчек кода нужно, чтобы это сделать?

S>
S>IEnumerable<T> ReplaceAt(this IEnumerable<T> source, int index, T newValue)
S>{
S>    return source.Take(index).Concat(new T[]{ newValue }).Concat(source.Skip(index + 1));
S>}
S>

S>С проверками аргументов — побольше.

Очень похоже на забивание шурупа стамеской
(Не пишут в таком стиле на ФЯ и C# слаб как ФЯ)
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 09:27
Оценка:
Здравствуйте, FR, Вы писали:

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



U>>>Сколько строчек кода нужно, чтобы это сделать?

S>>
S>>IEnumerable<T> ReplaceAt(this IEnumerable<T> source, int index, T newValue)
S>>{
S>>    return source.Take(index).Concat(new T[]{ newValue }).Concat(source.Skip(index + 1));
S>>}
S>>

S>>С проверками аргументов — побольше.

FR>Очень похоже на забивание шурупа стамеской

FR>(Не пишут в таком стиле на ФЯ и C# слаб как ФЯ)
Не сталкивался с задачей замены элемента в иммутабельном списке с сохранением индекса. Но раз попросили, ответил.
И конечно C# слаб как ФЯ. И я не силен
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 26.11.10 09:31
Оценка:
Здравствуйте, samius, Вы писали:

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

S>И конечно C# слаб как ФЯ. И я не силен

К тебе никаких претензий
Просто весь тред вызывает у меня недоумение зачем так мучатся
Re[40]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 26.11.10 09:36
Оценка:
Здравствуйте, DarkGray, Вы писали:

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


Неужели ни один? А эти?
Glasgow Haskell Compiler
NHC98
York Haskell Compiler
Utrecht Haskell Compiler
JHC
Clean
Munster Curry Compiler
Zinc
The Kiel Curry System
Mercury
Agda
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Курилка Россия http://kirya.narod.ru/
Дата: 26.11.10 09:59
Оценка:
Здравствуйте, Klapaucius, Вы писали:

K>Здравствуйте, DarkGray, Вы писали:


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


K>Неужели ни один? А эти?

K>Glasgow Haskell Compiler
K>NHC98
K>York Haskell Compiler
K>Utrecht Haskell Compiler
K>JHC

А как же unsafePerformIO?
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 10:02
Оценка:
Здравствуйте, samius, Вы писали:

S>С проверками аргументов — побольше.


Т.е. вместо:

list.Add(item);
...
item.X = 0;


будет:

list = list.Add(item);
...
list = list.Replace(item, item.To(X = 0));


Это точно более простой код?
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 10:10
Оценка:
Здравствуйте, Undying, Вы писали:

U>Т.е. вместо:


U>
U>list.Add(item);
U>...
U>item.X = 0;
U>


U>будет:


U>
U>list = list.Add(item);
U>...
U>list = list.Replace(item, item.To(X = 0));
U>

да, но правильнее будет так:
U>
U>var list1 = list.Add(item);
U>...
U>var listN = list{N-1}.Replace(item, item.To(X: 0));
U>


U>Это точно более простой код?

То что он более простой не утверждалось. Но нарушить инварианты в таком коде гораздо сложнее.
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 26.11.10 10:12
Оценка:
Здравствуйте, Курилка, Вы писали:

К>А как же unsafePerformIO?

GHCi, version 6.12.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> unsafePerformIO $ print "BANG!!!"
<interactive>:1:0: Not in scope: `unsafePerformIO'
Prelude>

Как видите, все под контролем. А какое пространство имен мне не нужно импортировать чтоб не компилировался метод с сайд эффектами на Яве, например?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 26.11.10 10:31
Оценка:
Здравствуйте, Undying, Вы писали:

Вместо
Aggregate(list.ToList(), (xs, x) => { xs.Add(f(x)); return xs; })

будет
Aggregate(list, (xs, x) => xs.Add(f(x)))


U>Это точно более простой код?


Точно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 10:41
Оценка:
Здравствуйте, samius, Вы писали:

U>>Это точно более простой код?

S>То что он более простой не утверждалось. Но нарушить инварианты в таком коде гораздо сложнее.

Какие конкретно инварианты в таком коде нарушить сложнее?
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 26.11.10 10:43
Оценка:
Здравствуйте, Klapaucius, Вы писали:

U>>Это точно более простой код?


K>Точно.


И в чем он более простой? Сеттер у нас никуда не делся, соответственно информацию о произошедшем изменении по прежнему надо протаскивать на другие уровни. При этом по ходу пришлось создать две лишние сущности — новый экземпляр коллекции и новый экземпляр элемента. Соответственно бритва Оккама с простотой этого кода категорически не согласна.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 26.11.10 11:10
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>>>Это точно более простой код?

S>>То что он более простой не утверждалось. Но нарушить инварианты в таком коде гораздо сложнее.

U>Какие конкретно инварианты в таком коде нарушить сложнее?

Например, если список не пуст после построения, он таким и останется до конца своего существования. Его не надо защищать от записи, опасаясь что кто-то забудет обновить changeTick.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 26.11.10 12:56
Оценка:
Здравствуйте, Undying, Вы писали:

U>И в чем он более простой?

Aggregate(list.ToList(), (xs, x) => { xs.Add(f(x)); return xs; })


В нем нет выделенного жирным шрифтом.

U>Сеттер у нас никуда не делся


Сеттера нет.

U>, соответственно информацию о произошедшем изменении по прежнему надо протаскивать на другие уровни.


Протаскивать информацию нужно об изменении мутабельной структуры. Иммутабельная структура не меняется — она существует "вне времени" связанных с ней событий не бывает.

U> При этом по ходу пришлось создать две лишние сущности — новый экземпляр коллекции и новый экземпляр элемента. Соответственно бритва Оккама с простотой этого кода категорически не согласна.


Они не лишние — они обеспечивают ссылочную прозрачность, которая в свою очередь снимает необходимость в "протаскивании информации об изменении".
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[41]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 26.11.10 19:52
Оценка:
DG>>никакой компилятор не гарантирует, что безобидная функция Sum не создает ненужных глобальных переменных, не форматирует винт и т.д.

K>Неужели ни один? А эти?


и сколько реальных проектов на них написано, кроме дипломных проектов и прототипов?
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 26.11.10 19:58
Оценка:
U>Какие конкретно инварианты в таком коде нарушить сложнее?

те самые кэши, которые у тебя перестраиваются через changetick.

если мир создается каждый раз с нуля, то путь построения мира (в том числе кэшей) всегда один и тот же, и просто негде что-нибудь забыть.
в варианте с changetick-ами можно или забыть поменять changetick после обновления, или забыть где-то поставить зависимость по пересчету кэша на основе этого changetick-а (особенно это касается редко меняющихся справочников).
Re[42]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 27.11.10 09:59
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>и сколько реальных проектов на них написано, кроме дипломных проектов и прототипов?


Столько же или даже несколько больше, чем реальных проектов, написанных в 1985-ом году на ОО-языках.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[43]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 12:01
Оценка:
K>Столько же или даже несколько больше, чем реальных проектов, написанных в 1985-ом году на ОО-языках.

вот только ОО-концепции в 85-ом было лет 5 от роду, а тому же haskell-у уже 20 лет прошло.
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 27.11.10 12:22
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>вот только ОО-концепции в 85-ом было лет 5 от роду,


Наверное языки вроде Simula-67 и Smalltalk-72 имеют в названии случайно выбранные числа, с годами никак не связанные.

DG>а тому же haskell-у уже 20 лет прошло.


И что с того? Есть какой-то фундаментальный закон, согласно которому все внедряется за постоянное время в n лет? С опытом это в любом случае не согласуется. Обычно, чем изменения революционнее, тем сроки внедрения выше.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[44]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 27.11.10 12:29
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>и я хочу лишь зафиксировать, что на "чистых" языках, которые жестко придерживаются одной концепции и непозволяют ее нарушать — очень тяжело писать реальные проекты.


И какой концепции жестко придерживается тот же Хаскель? Той, что тип функции в которой 2+2 всегда равен 4 отличается от типа функции, в которой результат 2+2 зависит от фазы луны? Ну так все реальные проекты вне программирования как-то обходятся вообще 2+2=4 и без всяких вариантов. Как же это получается-то?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 12:47
Оценка:
K>И какой концепции жестко придерживается тот же Хаскель?

на вскидку
1. всегда создается новый экземпляр, невозможно реализовать алгоритм, который переиспользует память.
2. есть только ленивые вычисления, нет энергичных вычислений
3. язык строго типизированный
Re[13]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.11.10 13:52
Оценка:
Здравствуйте, samius, Вы писали:

S>Попрошу сделать обертку для Dictionary<TKey, TValue>, что бы не кидала исключений, сохраняла интерфейс и вообще вела себя как IDictionary<TKey, TValue>. Может ответ сам найдется...

Как IDictionary в FP стиле она себя вести не должна.
Потому, что в FP стиле IDictionary придётся определять по-другому. Вместо всех сеттеров придётся писать методы, возвращающие новый экземпляр иммутабельного Dictionary.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.11.10 14:09
Оценка:
Здравствуйте, Undying, Вы писали:
U>Если в ходе некоего процесса состояние объекта меняется, то разумнее всего использовать мутабельный объект, а проблемы мутабельности минимизировать иными средствами (автоматическими кэшами, к примеру). Если же в ходе некоего процесса состояние объекта не должно меняться, то разумно это зафиксировать в коде, используя иммутабельный объект. Но во втором случае нет никакой необходимости эмулировать мутабельность путем создания нового иммутабельного объекта на базе старого. Соответственно мне не понятен круг задач, в котором эмуляция мутабельности с помощью пересоздания иммутабельных объектов, работает лучше чем использование мутабельных объектов.
Непонятно выражаетесь. Здесь процесс и объект — это артефакты моделирования? Или имеется в виду "реальный производственный процесс"?
Если первое — то рассуждение не имеет смысла. Само понятие состояния объекта возникло в результате определённого подхода к моделированию. Ну, то есть, собственно, при написании кода и возник этот "мутабельный объект".
А если второе — то не вижу смысла копировать особенности поведения "внешней" среды в коде.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[38]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.11.10 14:29
Оценка:
Здравствуйте, Undying, Вы писали:


U>Т.е. если у меня есть объект с десятком свойств, то я должен написать для него конструктор все эти десять свойств принимающий, а затем при модификации объекта вызывать этот конструктор, руками набивая в него 9 неизменившихся свойств и 1 изменившееся?

Если ты пишешь на языке без поддержки иммутабельности — то да, так и придётся.

Как видим, к одному readonly свести иммутабельность не удалось.

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

t = t.SetB(56);


Или хотя бы автомат, который бы не требовал от тебя писать вот этот boilerplate:
...
public int B
{ 
  get { return _b; } 
//  set { _b = value;} // setters are evil! Use SetB instead.
}
public MyClass SetB(int value) 
{
  return new MyClass(this.A, value, this.C, this.D, this.E, this.F, this.G);
}

Видим, что объём кода, нужный для обеспечения изменений B в иммутабл классе, на порядок больше, чем аналог для мутабл класса.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.11.10 18:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>Попрошу сделать обертку для Dictionary<TKey, TValue>, что бы не кидала исключений, сохраняла интерфейс и вообще вела себя как IDictionary<TKey, TValue>. Может ответ сам найдется...

S>Как IDictionary в FP стиле она себя вести не должна.
S>Потому, что в FP стиле IDictionary придётся определять по-другому. Вместо всех сеттеров придётся писать методы, возвращающие новый экземпляр иммутабельного Dictionary.
А так же убрать Remove(TKey) и изменяющие методы ICollection<T> (Add, Remove, Clear). Но отказавшись от стандартных интерфейсов мы потеряем возможность использовать свою коллекцию в методах фреймворка и не только, например там где могла бы пролезть ICollection<T> (Enumerable.Count, Last, ... для нее сработали бы с O(1)). Поддержать эти интерфейсы можно лишь реализовав эти модифицирующие методы возбуждением NotSupportedException. Примерно об этом я думал, когда отвечал в сообщении
Автор: samius
Дата: 19.11.10
.
Как обычно я срезал пару углов и предоставил догадываться о ходе своих мыслей форумчанам самостоятельно
Впрочем, я овечал в контексте невозможности контроля за изменением данных с помощью одного лишь readonly, безотносительно FP стиля "изменения" неизменяемых структур данных.
Re[15]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.11.10 18:59
Оценка:
Здравствуйте, samius, Вы писали:

S>например там где могла бы пролезть ICollection<T> (Enumerable.Count, Last, ... для нее сработали бы с O(1)).

Когда писал Last, думал уже о IList<T>
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 19:00
Оценка:
FR>Lisp отсюда точно вычеркивай, он практически все парадигмы поддерживает.

lisp — функциональный. это уже всякие common-lisp — объекты держит и т.д.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 27.11.10 21:30
Оценка:
Здравствуйте, DarkGray, Вы писали:

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


А часто некоторые экземпляры так вообще не создаются.

Переиспользование памяти явное:
ones = 1 : ones


Плюс, вспоминаем про tail recursive.

DG>2. есть только ленивые вычисления, нет энергичных вычислений


Это совершенно неправда.

1. seq, ($!)
2. Bang patterns
3. Strict datatypes
4. deepSeq, import Strategies...

DG>3. язык строго типизированный


Да, но cast, Dynamic — то, что первое приходит в голову.
Re[47]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.11.10 22:03
Оценка:
L>Переиспользование памяти явное:
L>
L>ones = 1 : ones
L>


и откуда следует что память будет использована та же самая?
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 04:42
Оценка:
Здравствуйте, samius, Вы писали:

U>>Какие конкретно инварианты в таком коде нарушить сложнее?

S>Например, если список не пуст после построения, он таким и останется до конца своего существования. Его не надо защищать от записи, опасаясь что кто-то забудет обновить changeTick.

Во-первых, changeTick это оптимизация. В честном решении входом кэша цены являются цены товаров корзины. Однако массив это достаточно тяжелый для проверки вход, то в таких случаях приходится использовать changeTick. В случае простых входов (несколько ссылок и/или примитивных типов) changeTick'и не нужны. При этом changeTick дает оптимальную скорость как на чтение, так и на модификацию, в то время как решение на иммутабельных объектах дает оптимальную скорость на чтение, но тормоза при модификации (из-за лишних пересозданий объектов).

Во-вторых, в чисто иммутабельном решении получается, что функции меняющей элемент коллекции надо давать права на пересоздание всей коллекции. Соответственно если в мутабельном решении функция изменяющая элемент коллекции физически не может испортить всю коллекцию, то в иммутабельном решении аналогичная функция может заменить исходную коллекцию на что угодно. Т.е. в общем случае функция передвигающая песчинку должна обладать правами на пересоздание, а соответственно и на произвольное изменение/уничтожение вселенной. Как это сочетается с требованиями надежности и безопасности совершенно не понятно.
Re[45]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 04:47
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>если мир создается каждый раз с нуля, то путь построения мира (в том числе кэшей) всегда один и тот же


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

DG>в варианте с changetick-ами можно или забыть поменять changetick после обновления,


Оптимизация требует жертв. В данном случае впрочем очень небольших.

DG>или забыть где-то поставить зависимость по пересчету кэша на основе этого changetick-а (особенно это касается редко меняющихся справочников).


Точно также и в иммутабельном коде можно забыть поставить зависимость кэша от одного из входов. Тут разницы никакой.
Re[15]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.11.10 05:27
Оценка:
Здравствуйте, samius, Вы писали:
S>А так же убрать Remove(TKey) и изменяющие методы ICollection<T> (Add, Remove, Clear).
Не убрать. Заменить их на методы, возвращающие новый экземпляр словаря.

S>Но отказавшись от стандартных интерфейсов мы потеряем возможность использовать свою коллекцию в методах фреймворка и не только, например там где могла бы пролезть ICollection<T> (Enumerable.Count, Last, ... для нее сработали бы с O(1)).

Это другой вопрос. Весь фреймворк построен на интерфейсах, подразумевающих mutable-объекты. Что является вторым основным препятствием для массового применения immutable — после отсутствия поддержки в языке.
Ну и само это решение тоже не самостоятельное — это следствие отстутствия в среде исполнения эффективных реализаций подобных интерфейсов. Насколько я понимаю, реализовать произвольные методы модификации через порождение новых экземпляров с приемлемой производительностью не так-то просто. Ну то есть я легко представляю метод Dictionary Dictionary.Clear(), работающий за O(1). С .Remove() я бы не справился.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 05:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Непонятно выражаетесь. Здесь процесс и объект — это артефакты моделирования? Или имеется в виду "реальный производственный процесс"?

Процесс в данном контексте это нечто длящееся во времени. Например, пользователь зашел на сайт, соответственно создалась сессия. Те параметры сессии, которые в процессе пребывания пользователя на сайте не меняются делаем иммутабельными, остальные мутабельными.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.11.10 05:57
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>>>Какие конкретно инварианты в таком коде нарушить сложнее?

S>>Например, если список не пуст после построения, он таким и останется до конца своего существования. Его не надо защищать от записи, опасаясь что кто-то забудет обновить changeTick.

U>Во-первых, changeTick это оптимизация. В честном решении входом кэша цены являются цены товаров корзины. Однако массив это достаточно тяжелый для проверки вход, то в таких случаях приходится использовать changeTick. В случае простых входов (несколько ссылок и/или примитивных типов) changeTick'и не нужны. При этом changeTick дает оптимальную скорость как на чтение, так и на модификацию, в то время как решение на иммутабельных объектах дает оптимальную скорость на чтение, но тормоза при модификации (из-за лишних пересозданий объектов).

Неважно, что changeTick оптимизация. Любому, кто меняет коллекцию, нужно его обновить. Если это не будет сделано, программа будет работать неверно. А средства, которые позволят "не забыть" это сделать, подпорчивают дизайн.

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

Это в мутабельном решении нужно следить за правами на изменение коллекции. Запрещать создавать что-либо в иммутабельном подходе смысла нет.

U>Соответственно если в мутабельном решении функция изменяющая элемент коллекции физически не может испортить всю коллекцию, то в иммутабельном решении аналогичная функция может заменить исходную коллекцию на что угодно.

Ровно наоборот. Мутабельную коллекцию испортить по определению легко. Иммутабельную заменить по определению нельзя, т.к. структуры данных, на нее ссылающиеся иммутабельны.

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

Любая функция может создавать любые данные, но подменить что-либо не в состоянии, если это не предусмотрено дизайном.
Вот смотри:
int Sum(IList<int>) // нет и тени уверенности что список останется неизменным.
int Sum(IEnumerable<int>) // изменить данные сложнее чем с IList.
Так где проблемы с безопасностью?
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.11.10 06:28
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, DarkGray, Вы писали:


DG>>если мир создается каждый раз с нуля, то путь построения мира (в том числе кэшей) всегда один и тот же


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


Пересоздание с нуля встречается в FP не так и часто, кроме того, поддается оптимизации.
Например, вместо того что бы добавить множество элементов в хвост энергичного иммутабельного списка, можно добавлять их в начало, а потом инвертировать список. Из квадратичной сложности получили линейную.
Re[48]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 07:11
Оценка:
Здравствуйте, DarkGray, Вы писали:

L>>Переиспользование памяти явное:

L>>
L>>ones = 1 : ones
L>>


DG>и откуда следует что память будет использована та же самая?


Не совсем понял вопроса. Из определения видно, что хвост ones есть сам список ones.
Re[49]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 10:00
Оценка:
L>Не совсем понял вопроса. Из определения видно, что хвост ones есть сам список ones.

так в том-то и дело, что есть только надежда, что компилятор догадается и переиспользует память, а может не догадается и не переиспользует.
и нет явного способа зафиксировать переиспользование памяти
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 10:08
Оценка:
U>Проблема в том, что ежели пересоздавать вселенную при каждом изменении атома, то пупок может развязаться. Соответственно такое решение может работать только в задачах с легким состоянием, при тяжелом состоянии на пересоздание с нуля никаких ресурсов не хватит.

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

DG>>или забыть где-то поставить зависимость по пересчету кэша на основе этого changetick-а (особенно это касается редко меняющихся справочников).


U>Точно также и в иммутабельном коде можно забыть поставить зависимость кэша от одного из входов. Тут разницы никакой.


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

> Оптимизация требует жертв. В данном случае впрочем очень небольших.


на практике — оптимизация (уменьшение) времени работы разработчиков требует еще больше жертв, чем оптимизация работы машинки.

например, ФЯ активно используются (и тренд сильно положительный) в нише прототипирования (опытной разработки) — где код часто меняется (и легко что-нибудь забыть не отследить), разработчики используются очень квалифицированные, время их дорого, а сами они выше той работы — которую можно автоматизировать.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 10:45
Оценка:
U>Проблема в том, что ежели пересоздавать вселенную при каждом изменении атома, то пупок может развязаться. Соответственно такое решение может работать только в задачах с легким состоянием, при тяжелом состоянии на пересоздание с нуля никаких ресурсов не хватит.

кстати gridsynchronizer работает именно на концепции "каждый раз мир пересоздается с нуля", и поэтому достаточно легко под него код писать.
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 29.11.10 10:49
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

DG>и нет явного способа зафиксировать переиспользование памяти

В типичной реализации списка переиспользует точно.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 29.11.10 10:50
Оценка:
Здравствуйте, Undying, Вы писали:

U>Ссылочная прозрачность мне даром не нужна. Мне нужно 1) чтобы ссылок было минимально возможное количество, т.е. чтобы объекты не создавались без необходимости 2) чтобы по коду легко было определить какие ссылки по условию задачи являются неизменяемыми, а какие нет. Мутабельный подход легко позволяет создавать решения удовлетворяющие и первому, и второму условию, чисто иммутабельный подход противоречит обоим условиям.


Выше нам продемонстрировали уже это "легко".
Re[47]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 10:57
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>кстати gridsynchronizer работает именно на концепции "каждый раз мир пересоздается с нуля", и поэтому достаточно легко под него код писать.


И где это в GridSynchronizer используется иммутабельный источник данных, который пересоздается с нуля при каждом изменении? Используй GridSynchronizer только иммутабельные источники данных это кошмар был бы, а не революционное решение. GridSynchronizer это честный (т.е. проверяющий все входы, а не ссылки на содержащие входы объекты) кэш поверх мутабельных исходных данных, поэтому он и удобен.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 11:02
Оценка:
U>Во-вторых, в чисто иммутабельном решении получается, что функции меняющей элемент коллекции надо давать права на пересоздание всей коллекции.

реальные права на пересоздание есть только у движка.
у отдельной функции есть только право "описать желание изменить часть вселенной".
дальше движок все эти желания склеивает, проверяя при этом права каждого пожелавшего, и перестраивает вселенную.
Re[51]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 11:03
Оценка:
FR>В типичной реализации списка переиспользует точно.

если бы это было правдой, то не надо было бы извращаться при реализации quicksort

http://en.literateprograms.org/Quicksort_(Haskell)
Re[48]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 11:07
Оценка:
U>И где это в GridSynchronizer используется иммутабельный источник данных, который пересоздается с нуля при каждом изменении? Используй GridSynchronizer только иммутабельные источники данных это кошмар был бы, а не революционное решение. GridSynchronizer это честный (т.е. проверяющий все входы, а не ссылки на содержащие входы объекты) кэш поверх мутабельных исходных данных, поэтому он и удобен.

не путай описание чистой концепции и ее реализацию в смешанном окружении.

то, что делается gridsynchronizer-ом каждый тик в runtime-е, в ФЯ делается один раз при компиляции.
Re[52]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 29.11.10 11:15
Оценка:
Здравствуйте, DarkGray, Вы писали:


FR>>В типичной реализации списка переиспользует точно.


DG>если бы это было правдой, то не надо было бы извращаться при реализации quicksort


DG>http://en.literateprograms.org/Quicksort_(Haskell)


Выше было отсекание головы спсика, в этом случае точно переиспользуется для qsort только отсекания недостаточно.
Re[48]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 11:32
Оценка:
U>И где это в GridSynchronizer используется иммутабельный источник данных, который пересоздается с нуля при каждом изменении? Используй GridSynchronizer только иммутабельные источники данных это кошмар был бы, а не революционное решение. GridSynchronizer это честный (т.е. проверяющий все входы, а не ссылки на содержащие входы объекты) кэш поверх мутабельных исходных данных, поэтому он и удобен.

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

gridsync использует переосмысленную концепцию "мир создается с нуля".
при этом changetick — это есть маркер, который показывает остальному миру, что можно считать, что данная часть мира иммутабельна пока неизменен changetick, и пересоздана с нуля — когда changetick поменялся.

зы
и программисту вообще стоит отличать концепции от того, что в реальном коде происходит.
ФЯ, ООП, АОП, иммутабельность, sql, стековый исполнитель и т.д. — это все концепции, которые упрощают описание происходящего и которые никакого отношения не имеют к тому, что происходит при реальном выполнении

мир пересоздается с нуля — такая же концепция, которая в реальном коде преобразуется например в то самое — изменение по месту, и выставлении вышестоящего changetick-а.

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

чистые академические языки (большая часть ФЯ, pascal, smalltalk, prolog и т.д.) они сдвинуты в сторону описания, и делание подгоняется под описание. mainstream(промышленные) языки — сдвинуты в сторону делания, и в них описание подгоняется под выполнение.
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 11:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>smalltalk точно не имеет, потому что публично он был предоставлен в 80-м


Какая разница, когда он был представлен публично?

DG>а simula-у правильнее сравнивать с lisp-ом, чем с haskell-ем.

DG>simula — это одна из самых ранних попыток реализовать ОО-концепцию, lisp — ранная попытка реализовать ФЯ-концепцию.

А еще lisp — ранняя попытка реализовать ОО-концепцию.

DG>причем lisp появился на 10 лет ранее, чем simula, и тогда ФЯ-концепции вообще уже 50 лет.


Не важно, сколько лет ФЯ концепции. Мы говорим не просто о ФЯ, а о декларативных ФЯ. Это довольно новые языки. Самый старых их предок это какой-нибудь KRC, аналогичный по дальности предок ОО — это Sketchpad 63-го года. Для них более-менее нормальный способ осуществлять IO придумали и реализовали в начале 90-х — о каких 50-и годах тут может идти речь? А императивные ФЯ уже какое-то время в мейнстриме. Вот C#, например, императивный ФЯ.

DG>и соответственно сравнение haskell-я со smalltalk-ом, имхо, является справедливым, также как сравнение simula с lisp-ом.


Да, какой-нибудь haskell 2020 можно будет сравнивать со смолтоком 80.

DG>а тому же haskell-у уже 20 лет прошло.


Столько лет прошло со времен первых заседаний комитета. Первый стандарт Хаскеля вышел в 99, в нем даже FFI не было. Хаскель 98 вообще предназначен, в основном, для обучения. Все интересные языковые фичи Хаскеля в настоящий момент — это экспериментальные расширения, причем часто расширения одной единственной реализации. Естественно, они никак не стандартизированы.

DG>фундаментального закона, но скорость внедрения является индикатором преимуществ того или иного подхода (того или иного языка).


Без учета принципиальной новизны перехода от нового подхода к старому такой индикатор только введет в заблуждение.
Никаких прогнозных сроков для внедрения декларативных ФЯ из сроков внедрения ООЯ вывести не получится — это несопоставимые шаги в развитии языков. Я, в основном, старался просто указать на нелепость самой поставновки вопроса "а сколько сейчас проектов?". Потому, что в 1850-ом году электровозы перевезли 0 тонн груза, а в 1930-ом году ядерные электостанции произвели 0 киловатт-часов электроэнергии. И что, какой из этих этих фактов в то время должен был следовать вывод?

DG>Исходя из данного индикатора можно сделать вывод, что haskell может быть и хорош, но не настолько сильно, что необходимо все бросать и переходить на него. в тоже время раз он еще не умер, а развивается, то можно сделать вывод: что у него есть плюсы важные для определенного круга людей, но в тоже время — есть существенные минусы, которые не позволяют остальным на него перейти.


Хаскель сейчас находится на полпути между зачатием и рождением. Поэтому следует удивляться тому, что с ним связана вообще хоть какая-то активность отличная от написания диссертаций.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[46]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 11:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

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


Это заблуждение. Во-первых, в чистых языках переиспользовать память даже легче — большая часть иммутабельных структур переиспользуется. Во-вторых, если под "переиспользованием памяти" понимается, например, модификация массива по месту, без сохранения старой верии, то и это возможно.

DG>2. есть только ленивые вычисления, нет энергичных вычислений


Это заблуждение.

DG>3. язык строго типизированный


Что не может не радовать. Потому, что как раз использование слаботипизированных языков на практике приводит к проблемам.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 11:33
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

DG>и нет явного способа зафиксировать переиспользование памяти

В этой ситуации обязательно использует. Всё таки ones — это конкретный идентификатор, ссылающийся на конкретный thunk. Это и есть явный способ.

Referential transparency гарантирует, что можно шарить не только переменную, но и выражения. Например, можешь почитать про cse.
Re[49]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 11:33
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>не путай описание чистой концепции и ее реализацию в смешанном окружении.


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

DG>то, что делается gridsynchronizer-ом каждый тик в runtime-е, в ФЯ делается один раз при компиляции.


Не понял. То есть в ФЯ не будет нужно крутить таймер? ФЯ не ленивый что ли и при изменении ссылки энергично перестраивает всех кто от этой ссылки зависит?
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 11:38
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>есть только надежда, что компилятор догадается


В принципе, в этом вся суть языков высокого уровня.

DG> и переиспользует память, а может не догадается и не переиспользует.

DG>и нет явного способа зафиксировать переиспользование памяти

Но это не тот случай. Здесь как раз "переиспользование памяти" задано в коде явно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[53]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 11:40
Оценка:
FR>Выше было отсекание головы спсика, в этом случае точно переиспользуется для qsort только отсекания недостаточно.

или другими словами — переиспользование памяти есть, но только в редких частных случаях — о чем и шла речь.

утверждение вида: "в языке есть инструмент xxx" верно, только — если инструмент xxx позволяет решать широкий круг задач, а в идеале все задачи, требующие использование данного инструмента,
иначе верно утверждение — "в языке есть элементы инструмента xxx".
и соответственно верны следующие утверждения:
в C# есть переиспользование памяти,
в C/C++ — есть полный контроль над памятью,
в haskell-е есть очень редкие элементы переиспользования памяти (которых даже не хватает для описания алгоритма quicksort).

так же верно, что в:
в C/C++ и C# — есть элементы функциональщины, но не более (и которых даже не хватает на описание алгоритмов с хвостовой рекурсией)
Re[54]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 29.11.10 12:04
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>в haskell-е есть очень редкие элементы переиспользования памяти (которых даже не хватает для описания алгоритма quicksort).


В Хаскеле да, в ML семействе также как в Java/C#.
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 12:08
Оценка:
U>А ты уверен, что решением в рамках чистой концепции будет удобно пользоваться? Не окажется ли что все удобство как раз в возможности работать в смешанном окружении окажется?

я в этом треде фиксирую строго обратное, что чистая концепция удобна лишь для того, чтобы:
1. во-первых, детально разобрать ее, и сделать полезные находки
2. с помощью чистой концепции описать часть или аспект реальной программы

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

DG>>то, что делается gridsynchronizer-ом каждый тик в runtime-е, в ФЯ делается один раз при компиляции.


U>Не понял. То есть в ФЯ не будет нужно крутить таймер? ФЯ не ленивый что ли и при изменении ссылки энергично перестраивает всех кто от этой ссылки зависит?


скажу про идеальный достижимый вариант для смешанного окружения:
1. программа спит все время пока нет изменений
2. все изменения склеиваются в единый пакет — который отрабатывается как единое целое. отработка идет в момент прихода внешнего сообщения

самое сложное здесь — это на этапе компиляции (разработки) определить что такое один пакет изменений.
общий подход: один пакет изменений — одно сообщение пришедшее снаружи — работает только пока, скорость обработки сообщений много выше скорости прихода сообщений.
и соответственно, можно, например, считать, что каждое нажатие на кнопку(контрол) — это есть отдельный пакет изменений.
но вот каждое нажатие на клавишу или каждое изменение положение курсора мыши — если это требует больших пересчетов — уже может трактоваться как часть пакета.
Re[54]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 12:16
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>в haskell-е есть очень редкие элементы переиспользования памяти (которых даже не хватает для описания алгоритма quicksort).


В целом верно. Но тут важно понимать, что переиспользование памяти — всего лишь техника. В случае чистых языков просто используют другие техники/алгоритмы. Например, для ленивых списков (которые по сути linked) используют mergesort. Для мутабельных же массивов вполне подойдёт quicksort — но код будет уже не чистым.
Re[51]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 12:20
Оценка:
DG>>есть только надежда, что компилятор догадается

K>В принципе, в этом вся суть языков высокого уровня.


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

возьмем тот же .net — в нем есть только надежда, что один и тот же элемент будет всегда расположен в одном и тот же месте, и для большинства задач этого достаточно. но в ряде критических мест особенно при стыковке с legacy-кодом этого недостаточно, и в язык, и в движок введены понятия fixed, GlobalAlloc и т.д.

с этим же связано появление dynamic в 4-ой версии: это есть следствие, что обычно достаточно надежды что на этапе компиляции легко зафиксировать тип элементов, но в ряде случаев, опять же при стыковке с внешним окружением — это не получается.
Re[49]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 29.11.10 12:24
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>есть чистая концепция (которая и реализована в ФЯ), а есть ее переосмысление и развитие на реальный код, который использует смешанные стратегии.


Есть чистая концепция — при изменении входа значение должно быть пересчитано. GridSynchronizer эту чистую концепцию реализует в полной мере, он честно проверяет весь вход и производит перерисовку, если вход изменился.

Однако чистая концепция не позволяет работать с тяжелыми входами, поэтому возникает необходимость в оптимизации, оптимизации бывают двух видов:

1) Для тяжелых входов вводим changeTick'и и проверку входов производим через них, а не через честное сравнение значений входов.
2) Используем только иммутабельные объекты, что позволяет вместо честного сравнения значений входов использовать сравнение ссылок.

Реализовать в gridSynchronizer'е хоть первую, хоть вторую оптимизацию означает испортить решение, т.к. решение прекрасно работает в рамках чистой концепции и отказа от чистоты ради оптимизаций не требует.

DG>чистая концепция использует допущение, что на этапе компиляции можно отследить все изменения данных, в реальном сложном приложение — выполнить это допущение нереально, поэтому используется смешанная концепция — которая фиксирует, что на этапе компиляции(разработки кода) можно отследить все изменения в отдельном участке кода (чем ты и занимаешься при развешивании кода, который меняет changetick)


Где ты в gridSynchronizer'е увидел changeTick'и?
Re[55]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 12:27
Оценка:
L>Но тут важно понимать, что переиспользование памяти — всего лишь техника.

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

отсутствие в языке техники "переиспользование памяти" — на практике может означать невозможность решения задачи из-за того, что:
1. есть алгоритм который эту технику использует,
2. при реализации в лоб на языке без этой техники — резко вырастают затраты на выполнение (в том числе и экспонециально),
3. и нет гарантированного способа(алгоритма) который позволяет переписать имеющийся алгоритм на другую технику, поддерживаемую в данном языке.
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 12:39
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>отсутствие в языке техники "переиспользование памяти" ...


... — предположение, которое не соотвествует действительности.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 12:48
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>отсутствие в языке техники "переиспользование памяти" — на практике может означать невозможность решения задачи из-за того, что:

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

Я же написал другие алгоритмы. Хороший пример — зиппер.

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

2 — неправда насчёт резко/экспоненциально. Работает так: иногда получаются алгоритмы логарифмической сложности вместо константной, или NlogN против линейной, но и тут есть обходные пути — можно почитать про амортизационную сложность у Окасаки.
Re[52]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 12:59
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

DG>и соответственно чистые академические языки — это противоречие игнорируют.

Что такое "чистый академический язык"? Примеры можно?

DG>промышленные языки пытаются с этим противоречием бороться.

DG>возьмем тот же .net — в нем есть только надежда, что один и тот же элемент будет всегда расположен в одном и тот же месте

Нет там такой надежды. Там надежда противоположная — можно надеяться на то, что GC уплотняет кучу. А потому, если все идет по плану элемент на одном месте не останется. Но это только надежда: fixed может поставить на уплотнении кучи жирный крест.

DG>, и для большинства задач этого достаточно. но в ряде критических мест особенно при стыковке с legacy-кодом этого недостаточно, и в язык, и в движок введены понятия fixed, GlobalAlloc и т.д.


Это есть везде, где нужен FFI. Т.е. навскидку я не могу припомнить ни одного языка, где этого нет, ну за исключением всяких эзотерических анлямбд.
Не уж то кто-то всерьез считает, что в Хаскеле этого нет?

DG>с этим же связано появление dynamic в 4-ой версии: это есть следствие, что обычно достаточно надежды что на этапе компиляции легко зафиксировать тип элементов, но в ряде случаев, опять же при стыковке с внешним окружением — это не получается.


В Хаскеле аналог dynamic появился раньше, чем в C#, в этом, впрочем, нет ничего хорошего.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 13:16
Оценка:
U>Есть чистая концепция — при изменении входа значение должно быть пересчитано. GridSynchronizer эту чистую концепцию реализует в полной мере, он честно проверяет весь вход и производит перерисовку, если вход изменился.

давай распутаем какие концепции использует gridsynchronizer

концепция 1 — замена push на pull. если изначально утверждается, что каждое изменение должно быть сразу пересчитано, то grid synchronizer утверждает обратное — пересчитывать будем только то, что спрашивают.

при этом концепция 1 опирается на
концепция 1б. ленивость вместо энергичности.

это тянет за собой следующие концепции:
концепция 2. единый поток управления
концепция 3. отсутствие побочных эффектов (все есть функция, нет процедур)
концепция 4. перестройка мира с нуля (gridsync свой выход(грид) каждый раз пытается строит с нуля)

концепция 4 — тяжелая, и требует:
концепция 5. замена полной перестройки мира на частичную: перестройка только измененной части

концепция 5 требует:
концепция 6. быстрое определение измененной части

концепция 6 требует:
концепция 7. иммутабельность (хотя бы частичную). когда по большому куску данных требуется быстро сказать менялся он или нет.
концепция 8. по изменению входа быстро понять какая часть результата меняется
концепция 9. по результату понять от каких входов он зависит

все эти концепции вирусные, они требуют чтобы код используемый из под gridsync тоже был таким же (иначе весь эффект теряется)
и соответственно те же кэши с changetick-ом — это часть gridsync-а, т.к. именно наличие gridsync-а требует такого построения кода.

кэши с changetick-ом используются для построения кодам таким образом, чтобы он удовлетворял требованиям вышеуказанных концепций

U>Где ты в gridSynchronizer'е увидел changeTick'и?


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

при этом из-за того, что все это отслеживание делалось в ручную, дальнейшее наращивание мощности gridsync-а затруднительно — из-за сложности удержания всех концепций и зависимостей в голове.
Re[53]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 13:40
Оценка:
DG>>и это вступает в противоречие с реальными задачи в которых в критических местах требуется гарантия, а не надежда.
DG>>и соответственно чистые академические языки — это противоречие игнорируют.

K>Что такое "чистый академический язык"? Примеры можно?


например, pascal как введенный Виртом

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

K>Не уж то кто-то всерьез считает, что в Хаскеле этого нет?

fixed там точно нет
Re[57]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 13:50
Оценка:
L>Я же написал другие алгоритмы. Хороший пример — зиппер.

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

или даже спрошу по другому: какие требования в резюме необходимо выставить, чтобы пришедший человек, удовлетворяющий этим требованиям, гарантировано хотя бы за пару дней въехал в данный подход?
Re[58]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 13:51
Оценка:
DG>или даже спрошу по другому: какие требования в резюме необходимо выставить, чтобы пришедший человек, удовлетворяющий этим требованиям, гарантировано хотя бы за пару дней въехал в данный подход?

и да — какой оклад данному человеку стоит положить (например, для Москвы)?
Re[54]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 29.11.10 14:03
Оценка:
Здравствуйте, DarkGray, Вы писали:

K>>Что такое "чистый академический язык"? Примеры можно?

DG>например, pascal как введенный Виртом

Ладно, пример есть. Но вопрос остался.
Что такое "чистый академический язык"?

K>>Не уж то кто-то всерьез считает, что в Хаскеле этого нет?

DG>fixed там точно нет

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Foreign-StablePtr.html#t:StablePtr

A stable pointer is a reference to a Haskell expression that is guaranteed not to be affected by garbage collection, i.e., it will neither be deallocated nor will the value of the stable pointer itself change during garbage collection (ordinary references may be relocated during garbage collection). Consequently, stable pointers can be passed to foreign code, which can treat it as an opaque reference to a Haskell value.

... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[55]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 14:29
Оценка:
K>Что такое "чистый академический язык"?

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

язык академический — если не рассматривается и не решается задача в которой нарушаются ограничения концепции.

зы
например, нарушением концепции "все есть объект" является введение атомарных типов (числа, булы, строки и т.д.) как не совсем объектов.
исходя из этого критерия — smalltalk — академический, Java, C++, C# — не академические.
Re[55]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 14:36
Оценка:
K>A stable pointer is a reference to a Haskell expression that is guaranteed not to be affected by garbage collection

и опять полумера.
fixed — это же не только пометка для gc. это еще возможность быстро побегать по данной памяти через семантику указателя на память.
Re[58]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 29.11.10 14:51
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>ты забываешь про существенное дополнение "рано или поздно достаточно умный человек сможет переписать алгоритм, чтобы он не требовал такой техники".

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

Конкретно о чём мы говорим? На Haskell можно писать? Можно. Удобно? Удобно. Чтобы это делать — надо учиться? Надо. Как и везде.

DG>самое фиговое что большинство фундаментальных алгоритмов записана именно в терминах переиспользования памяти:


А как же их на Haskell умудрились переписать?

Насчёт большинства алгоритмов и переиспользования памяти — если нужен такой алгоритм — бери и переиспользуй память. Haskell это позволяет. Есть IORef, есть мутабельные массивы (IO и ST).

DG>и ты предлагаешь все алгоритмы которые в универе только рассказывали пару лет, обычному программисту в одиночку за пару дней переосмыслить как их эффективно записать без переиспользования памяти?


Мне эти алгоритмы объясняли вообще на псевдоязыке. И ты предлагаешь мне их за пару дней переписать на Java? Вот так я твой вопрос вижу. Странный он для меня.

DG>т.е. ты действительно считаешь, что возможности отдельного программиста равны возможностям ученых всего мира, которые думали над алгоритмами последние 100 лет?


Я не вижу причин для такого вывода.

Абсолютно симметрично — возможности обычныго императивного программиста сопоставимы с возможностями учёных мира за 100 лет? Если нет, то как же он алгоритмы пишет? Подсматривает у этих учёных? Ну так точно так же и функциональщики работать могут.
Re[57]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 15:52
Оценка:
k> Даже в Прологе есть (!) что уж про другие "академические" языки говорить?

в исходном? или в одной из реализаций?

и кстати что именно есть?

ты для начала зафиксируй какие концепции реализует пролог, ограничения этих концепций — а уже потом говори что там что-то "есть".

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

K>Какой-то странный пример. Какие ограничения у чисел-"объектов"? И почему в C# число — "не совсем объект"?


чистая концепция ООП — каждому объекту можно послать сообщение, которое он может как хочет отработать.

на практике — эта концепция смешивается с повторным использованием кода (наследованием) и со статик типизацией — результатом являются объекты с фиксированным списком виртуальных методов.

> И почему в C# число — "не совсем объект"?


и соответственно число в C# — это не совсем объект: у него нет виртуальных методов, от него нельзя наследоваться, оно по другому хранится чем настоящие объекты.
Re[59]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 16:01
Оценка:
L>Мне эти алгоритмы объясняли вообще на псевдоязыке. И ты предлагаешь мне их за пару дней переписать на Java? Вот так я твой вопрос вижу. Странный он для меня.

что такое алгоритмическая задача (и что такое неалгоритмическая задача) — тебе понятно?
и что и машину, и человека легко научить решать алгоритмические задачи?
и что почти невозможно научить решать неалгоритмические задачи?

тебе понятно — что задача переписывание с псевдоязыка на Java есть алгоритмическая задача?
и тебе понятно — что задача переписывания алгоритма с техники переиспользования памяти на другую технику — есть неалгоритмическая задача?

DG>>т.е. ты действительно считаешь, что возможности отдельного программиста равны возможностям ученых всего мира, которые думали над алгоритмами последние 100 лет?


L>Я не вижу причин для такого вывода.


L>Абсолютно симметрично — возможности обычныго императивного программиста сопоставимы с возможностями учёных мира за 100 лет? Если нет, то как же он алгоритмы пишет? Подсматривает у этих учёных? Ну так точно так же и функциональщики работать могут.


еще раз повторю — что есть алгоритмические задача, а есть не алгоритмические.
1. переписывание с одного императивного языка на другой императивный — есть алгоритмическая задача.
2. переписывание с ФЯ на императивный язык тоже алгоритмическая задача.
3. а вот обратное преобразование — с императивного на ФЯ это уже не алгоритмическая задача.

соответственно первым двум вещям легко научить, достаточно научить применять алгоритм.
как учить третьему не понятно. только надеяться, что человек умеет как-то сам.
Re[60]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 16:05
Оценка:
DG>>и да — какой оклад данному человеку стоит положить (например, для Москвы)?

L>Не знаю. Ты что ли пучок равшанов хочешь набрать вместо пары нормальных специалистов?


не уходи от ответа — а назови цену.

зы
я знаю, что для того, чтобы все вышеуказанные алгоритмы достаточно эффективно в один один реализовать на C#, Java и т.д. — можно брать человека и за 30-50 тыс. в москве.
пару месяцев его понадобится поднатаскать, а дальше это он будет делать это сам.
Re[61]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 16:34
Оценка:
> Выдумки какие-то. С чего ты взял, что нужно переписывать алгоритм с техникой переиспользования памяти? Нужно просто взять другой алгоритм. Третий раз курсивом выделяю. Их полно в инете. Если взять одну из сложнейших областей — алгоритмы на графах, то посмотри на inductive graphs как на пример.

откуда следует что для каждого алгоритма с техникой переиспользования памяти есть в инете его аналог без данной техники?



L>В частности, если тебя так интересует формализация (для сведения задачи к алгоритмической) — используй изменяемые значения и текущее положение как аругменты — и алгоритм с переиспользованием памяти превратится в алгоритм без переиспользования


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

зы
напомню, что на практике — если задача имеет только экспонециальный алгоритм — то считается, что задача не имеет алгоритмического решения.
Re[62]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 29.11.10 18:04
Оценка:
L>А я вот не уверен. Я вообще плохо понимаю, почему здесь разговор перешёл не менеджерские рельсы. Мы же вроде о программировании, нет?

да, речь шла о программирование, точнее о сравнении разных подходов(языков) программирования.

но сравнение — не имеет никакого смысла без оценки стоимостной составляющей.

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

ассемблер тоже очень хороший язык, на нем можно решить любую задачу самым эффективным образом. но вот высокая стоимость сопровождения такого решения (в частности большой объем переписываемого кода при внесении изменений) тоже не дает широко использовать данный язык на практике.
Re[63]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 30.11.10 05:54
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>но сравнение — не имеет никакого смысла без оценки стоимостной составляющей.


Совершенно верно! Но давай оценивать стоимость с точки зрения программиста — затраченное время, производительность и т.д.
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: FR  
Дата: 30.11.10 08:06
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>зы

DG>например, нарушением концепции "все есть объект" является введение атомарных типов (числа, булы, строки и т.д.) как не совсем объектов.
DG>исходя из этого критерия — smalltalk — академический, Java, C++, C# — не академические.

Re[58]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 30.11.10 08:51
Оценка:
Здравствуйте, DarkGray, Вы писали:

k>> Даже в Прологе есть (!) что уж про другие "академические" языки говорить?

DG>в исходном? или в одной из реализаций?

Ничего не знаю о реализациях, в которых нет (!).

DG>и кстати что именно есть?


Я же написал что именно: cut (!)

DG>ты для начала зафиксируй какие концепции реализует пролог, ограничения этих концепций — а уже потом говори что там что-то "есть".


Дизъюнкт Хорна.

DG>есть более простой пример академического языка: sql, например.


Ну вот, мы уже с GPL на DSL съехали. А все из-за более чем странного определения "академического языка". Академический язык — это просто язык, имеющий некоторую научную новизну. Язык, на описание которого дают ссылки в статьях, которые не посвящены ему напрямую (SML — пример такого языка). Вот и все, никак это не связано ни с практичностью ни с чистотой концепции. Языков соотвествующих вашему определению "академического языка" вообще, скорее всего, не существует, потому что "рассмотрение и решение задач в которых нарушаются ограничения концепции" — это важная часть исследовательноской работы связанной с "академическими" языками.

K>>Какой-то странный пример. Какие ограничения у чисел-"объектов"? И почему в C# число — "не совсем объект"?

DG>чистая концепция ООП — каждому объекту можно послать сообщение, которое он может как хочет отработать.
DG>на практике — эта концепция смешивается с повторным использованием кода (наследованием) и со статик типизацией — результатом являются объекты с фиксированным списком виртуальных методов.

Это же не ответ на вопрос "Какие ограничения у чисел-"объектов"?".

>> И почему в C# число — "не совсем объект"?

DG>и соответственно число в C# — это не совсем объект: у него нет виртуальных методов, от него нельзя наследоваться, оно по другому хранится чем настоящие объекты.

Вот такая в C# объектная система. Программист сам может определить класс объектов, у которого нет виртуальных методов, от которого нельзя наследоваться и который по другому хранится. Поэтому число ничем от других объектов не отличается.
Кроме того, числа много где можно "хранить по другому" и вообще специальным образом обрабатывать некоторые сообщения. Думаете, в Smalltalk все целые числа в памяти в виде синглетонов хранятся?

Ну и, чтоб два раза не вставать:
DG>fixed — это же не только пометка для gc. это еще возможность быстро побегать по данной памяти через семантику указателя на память.
Это в первую очередь средство интеропа, что в C#, что в Haskell. А возможность "бегать по данной памяти через семантику указателя" — ну бегайте, насколько это будет быстро зависит от реализации. Но принципиальных ограничений на использование указателей нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[63]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 10:02
Оценка:
L>Из равной мощности языков. Из того, что задачи на таких языках решаются, а языки не заявляются как менее мощные.

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

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

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

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

например, нет хорошого алгоритма чтобы из записи
TItem[] items = ...
var _result = new List<TItem>();
for(int i = 0; i < items.Length; ++i)
 if (items[i] > 10)
  result.Add(items[i]);
result = _result.ToArray();

сделать запись
result = items.Where(item=>item > 10).ToArray();

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

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

зы
задача повышения емкости ставится — потому что емкость записи очень тесно связана со скоростью выполнения. чем короче запись, тем меньше там лишнего кода — тем быстрее код выполняется.
Re[51]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 30.11.10 10:14
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>все эти концепции вирусные, они требуют чтобы код используемый из под gridsync тоже был таким же (иначе весь эффект теряется)

DG>и соответственно те же кэши с changetick-ом — это часть gridsync-а, т.к. именно наличие gridsync-а требует такого построения кода.

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

DG>кэши с changetick-ом используются для построения кодам таким образом, чтобы он удовлетворял требованиям вышеуказанных концепций


DG>при этом из-за того, что все это отслеживание делалось в ручную, дальнейшее наращивание мощности gridsync-а затруднительно — из-за сложности удержания всех концепций и зависимостей в голове.


Что ты понимаешь под "дальнейшим наращиванием мощности gridsync"? Приведи примеры.
Re[63]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 10:57
Оценка:
L>Второй раз в этом комментарии мне приходится повторяться. Не растёт сложность алгоритма экспоненциально. Это неправда или пруфлинк. На сложных алгоритмах бывает, что растёт логарифмически — и это О большое.

т.е. хочешь сказать, что если записывать алгоритмы в лоб — то проблема haskell-я будет только в высоком C в C*O(n)?
просадка по скорости от максимальной 10^4, по памяти 20 (для классического quicksort-а)
Re[59]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 11:02
Оценка:
DG>>ты для начала зафиксируй какие концепции реализует пролог, ограничения этих концепций — а уже потом говори что там что-то "есть".

K>Дизъюнкт Хорна.


там еще есть концепция: что язык сам решает проблему вывода одних условий из других.
и при этом в прологе не рассматривается вариант — когда человек (или другая автоматика) может вмешиваться в этот процесс.
Re[64]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 30.11.10 11:08
Оценка:
Здравствуйте, DarkGray, Вы писали:

L>>Из равной мощности языков. Из того, что задачи на таких языках решаются, а языки не заявляются как менее мощные.

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

У тебя в посылках стоит, что мы переписываем обязательно в более ёмкой форме. Откуда такая посылка?

DG>например, нет хорошого алгоритма чтобы из записи

DG>
DG>TItem[] items = ...
DG>var _result = new List<TItem>();
DG>for(int i = 0; i < items.Length; ++i)
DG> if (items[i] > 10)
DG>  result.Add(items[i]);
DG>result = _result.ToArray();
DG>

DG>сделать запись
DG>
DG>result = items.Where(item=>item > 10).ToArray();
DG>

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

Во-первых. Пример неудачный. Увидев первую запись программист напишет вторую. Слишком явно виден паттерн.
Во-вторых. Я тебе описал как из первого получить вот такое (опускаю массивы, чтобы не расписывать кучу деталей):
f items = go 0 empty
  where
    go i result | i < length items = result
                | i > 10           = go (i + 1) (add (get i items) result)
                | otherwise        = go (i + 1) result

Единственное, я здесь пропустил промежуточный этап — явно автоматический перевод if-ов в гарды.
В-третьих. Меня мало интересует _перевод_ алгоритма. Потому что за весь мой небольшой опыт мне приходилось сотни раз находить алгоритмы и лишь однажды переписывать из императивной формы.

DG>при переписывании с одного языка на другой язык — ставится задача сохранить емкость запись (хотя бы на уровне двоичного порядка).

DG>если языки имеют разный набор техник — то при алгоритмизированном переписывании емкость записи теряется, и появляется неалгоритмизированная задача — по уменьшению емкости записи

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

DG>зы

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

Некорректно. Опять берёшь один критерий и по нему оцениваешь сложную величину.
Re[64]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 30.11.10 11:10
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>т.е. хочешь сказать, что если записывать алгоритмы в лоб — то проблема haskell-я будет только в высоком C в C*O(n)?

DG>просадка по скорости от максимальной 10^4, по памяти 20 (для классического quicksort-а)

Не в лоб. Я говорю о существовании алгоритмов. Я не слышал ещё ни об одном, превышающим *logN.
Re[52]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 11:14
Оценка:
U>GridSynchronizer корректно работает с любым хранимым состоянием.

теоретически — да, практически — нет.

например, нельзя писать такой код:
sync.data = ()=>File.ReadAllText("10MBfile.txt");

и появление вот таких ограничений и есть вирусность

U>Что ты понимаешь под "дальнейшим наращиванием мощности gridsync"? Приведи примеры.


1. вывод в ячейке что-то отличного от просто текста (раскраска, форматирование, вывод rich-текста и т.д.)
2. поддержка rowspan, colspan-ов
3. вывод нескольких разнородных источников на одну сетку грида
Re[53]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 30.11.10 12:13
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>1. вывод в ячейке что-то отличного от просто текста (раскраска, форматирование, вывод rich-текста и т.д.)


Я уже смутно помню, что там было в DataGridViewSynchronizer, но в VirtualGridSynchronizer, который сам себе и синхронайзер, и отрисовщик любая из этих задач решается за пять копеек. Достаточно написать новый CellFiller и возможно добавить несколько новых ColumnExtensionAttribute.

DG>2. поддержка rowspan, colspan-ов


Объединять ячейки VirtualGridSynchronizer умеет. Механизм правда не на rowspan и colspan основан, а на композитных и фальшивых ячейках.

DG>3. вывод нескольких разнородных источников на одну сетку грида


Имеешь в виду разнородные строки? Тоже реализовано, работает без проблем, единственное читается похуже, из-за того, что группировка кода производится по колонкам, а не по строкам.

DG>например, нельзя писать такой код:

DG>
DG>sync.data = ()=>File.ReadAllText("10MBfile.txt");
DG>

DG>и появление вот таких ограничений и есть вирусность

Если использовать хранение состояния на диске вместо хранения состояния в памяти, то проблемы будут у любого решения. Подсунь тому же ComboBox в DataSource объект, который при обращении к полям будет обращаться к диску. Что у ComboBox'а проблем с производительностью не будет?
Re[60]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 30.11.10 12:50
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>там еще есть концепция: что язык сам решает проблему вывода одних условий из других.


Это не еще одна концепция, а все та же, мной упомянутая.

DG>и при этом в прологе не рассматривается вариант — когда человек (или другая автоматика) может вмешиваться в этот процесс.


Это, разумеется, не соотвествует действительности. Предполагается, что человек:
а) Определяет последовательность выражений, потому как полностью корректная в смысле "чистой концепции" программа может при работе зацикливаться. В "чистой концепции" эта последовательность не имеет значения, а в Прологе имеет и еще как. Ну и определяется человеком.
б) Расставляет каты, управляя, таким образом, бэктрекингом.
т.е. самым прямым и непосредственным образом вмешивается в процесс.
И это не какие-то там индустриальные расширения а "академический" Пролог. Поэтому я и говорю, что языков, которые "не рассматривают" и "не решают" просто не существует. Каждый раз, когда разрабатывают язык, хоть для исследований, хоть для индустриального применения — приходится рассматривать и решать. Т.е. "академических" языков, общего назначения, по крайней мере, соотвествующих вашему определению не существует.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[54]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 12:52
Оценка:
U>Если использовать хранение состояния на диске вместо хранения состояния в памяти, то проблемы будут у любого решения. Подсунь тому же ComboBox в DataSource объект, который при обращении к полям будет обращаться к диску. Что у ComboBox'а проблем с производительностью не будет?

не будет, потому что он один раз это только сделает
а синхронайзер это делает каждый тик
Re[65]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 13:15
Оценка:
L>Во-вторых. Я тебе описал как из первого получить вот такое (опускаю массивы, чтобы не расписывать кучу деталей):

а теперь оцени потери производительности по сравнению с исходной версией на императивном языке (C/C++/Java/CSharp и т.д.)

проблема в том, что если алгоритм не свернуть в более емкую форму родную для данного языка, то потеря производительности может быть на пару порядков.
Re[61]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 13:19
Оценка:
K>т.е. самым прямым и непосредственным образом вмешивается в процесс.

в том-то и дело, что вмешивается опосредованно
пролог у себя внутри оперирует одним набором операций, а человек снаружи другим
и первое — не эквивалентно второму.
Re[66]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 30.11.10 13:28
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>а теперь оцени потери производительности по сравнению с исходной версией на императивном языке (C/C++/Java/CSharp и т.д.)


Ну сам и оцени. Если get и add O(1), то никакой потери не будет.
Так и поступают — выбирают нужную структуру или переписывают алгоритм, использующий лёгкие операции.

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


Может быть, а может не быть... Мы же не астрологией занимаемся, верно? Твои предположения не имеют ничего общего с тем, что происходит в реальном мире. Идея о том, что производительность зависит от длины кода — совершенно неверная. Вспомни про разворачивание циклов хотя бы.

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

P.S. Лучше всего Окасаки. Пишет понятно и по делу.
Re[63]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 14:27
Оценка:
K>И чем в данном случае Пролог отличается от любого другого языка? Смысл любого языка в том, чтобы внутри было одно — а снаружи что-то другое. Если снаружи в точности то же, что и внутри, то языка просто нет.

т.е. машина тьюринга, форт и т.д. — это не языки что ли?

любой язык можно представить: как уровень описания, и уровень исполнения.
в интерпретаторах — эти уровни совпадают: описание идет ровно теми же понятиями, которые и исполняются.
в компиляторах/трансляторах — эти уровни не совпадают (и появляется еще уровень трансляции), при этом доступ к исполнителю (и к транслятору) может даваться посредством языка, может посредством api, может вообще не даваться.
если взять связку C#/.net, то ее можно рассматреть как связку: C# — уровень описания, .net — уровень исполнения. доступ к уровню исполнения есть через api, доступа к транслятору C#->.net почти нет.
если брать связку C/Asm, то С — уровень описания, asm — уровень исполнения, при этом в реализации языка C часто вводят доступ к исполнителю через: кодовое слово — asm, intrsinc-и и т.д.
частично есть управление трансляцией: слова register, inline, stdcall и т.д.

если брать, например, pascal — то у него низкоуровневый исполнитель не зафиксирован, доступ к нему, и к транслятору нет

стандартный sql: описание — sql, исполнитель — реляционный движок. доступа ни к движку, ни к трансляции нет
oracle sql: описание pl/sql, исполнитель — oracle движок. добавлены hint-ы управляющие трансляцией, добавлен доступ к реляционному движку (введен курсор) и т.д.

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

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

и первые можно называть чистыми академическими (есть четко выраженная инкапсуляция), а вторые — это "грязные" смешанные языки (инкапсуляцию нарушают всякие грязные хаки)

зы
уровень описания и уровень исполнителя в языке — их обычно не по одному, а целая иерархия.
например, для .net-а уровни исполнения будут: .net-исполнитель -> x86-исполнитель -> risc-исполнитель
Re[64]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 30.11.10 14:56
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>т.е. машина тьюринга, форт и т.д. — это не языки что ли?


Языки.

DG>любой язык можно представить: как уровень описания, и уровень исполнения.

DG>в интерпретаторах — эти уровни совпадают: описание идет ровно теми же понятиями, которые и исполняются.

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

DG>в компиляторах/трансляторах — эти уровни не совпадают (и появляется еще уровень трансляции), при этом доступ к исполнителю (и к транслятору) может даваться посредством языка, может посредством api, может вообще не даваться.


Это упрощенная схема.

DG>стандартный sql: описание — sql, исполнитель — реляционный движок. доступа ни к движку, ни к трансляции нет

DG>oracle sql: описание pl/sql, исполнитель — oracle движок. добавлены hint-ы управляющие трансляцией, добавлен доступ к реляционному движку (введен курсор) и т.д.

Ну и у Пролога — описание — дизъюнкты Хорна, исполнитель — прологовский "движок", при этом, переставляя выражения и расставляя каты, мы управляем именно движком, т.е. доступ к "уровню исполнения" у нас есть.

DG>причем есть сильная корреляция с использованием языков:

DG>языка без доступа — используются в около академических кругах,

Примеры можно?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[65]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 15:08
Оценка:
DG>в интерпретаторах — эти уровни совпадают: описание идет ровно теми же понятиями, которые и исполняются.

K>вы только что писали, что Пролог "снаружи" оперирует одними понятиями, а "внутри" другими. Теперь утверждаете обратное.


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

кстати, про тот же .net я забыл упомянуть, что:
во-первых есть еще тонкий уровень C#-исполнителя (на этом уровне есть именованные локальные переменные, который на уровне .net-исполнителя уже нет)
во-вторых, C#/.net посредством C++/Cli предоставляет доступ не только к .net-исполнителю, но и к исполнителю на уровень(C-исполнитель) и на два(asm-исполнитель) ниже.


K>Ну и у Пролога — описание — дизъюнкты Хорна, исполнитель — прологовский "движок", при этом, переставляя выражения и расставляя каты, мы управляем именно движком, т.е. доступ к "уровню исполнения" у нас есть.


опиши своими словами, что делает прологовский движок — когда выполняет еще одну команду (для начала в самой краткой форме)

DG>>причем есть сильная корреляция с использованием языков:

DG>>языка без доступа — используются в около академических кругах,

K>Примеры можно?


примеры чего?
Re[65]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 30.11.10 15:32
Оценка:
K>Ну и у Пролога — описание — дизъюнкты Хорна, исполнитель — прологовский "движок", при этом, переставляя выражения и расставляя каты, мы управляем именно движком, т.е. доступ к "уровню исполнения" у нас есть.

тебе понятно в чем отличие между прямым доступом и опосредованным?

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

например, в C++-исполнителе есть такое понятие как виртуальная таблица, и законный доступ к ней только опосредованный: на виртуальную таблицу можно влиять частично только через генерацию C++-кода.
но прямой доступ к ней, например, позволяет в том числе менять ее и при исполнении (на чем бывает делаются всякие трюки)
Re[2]: Что-то вроде заключения
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.11.10 23:57
Оценка:
Здравствуйте, borisma/n3, Вы писали:

B>3) Реализуем контракт внутри модуля на любом удобном для нас языке используюя любую удобную для нас парадигму.


Советую не гробить время зря и взять Скалу в качесвте основного инструмента.

А далее все очень просто.
1. Дизайн делашеь в ОО-стиле с учетом того, что реализация будет приемущественно функциональной.
2. Все что можешь (структуры данных) стараешься сделать неизменяемым (Скала в этом поможет).
3. Используешь принципы инкапсуляции на основе абстрактных типов данных даже там где казалось бы ООП и не особо нужен.
4. Старавшийся проектировать так чтобы связанность отдельных частей была минимальной. Тут как раз хорошо подходят связь на уровне интерфейсов/трэйтсов.

Кложур не лучший выбор просто потому, что это язык с совсем другой идеологией (динамика, лисп).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 00:04
Оценка:
Здравствуйте, borisman3, Вы писали:

B>А как же все заверения адептов что FP мол надо широко применять как отдельную (от ООП) парадигму ?


Что ты хочешь с верующих?

Потом тут надо понимать, что ложкиООП нет. Есть принципы:
1. Инкапсуляция.
2. Полиморфизм.
3. Повторное использование.

Оных можно добиться как используя ООП, так и без него.

В ОО-проектировании очень важным аспектом является именно что разделение на интерфейсы и использование абстрактных типов данных для инкапсуляции.

Есть только действующий ФП-язык — Хакель, который предлагает для оных вещей приемлемые "функциональные" аналоги — классы типов. Остальные языки предлагают использовать дедовские методы вроде модулей и хэндлов, а многие так и вообще полные или частичные аналоги из ОО-мира. Скажем клоны Окамала предлагают улучшенные модули и классы, что есть классы ООП вид в профель. А Эрланг предлагает "легкие" процессы, что опять же идеологически дико смахивает на классы в стиле Смолтока.

Так что не забивай себе голову мнением верующих. Твой мозг уже поражен ООП-ом и ты вряд ли станешь верить в другую религию. В лучшем случае ты поймешь, что все религии ложны и нужно черпать из них лучшие идеи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 00:09
Оценка:
Здравствуйте, borisman3, Вы писали:

B>Для ООП существует отработанная методология разработки архитектуры — OOD. Теоретически она настолько общая, что, конечно, не предполагает на чем конкретно и в каком конкретно стиле будет написан тот или иной модуль. Но практически она заточена на ООП, классы, поведение, состояния. Я надеялся что есть некая альтернативная методология более подходящая для FP, но увы.


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

B>Микшировать ООП и FP это тоже конечно жизнеенный подход, но хотелось как раз pure fp.


Хочешь пьюр ФП — переходи на хаскель. ФП + ООП отлично реализовано в Скале и Немерле. По понятным причинам тебе больше подойдет первый. Клозюр же, на мой вгляд, не очень хороший выбор. Тогда уж лучше взять Комон Лисп и забить ан яыву. ООП в ЦЛ есть и она довольно крут.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 00:13
Оценка:
Здравствуйте, borisman3, Вы писали:

IT>>В общем, забей Используй ФП там где оно даёт эффект тебе лично, а не там где про него рассказывают умные дядьки.


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


ООП и родился под влиянием двух факторов:
1. Необходимость проектирования более больших и более сложных систем нежели те что легко реализуются путем структурной декомпозиции (применявшейся в процедурном программировании).
2. Необходимость сборки приложений из готовых компонентов. Это уже КООП, а не ООП, но оная парадигма базируется на ООП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 00:15
Оценка:
Здравствуйте, borisman3, Вы писали:

FR>>FP чтобы быть отдельной парадигмой ни в каком ООП не нуждается, достаточно модульности.


B>Постойте, постойте. Мне кажется, я знаю. Сначала Вы говорите модульность. Затем Вы скажете что у модулей МОЖЕТ быть состояние. Затем Вы скажете "абстрактные типы данных". Поправьте меня, где я ошибся ?


Да, да. И АТД для них ни ООП, а так...

У "них" и модули — первоклассные объекты которые могут хранить состояние.

Короче чтобы не позриться отсутствие состояния и объектов они назвали это по другому.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[55]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 04:49
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>не будет, потому что он один раз это только сделает

DG>а синхронайзер это делает каждый тик

Согласен. DataSource оказывается совсем убогий, только на подмену ссылки реагирует.

ps
Так в чем все-таки заключаются проблема вывода с помощью GridSynchronizer'а форматированного текста? Я так и не понял.
Re[7]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 07:36
Оценка:
Здравствуйте, VladD2, Вы писали:

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


Идеологи как раз так и говорят:

Haskell is the world's finest imperative programming language


VD>А ведь если бы к в нем убрать догмы и добавить удобные для людей конструкции описания тех самых объектов мог бы получиться хороший гибрид.


Хороший гибрид — мёртвый гибрид.

OOHaskell, O'Haskell, куча разных имплементаций OO в Haskell — где они все? Вывод напрашивается: OO в Haskell не нужен
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 10:10
Оценка:
K>В общем случае прямой доступ не может поддерживать более полный комплект операций. Будут некоторые операции, которые недоступны при опосредованном доступе, а некоторых операций, доступных из опосредованного не будет в прямом. Иначе языки прогрммирования не имели бы смысла.

вот это бред какой-то...

можно пример когда прямой доступ поддерживает меньше операций, чем опосредованный?

зы
это возможно только для случая — когда управляющий менее мощный, чем посредник.
я мы вроде рассматриваем ситуацию: человек -> язык описания -> исполнитель
и что это за человек такой, который менее мощный чем посредник(язык описания)?
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 10:25
Оценка:
K>Упрощенно это выглядит так: движок обходит дерево; листья дерева — решения, узлы — условия, которые движок проверяет. Программист может указать в какие ветви заходить в первую очередь, в какие во вторую и т.д. Также, если, например, условие в узле противоположные (жив и мертв, например), то программист может поставить метку, которая будет движком интерпретирована так: если выполняется условие "жив", то поддерево с корнем в "мертв" движок уже обходить не будет. Каких тут еще способов контроля движка не хватает? Ни и для того, что не укладывается в обход таких вот деревьев есть "предикаты" совершающие императивные действия.

во-первых: что является результатом обхода?
во-вторых: обход узлов гарантированно делается наиэффективнейшим образом, который ни для какого случая нельзя улучшить?
K> Программист может указать в какие ветви заходить в первую очередь, в какие во вторую и т.д.
если в разных случаях — это по разному, то как это указывается?
в-третьих: в математике есть такое утверждение, что для многих задач проверка правильности решения делается намного эффективнее, чем поиск самого решения.
это позволяет использовать стратегию, что если при предыдущем запуске мы уже обход сделали и зафиксировали для ряда узлов правильный ответ, то при следующем запуске лучше начинать с проверки правильности предыдущего решения, и только при его неверности делать полный обход.
как эту стратегию реализовать единожды на прологе?

зы
кстати пролог использует четкую логику, и не рассматривает вариант с нечеткой. это на тему ограничений концепций.
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 10:36
Оценка:
K>Примеры языков без такого доступа. Потому, что это фантастика. Ну вот представьте, что вы реализуете экспериментальный язык. Компилируемый. Вам для него нужна стандартная библиотека. В которой будет ввод/вывод. Для этого вам нужно как то взаимодействовать с ОС.

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

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

в .net-е много чего есть, но нет доступа к уровню JIT-трансляции.
Re[5]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 10:38
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Обсуждали уже. Классы типов — всего лишь сахар для естественного в мире ФП приёма. Так что это не аналог. Это просто сахар для своего чисто ФП-шного приёма абстракции. Который с успехом можно применять в любом ФЯ.


Я не знаю кто и где это обсуждал, но точно знаю, что классы типов есть только в одном языке. Так что обсуждать тут нечего.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 10:40
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Хороший гибрид — мёртвый гибрид.


Ну, ну. Ваша вера действительно крепка. А вось она и сдвинет горы.

L>OOHaskell, O'Haskell, куча разных имплементаций OO в Haskell — где они все? Вывод напрашивается: OO в Haskell не нужен


Ну, или Haskell не нужен. Всегда ведь есть альтернативные решения.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 10:45
Оценка:
K>Сама ваша концепция иерархии исполнителей, по моему мнению, только вносит путаницу. Вы смешиваете и свойства языка, и апи рантайма и апи компилятора и еще бог знает что.
K>API рантайма и компилятора — это вообще свойства реализации, такое можно сделать для любого языка.

цель языков вообще какая? повысить эффективность разработки, исполнения и т.д.

разработчик языка скрывая возможность доступа к исполнителю или к транслятору — берет на себя обязательство, что при этом и исполнитель, и транслятор — все делают самым эффективным образом.

т.е. инкапсуляция может делаться только в обмен на гарантии: на гарантии надежности, безбажности, эффективности и т.д.

но во многих случаях — эти гарантии не соблюдаются, и не обеспечиваются.
и тогда для достижения максимальной эффективности — необходимо понять где кроятся причины неэффективности, как это можно исправить, и есть ли для этого возможности (доступ)\
для решения этой задачи — и необходимо понимать: как язык устроен, какие в нем уровни, какие есть исполнители, какую задачу они решают на отлично, какие — не очень.
Re[47]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 10:57
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>реальные права на пересоздание есть только у движка.

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

Вот код изменяющий цену конкретного товара:

         | SetProductPrice(name, price) ->
             let productMap' = Map.add name { Key = name; Price = price } productMap


Объясни какой компилятор мне запретит вместо этого написать так:

         | SetProductPrice(name, price) ->
             let productMap' = Map.Empty


и испортить все товары?

При использовании мутабельных объектов эта функция выглядела бы так:

SetProductPrice(Product product, int price)
{
  product.Price = price;
}


и все продукты не могла бы испортить физически.
Re[47]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 10:59
Оценка:
Здравствуйте, samius, Вы писали:

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

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

http://rsdn.ru/forum/philosophy/4060401.1.aspx
Автор: Undying
Дата: 01.12.10
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 11:08
Оценка:
K>В общем случае прямой доступ не может поддерживать более полный комплект операций. Будут некоторые операции, которые недоступны при опосредованном доступе, а некоторых операций, доступных из опосредованного не будет в прямом.
K> Иначе языки прогрммирования не имели бы смысла.

вот тут мне кажется кроется корень твоего не понимания.

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

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

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

спросишь — зачем такие сложности, и зачем так делить?

ответ все тотже — достижение максимальной эффективности.
например, исполнитель вывода типов — очень часто ведет себя неэффективно, и при этом нет хорошего способа им поуправлять.
например, в сложной системе типов — бывает несколько путей преобразований из типа A в тип B.
при этом обычно нет хороших способов зафиксировать какой путь преобразования лучше выбирать — и это уже одна из проблем которая сажает эффективность разработки.

зы
что самое интересное.. исполнитель вывода типов очень похож на исполнителя из пролога. и в идеале — это должен был быть один мощный исполнитель, который можно подключать к произвольному языку — но пока это не так. и так будет продолжаться пока и разработчики языков, и пользователи языков — не научатся четко фиксировать с чем они имеют дело — с описанием или с исполнителем.
Re[41]: кэширование цены корзины в FP
От: Undying Россия  
Дата: 01.12.10 11:10
Оценка:
Здравствуйте, samius, Вы писали:

S>Начал на C# и припух. Тяжеловат он для чистого FP. Потому написал на F#. Если что непонятно — предлагаю скомпилировать и воспользоваться рефлектором с таргетингом в C#.


Как будет выглядеть код при увеличении числа уровней иерархии?

         | SetProductPrice(name, price) ->
             let productMap' = Map.add name { Key = name; Price = price } productMap


Например, список товаров является частью иммутабельного объекта магазин.

Я правильно понимаю, что в этом случае код станет примерно таким?

         | SetProductPrice(name, price) ->
             let productMap' = Map.add name { Key = name; Price = price } shop.productMap
             let shop' = { shop with ProductMap = productMap' }


И чем больше будет уровней иерархии тем больше строчек кода придется писать для того, чтобы изменить значение нижнего уровня?
Re[48]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 11:16
Оценка:
Здравствуйте, Undying, Вы писали:

U>Объясни какой компилятор мне запретит вместо этого написать так:


U>
U>         | SetProductPrice(name, price) ->
U>             let productMap' = Map.Empty
U>


U>и испортить все товары?


U>При использовании мутабельных объектов эта функция выглядела бы так:


U>
U>SetProductPrice(Product product, int price)
U>{
U>  product.Price = price;
U>}
U>


U>и все продукты не могла бы испортить физически.


Ты тут немного перемешал уровни ответственности. Код, обновляющий карту продуктов — это код верхнего уровня. Запрещать ему что-то делать самому себе нет резона.
Это как если бы код, достающий из коллекции определенный продукт для передачи SetProductPrice испортил бы коллекцию продуктов не обращаясь к SetProductPrice.

т.е. это проблема уровня "кто мне запретит написать в MAIN Kill(myself);".

А аналог SetProductPrice выглядел бы так:
Product UpdateProduct(Product product, int newPrice)
{
     return new Product(product.Name, price);
}

Соответственно этот код доступа к миру не имеет и изменить его не может никак.
Re[48]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 11:20
Оценка:
U>
U>         | SetProductPrice(name, price) ->
U>             let productMap' = Map.Empty
U>


U>и испортить все товары?


в данном коде ты еще ничего не испортил.
ты создал свою локальную переменную productmap', которая никакого отношения к исходной корзине не имеет

ps
SetProductPrice(Product product, int price)
{
  product.Price = price;
}


и на хера такой костыль? т.е. зачем ты хочешь это записать именно в виде отдельного метода?

ты вроде хотел записать:
хочу разрешить васе пупкину доступ на изменение поля price в продуктовой корзине
или может вообще хотел записать
хочу разрешить всем пользователям с ролью пользователь_уровня_1 доступ на изменение поля price в продуктовой корзине

так если ты это хотел записать, так это и запиши:
world access role user_level_1 readonly
  productMap access role user_level_1 readonly
    products access role user_level_1 readonly
       price access role user_level_1 readwrite


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

дык, значит плохой у тебя компилятор. выкини его, возьми другой — который лучше.
Re[9]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 11:31
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>OOHaskell, O'Haskell, куча разных имплементаций OO в Haskell — где они все? Вывод напрашивается: OO в Haskell не нужен

VD>Ну, или Haskell не нужен. Всегда ведь есть альтернативные решения.

Смотри — Haskell есть и используется. OO в Haskell есть и не используется. Разницу чувствуешь?
Re[49]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 11:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>в данном коде ты еще ничего не испортил.

DG>ты создал свою локальную переменную productmap', которая никакого отношения к исходной корзине не имеет

Значит, я плохо понял как на F# происходит перезапись ссылки на объект, и надо эту строчку записать иначе. Смысл моего утверждения от этого не поменяется.

DG>так если ты это хотел записать, так это и запиши:

DG>
DG>world access role user_level_1 readonly
DG>  productMap access role user_level_1 readonly
DG>    products access role user_level_1 readonly
DG>       price access role user_level_1 readwrite
DG>


DG>так ты хотел чтобы это проверялось на уровне компиляции? и твой компилятор такую запись не понимает и не умеет такое делать?


И что с этой хренью делать на практике?

Вот я читаю код, допустим меня интересует количество элементов в ProductList. Далее я вижу в коде строчку:

ModifyProduct(product);

Код этой функции я могу не смотреть, т.к. компилятор гарантирует, что эта функция ни при каких обстоятельствах не может изменить количество элементов в ProductList. Если же обновление продукта делать так как это делает samius, то смотреть надо каждую функцию, т.к. любая функция может поменять все что угодно.

И что тут дадут твои user_level? Позволят наплодить в коде лишних сущностей, чтобы потом в коде точно никто не разобрался?
Re[49]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 11:38
Оценка:
Здравствуйте, samius, Вы писали:

S>Ты тут немного перемешал уровни ответственности. Код, обновляющий карту продуктов — это код верхнего уровня. Запрещать ему что-то делать самому себе нет резона.


Т.е. передвижение любой песчинки во вселенной становится кодом верхнего уровня. Соответственно ошибка при передвижении любой песчинки может уничтожить вселенную.

S>А аналог SetProductPrice выглядел бы так:

S>
S>Product UpdateProduct(Product product, int newPrice)
S>{
S>     return new Product(product.Name, price);
S>}
S>

S>Соответственно этот код доступа к миру не имеет и изменить его не может никак.

Дальше ты этот код где будешь вызывать? Вот у тебя пользователь нажал на кнопку, пользователь работает с конкретной песчинкой, но тебе все равно придется заменять вселенную новым объектом, т.е. благодаря иммутабельности действие пользователя работающего с песчинкой вызывает код, который может уничтожить вселенную.
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 11:50
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Ты тут немного перемешал уровни ответственности. Код, обновляющий карту продуктов — это код верхнего уровня. Запрещать ему что-то делать самому себе нет резона.


U>Т.е. передвижение любой песчинки во вселенной становится кодом верхнего уровня. Соответственно ошибка при передвижении любой песчинки может уничтожить вселенную.


Это не обязательно так. Если вселенная доверяет коду изменить песчинку, она возьмет новую песчинку у кода. Если вселенная доверяет изменить набор цен — она отдаст набор цен тому коду и заберет у него новый набор цен.
Тут очень просто контроллировать то, что ты доверяешь коду с помощью сигнатуры метода.

S>>А аналог SetProductPrice выглядел бы так:

S>>
S>>Product UpdateProduct(Product product, int newPrice)
S>>{
S>>     return new Product(product.Name, price);
S>>}
S>>


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


Все наоборот. Код, который может изменить вселенную вызывает код, который работает с песчинкой, а потом решает, изменять ли песчинку во вселенной, или нет. Даже если коду, изменяющему песчинку позволили вернуть вернул новую вселенную, это еще не значит что текущая вселенная сломана. После проверки инвариантов новой вселенной, можно прийти к решению что её следует скормить GC.
Re[42]: кэширование цены корзины в FP
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 11:51
Оценка:
U>И чем больше будет уровней иерархии тем больше строчек кода придется писать для того, чтобы изменить значение нижнего уровня?

имхо, опять все мешается в кучу. уровень описания, исполнения, синтаксис и ограничения текущих трансляторов, привычки программистов и т.д.

в данном случае тут можно выделить три разные задачи:
1. описание того, что внешняя сторона хотела изменить
2. описание того, чему равно корректное состояние системы после изменения
3. описание того, что необходимо сделать, что перевести систему из состояния до данного конкретного изменения к корректному состоянию после изменения.

первую задачу удобнее (максимально емко) записывать тем же способом, которым она сейчас записывается в объектных императивных языках, в виде цепочки идентификаторов слева и нового значения справа:
world.productMap.product(подгузники).price = 145р;


вторую задачу удобнее (максимально емко) записывать через построение мира с нуля, как это принято в ФЯ
newworld:world merge(this oldworld:world, world-delta:world-delta)
{
   newworld = new world{product-map = oldworld.product-map.merge(world-delta.product-map);
}
..
newproductmap:product-map merge(this oldproductmap:product-map, productmap-delta: productmap-delta)
{
   newproductmap = new productmap
   {
    products = products.merge(productmap-delta.products),
    totalprice = products.select(product=>product.price).sum()
   };
}

newproduct:product merge(this oldproduct:product, product-delta: product-delta)
{
   newproduct = new product{name = oldproduct.name, price = product-delta.price};
}


третью задачу удобно (максимально емко) записывать так же как первую (формирование такого сообщения делается автоматически)
world.productMap.product(подгузники).price = 145р;  
world.productMap.totalprice = (75$, 307р);

такое сообщение может посылаться системой терминалу вывода (например, от server-а в браузер, если расчет корзины делается на сервере)
Re[50]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 11:59
Оценка:
U>Код этой функции я могу не смотреть, т.к. компилятор гарантирует, что эта функция ни при каких обстоятельствах не может изменить количество элементов в ProductList. Если же обновление продукта делать так как это делает samius, то смотреть надо каждую функцию, т.к. любая функция может поменять все что угодно.

U>И что тут дадут твои user_level? Позволят наплодить в коде лишних сущностей, чтобы потом в коде точно никто не разобрался?



Ты до сих пор пользуешься notepad-ом который не умеет сформировать обзор кода под тот вопрос, который ты задал?
значит в топку — notepad.
возьми IDE — которая тебе сможет представить такое представление кода, из которого тебе будет наглядно понятно, к чему у тебя доступ есть, а к чему нет.

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

U>И что тут дадут твои user_level?


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

сейчас ты такое зафиксировать не можешь, хотя именно это текущие задачи и требуют.
Re[51]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 01.12.10 12:43
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>как минимум гибкость и возможность прямо в коде зафиксировать, что например есть уровень доступа администратора, есть уровень доступа продвинутого пользователя, есть уровень простого пользователя, есть уровень гостя.


Сейчас я руководствуюсь простым принципом, если функция модифицирует песчинку, то только песчинку она на вход и получает. И этот простой принцип позволяет добиться высокой надежности, т.к. мест, которые могут сломать не маленький кусочек мира, а весь мир целиком становится очень немного. Вместо этого ты предлагаешь указывать для каждой сущности права на доступ к ней, а затем в каждой функции указывать какие права она имеет. Ты всерьез считаешь, что такая гора лишних сущностей это способ сделать мир проще?
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 01.12.10 12:53
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>можно пример когда прямой доступ поддерживает меньше операций, чем опосредованный?


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

DG>и что это за человек такой, который менее мощный чем посредник(язык описания)?


Человек в данном случае владеет мощностью языка описания, как оператор экскаватора владеет мощностью экскаватора. Ну или как оператор лопаты владеет мощностью лопаты.

DG>во-первых: что является результатом обхода?


Ленивый список правильных ответов. Решатель находит первй правильный ответ, если требуем следующий — ищет дальше. Ну или не находит.

DG>во-вторых: обход узлов гарантированно делается наиэффективнейшим образом, который ни для какого случая нельзя улучшить?


Не гарантировано. точно так же как и компилятор любого языка не компилирует код на этом языке в гарантированно наиэффективнейший машинный код.

K>>Программист может указать в какие ветви заходить в первую очередь, в какие во вторую и т.д.

DG>если в разных случаях — это по разному, то как это указывается?

Решатель обходит дерево в том порядке, в каком оно описано в коде. Слева направо, сверху вниз. Декларативный смысл програмы на Прологе от перестановки не меняется, а вот эффективность и завершимость программы — еще как.

DG>в-третьих: в математике есть такое утверждение, что для многих задач проверка правильности решения делается намного эффективнее, чем поиск самого решения.

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

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

K>>Примеры языков без такого доступа. Потому, что это фантастика. Ну вот представьте, что вы реализуете экспериментальный язык. Компилируемый. Вам для него нужна стандартная библиотека. В которой будет ввод/вывод. Для этого вам нужно как то взаимодействовать с ОС.


DG>доступ к внешнему окружению != доступ к исполнителю самого языка.


Но это не касается языка в общем случае. Можно ведь организовать доступ к исполнителю через api.

DG>в .net-е много чего есть, но нет доступа к уровню JIT-трансляции.


Но .net — это не язык. Берете бэкенд в LLVM и делаете что хотите.

DG>цель языков вообще какая? повысить эффективность разработки, исполнения и т.д.


Да.

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


Никто на себя таких обязательств и не берет. это невыполнимые обязательства.

DG>т.е. инкапсуляция может делаться только в обмен на гарантии: на гарантии надежности, безбажности, эффективности и т.д.


Не обязательно.

DG>но во многих случаях — эти гарантии не соблюдаются, и не обеспечиваются.


Вот именно.

DG>и тогда для достижения максимальной эффективности — необходимо понять где кроятся причины неэффективности, как это можно исправить, и есть ли для этого возможности (доступ)\

DG>для решения этой задачи — и необходимо понимать: как язык устроен, какие в нем уровни, какие есть исполнители, какую задачу они решают на отлично, какие — не очень.

Для этого и надо понимать разницу между языком и реализаций. Между рантаймом и компилятором а не сваливать все в одну кучу.

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


Может.

DG>их либо умеет делать — управляющий (человек), либо управляемый (исполнитель).


Уметь мало. Нужно еще и делать. Какой смысл уметь выкопать канал одной лопатой, если на практике этого не сделать?

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

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

"Емкость" и "точность" — противоречивые требования, если под точностью понимается детальность.

DG>и надо четко различать — речь идет о языке, или об исполнителях встроенных в язык.

DG>например, вывод типов в языке — это встроенный исполнитель, но не сам язык. валидация типов — это тоже исполнитель, но не сам язык.

DG>спросишь — зачем такие сложности, и зачем так делить?


DG>например, исполнитель вывода типов — очень часто ведет себя неэффективно, и при этом нет хорошего способа им поуправлять.

DG>например, в сложной системе типов — бывает несколько путей преобразований из типа A в тип B.
DG>при этом обычно нет хороших способов зафиксировать какой путь преобразования лучше выбирать — и это уже одна из проблем которая сажает эффективность разработки.

Не понял, какое значение тут имеет какой-то путь преобразования? И о какой эффективности идет речь? Времени компиляции?

Кстати сказать, в языках с выводом типов бывают средства управления выводом типов. От опциональных аннотаций типов и до Хаскелевских деректив вроде NoMonomorphismRestriction или IncoherentInstances.

DG>что самое интересное.. исполнитель вывода типов очень похож на исполнителя из пролога.


Да, сходство есть. Те же многопараметрические тайпклассы с фундепами в Хаскеле — это что-то напоминающее эдакий тайплевел-Пролог.

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


Типы в разных языках выводить каким-нибудь одним констрейнт-солвером или там абстрактным интерпретатором, наверное, можно. Но это все может быть достаточно медленным по сравнению с ad-hoc реализацией для конкретного языка. Избыточная гибкость.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[52]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 12:57
Оценка:
U>Сейчас я руководствуюсь простым принципом, если функция модифицирует песчинку, то только песчинку она на вход и получает. И этот простой принцип позволяет добиться высокой надежности,

и этот простой принцип помогает решать только простые задачи (задачи с очень малым кол-вом вариантов)

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

и вот уже твоя маленькая песчинка для ответа на вопрос "сколько стоит?" должна получать на вход весь мир.

и соответственно, ты себя обманываешь — когда считаешь, что ты понимаешь сложность задач которые [b]хочется и требуется{/b] решать.
и это не идет ни в какое сравнение с той сложностью задач: которые ты уже решаешь и которую помогают решать твои текущие подходы и текущий язык.
Re[10]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 13:03
Оценка:
Здравствуйте, lomeo, Вы писали:

L>Смотри — Haskell есть и используется. OO в Haskell есть и не используется. Разницу чувствуешь?


Я чувствую разницу когда вижу как используется ООЯ и как хаскель. Применение Хаскеля на фоне ООЯ не видно в микроскоп. И вижу что нет никаких проблем в совместном использовании ООП и ФП. Они прекрасно друг-друга дополняют. Абстракции верхноего уровня — ООП, реализация — ФП + где надо ИП. Результат получается отличнийший. И не нужны промывания мозгов, вера, объяснения, заумности... Абстракции в ООП проработаны отлично. Методология проектирования отточена и хорошо описана во многих источниках. Тоже самое об ФП сказать нельзя. Да и по твоим же словам ФП заканчивается хаскелем. Что не может не настораживать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[69]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 13:36
Оценка:
DG>>можно пример когда прямой доступ поддерживает меньше операций, чем опосредованный?

K>Например, когда непосредственный доступ нарушает гарантии, которые сразу делают неработающими челый класс операций на "опосредованном" уровне.


во-первых:это значит что ты не умеешь измерять мощность операций:
1) вариантность вида — есть возможность проводить и корректные операции и некорректные операции — мощнее, чем вариантность вида — есть возможность проводить только корректные операции.
2) вариантность вида — есть возможность проводить и корректные операции, и некорректные операции + есть возможность для определенного контекста потребовать гарантию возможности только корректных операции — мощнее, чем вариантность вида — есть возможность проводить и корректные операции и некорректные операции.

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

для понимания последнего могу привести пример с истребителями последнего поколения:
1. с точки зрения планера — неустойчивое состояние — это плохо и некорректно — т.к. приводит к срыву в штопор.
2. но с точки зрения системы управления последнего поколения — неустойчивый планер — это хорошо и корректно, т.к. позволяет делать быстрые развороты, а от срыва в штопор система защищается постоянным подруливанием.

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


DG>>и что это за человек такой, который менее мощный чем посредник(язык описания)?


K>Человек в данном случае владеет мощностью языка описания, как оператор экскаватора владеет мощностью экскаватора. Ну или как оператор лопаты владеет мощностью лопаты.


DG>>во-первых: что является результатом обхода?


K>Ленивый список правильных ответов. Решатель находит первй правильный ответ, если требуем следующий — ищет дальше. Ну или не находит.


DG>>во-вторых: обход узлов гарантированно делается наиэффективнейшим образом, который ни для какого случая нельзя улучшить?


K>Не гарантировано. точно так же как и компилятор любого языка не компилирует код на этом языке в гарантированно наиэффективнейший машинный код.


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

есть неэффективное место оно должно быть заменено. точка.

K>Никто на себя таких обязательств и не берет. это невыполнимые обязательства.


берут. и именно этим обосновывается то, что инкапсуляция ничего не нарушает, и что по парето мы получаем максимум по обоим параметрам: простота, эффективность.

DG>>т.е. инкапсуляция может делаться только в обмен на гарантии: на гарантии надежности, безбажности, эффективности и т.д.


K>Не обязательно.


тогда это вредная инкапсуляция.

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

у меня критерий есть, и он написан выше.

DG>>и тогда для достижения максимальной эффективности — необходимо понять где кроятся причины неэффективности, как это можно исправить, и есть ли для этого возможности (доступ)\

DG>>для решения этой задачи — и необходимо понимать: как язык устроен, какие в нем уровни, какие есть исполнители, какую задачу они решают на отлично, какие — не очень.

K>Для этого и надо понимать разницу между языком и реализаций. Между рантаймом и компилятором а не сваливать все в одну кучу.


это ты сваливаешь все в кучу. ты и язык уровня компиляции и runtime уровня компиляции называешь одним словом компилятор.

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


K>Может.


DG>>их либо умеет делать — управляющий (человек), либо управляемый (исполнитель).


K>Уметь мало. Нужно еще и делать. Какой смысл уметь выкопать канал одной лопатой, если на практике этого не сделать?


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

K>"Емкость" и "точность" — противоречивые требования, если под точностью понимается детальность.


во-первых, есть парето-фронт — который для начала стоит достигнуть
во-вторых, парето-фронт для множества задач может состоять и из одной точки

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


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

и в частности это есть следствие того, что ты не отделяешь исполнителей друг от друга, и от языка описания.
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.12.10 15:40
Оценка:
U>ps
U>Так в чем все-таки заключаются проблема вывода с помощью GridSynchronizer'а форматированного текста? Я так и не понял.

если брать virtualgridsync, то:
во-первых, он глючит
во-вторых, моргает
в-третьих, почему цвет начинает отражать наезд мышки только если строку расскоментировать?
  public partial class VirtualGridTestForm : Form
  {
    public VirtualGridTestForm()
    {
      InitializeComponent();

      var sync = new VirtualGridSynchronizer(this.panel1);
      sync.DataLink = () => new object[]
       {
         1, 2, 3, 
//         IsHover(panel1)
       };

      sync.ColumnsGetter = ()=> new IGridColumn[]
      {
        new SimpleColumn<object>("x", x=>x, new SoftTech.Gui.ColumnExtensions.CellBackColorExtension(x=> IsHover(this) ? Color.Red : Color.Green))
      };
    }

    public bool IsHover(Control control)
    {
      var position = Cursor.Position;
      var local = control.PointToClient(position);
      return 0 <= local.X && 0 <= local.Y && local.X < control.Width && local.Y < control.Height;
    }
  }

в-четвертых: как сделать чтобы внутри задания ячейки можно было использовать инфу — есть ли мышка над ячейкой, не переписывая при этом gridsync и все extension-ы?
Re[11]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 18:02
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Смотри — Haskell есть и используется. OO в Haskell есть и не используется. Разницу чувствуешь?

VD>Я чувствую разницу когда вижу как используется ООЯ и как хаскель. Применение Хаскеля на фоне ООЯ не видно в микроскоп. И вижу что нет никаких проблем в совместном использовании ООП и ФП. Они прекрасно друг-друга дополняют.

Ах, как ты умеешь вовремя подменять критерии оценки! Применения Хаскеля на фоне ООЯ не видно в микроскоп, а вот совместное использование ООП и ФП оцениваем уже по твоим личным "вижу дополняют". Изумительно! Можно я тоже воспользуюсь?

Я чувствую разницу когда вижу как используется связка ФП-ООП и хаскель. Применение гибридных языков на фоне ФЯ не видно в микроскоп. И вижу что нет никаких проблем в использовании Хаскеля. Он самодостаточен.
Re[12]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 18:48
Оценка:
Здравствуйте, lomeo, Вы писали:

L>>>Смотри — Haskell есть и используется. OO в Haskell есть и не используется. Разницу чувствуешь?

VD>>Я чувствую разницу когда вижу как используется ООЯ и как хаскель. Применение Хаскеля на фоне ООЯ не видно в микроскоп. И вижу что нет никаких проблем в совместном использовании ООП и ФП. Они прекрасно друг-друга дополняют.

L>Ах, как ты умеешь вовремя подменять критерии оценки!


Я ничего не подменял. Это ты начал измерять количество ОО в Хаскеле. На что тебе резонно заметили, что если уж мерить пиписьки, то по честному. Мы же не мир хаскеля обсуждаем, а вопрос совместного использования ОО и ФП. Ты утверждаешь, что это не правильно и плохо, и приводишь в доказательство "объем ОО в Хаскеле". Но это же смешно.

L>Применения Хаскеля на фоне ООЯ не видно в микроскоп, а вот совместное использование ООП и ФП оцениваем уже по твоим личным "вижу дополняют". Изумительно! Можно я тоже воспользуюсь?


Акстись. LINQ шагает по планете. Хаскелю и не снилась его популярность. Я уже не говрю про вполне успешную практику использования таких языков как Немерл, Скала и ФШарп.

L>Я чувствую разницу когда вижу как используется связка ФП-ООП и хаскель. Применение гибридных языков на фоне ФЯ не видно в микроскоп. И вижу что нет никаких проблем в использовании Хаскеля. Он самодостаточен.


Веруй в эту чушь сколько влезет. От этого ровным счетом ничего не изменит. Реалии мира таковы каковы они есть. ООП и ФП отлично уживаются в куче вполне себе живых языков (C#, VB.NET, F#, Scala, Nemerle, OCaml...).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 01.12.10 19:23
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я ничего не подменял. Это ты начал измерять количество ОО в Хаскеле.


Ну что за ерунда в самом деле? Ты уже свои фантазии мне приписываешь?
Вот эту глупость кто сказал?

А ведь если бы к в нем убрать догмы и добавить удобные для людей конструкции описания тех самых объектов мог бы получиться хороший гибрид.


VD>На что тебе резонно заметили, что если уж мерить пиписьки, то по честному. Мы же не мир хаскеля обсуждаем, а вопрос совместного использования ОО и ФП. Ты утверждаешь, что это не правильно и плохо, и приводишь в доказательство "объем ОО в Хаскеле". Но это же смешно.


Конечно смешно! Когда передёргиваешь так бывает. Потому что объём ОО в Haskell был приведён в подтверждение совсем другому тезису. А конкретно тому, что ОО в Haskell не нужен. Зачем делать отсюда далеко идущие выводы?

L>>Применения Хаскеля на фоне ООЯ не видно в микроскоп, а вот совместное использование ООП и ФП оцениваем уже по твоим личным "вижу дополняют". Изумительно! Можно я тоже воспользуюсь?

VD>Акстись. LINQ шагает по планете. Хаскелю и не снилась его популярность. Я уже не говрю про вполне успешную практику использования таких языков как Немерл, Скала и ФШарп.

Ты на что сейчас отвечал?

L>>Я чувствую разницу когда вижу как используется связка ФП-ООП и хаскель. Применение гибридных языков на фоне ФЯ не видно в микроскоп. И вижу что нет никаких проблем в использовании Хаскеля. Он самодостаточен.

VD>Веруй в эту чушь сколько влезет. От этого ровным счетом ничего не изменит. Реалии мира таковы каковы они есть. ООП и ФП отлично уживаются в куче вполне себе живых языков (C#, VB.NET, F#, Scala, Nemerle, OCaml...).

Угу! Потому что с объектами на Ocaml и F# работают столь же активно, как и на ОО-языках, я прав? А на C# и VB.NET в функциональном стиле разработка ведётся как минимум для большей части методов. Т.е. разработка на этих языках ведётся как ты описал — "абстракциях верхноего уровня — ООП, реализация — ФП + где надо ИП". Или всё таки эти слова применимы только к гибридным языкам?

Теперь конкретнее.
Применение гибридных языков на фоне ФЯ не видно в микроскоп. Гибридных языков всего-то два. На фоне огромного пласта ФЯ они действительны не видны. Только если Haskell взять, до него Scala чуть-чуть не дотягивает. А ФЯ разных чуть больше, чем один Haskell.
И вижу что нет никаких проблем в использовании Хаскеля. Ты будешь спорить с тем, что я не вижу никаких проблем с использованием Haskell?
Итак, что конкретно было чушью?
Re[57]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 02.12.10 09:48
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>если брать virtualgridsync, то:

DG>во-первых, он глючит

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

DG>во-вторых, моргает


Ему VirtualPanel надо передавать, а не обычную панель.

DG>в-третьих, почему цвет начинает отражать наезд мышки только если строку расскоментировать?


Потому что значения грида при наезде мышки на ячейку не меняются. Вызывай ForceSynchronize при наезде мыши на новую ячейку и все будет работать.

DG>в-четвертых: как сделать чтобы внутри задания ячейки можно было использовать инфу — есть ли мышка над ячейкой, не переписывая при этом gridsync и все extension-ы?


Если не меняя кода GridSynch, то отнаследоваться от него, подписаться на MouseMove и MouseLeave rowPanel и с помощью метода GetCellByClientCoord запоминать ячейку, на которой находится курсор мыши. Можно еще событие сделать, которое будет дергаться, если ячейка изменилась. Информация из грида в ячейку элементарно прокидывается через ColumnExtensionAttribute с делегатом. Если GetCellByClientCoord сделать публичным, то и наследования бы не понадобилось.

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

ps
Давай по этому вопрос в приват, все равно он больше никому не понятен.
Re[53]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 02.12.10 10:00
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>сама цена зависит от того кто товар поставил, когда, по какой цене, какое отношение местной валюты к валюте поставщика и т.д.

DG>валюта цены зависит места магазины, от места покупателя, от предпочтений и возможностей покупателя и т.д.

Во-первых, в этом случае изменение будет производится точно также, только у продукта поле будет называться не Price, а BasePrice.

DG>и вот уже твоя маленькая песчинка для ответа на вопрос "сколько стоит?" должна получать на вход весь мир.


Во-вторых, если нижним уровням при модификации и будут требоваться верхние уровни, то они будут требоваться только на чтение. Соответственно в мутабельном коде нажимая кнопочку "Найти все сеттеры" для верхнего уровня я получу пару-тройку мест в коде, т.к. верхний уровень меняется очень редко, то нажимая ту же самую кнопочку в иммутабельном коде я получу сотни и тысячи мест, т.к. любое изменение нижнего уровня порождает пересоздание верхнего уровня. И все эти сотни и тысячи мест придется просматривать, для того, чтобы найти те самые три места где галактика пересоздавалась по условию задачи, а не потому что в ней песчинка переместилась.

DG>и соответственно, ты себя обманываешь — когда считаешь, что ты понимаешь сложность задач которые [b]хочется и требуется{/b] решать.

DG>и это не идет ни в какое сравнение с той сложностью задач: которые ты уже решаешь и которую помогают решать твои текущие подходы и текущий язык.

Не знаю о каких задачах ты говоришь. Но знаю, что для написания сложных систем мутабельный подход, с представлением сущностей зависящих от других сущностей в виде кэшей, а не обычных переменных, подходит намного лучше иммутабельного подхода. Соответственно если для еще более сложных систем не подходит и этот подход, то иммутабельный не подходит тем более.
Re[58]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 02.12.10 11:43
Оценка:
U>Т.е. ничего сложного, это при том, что при проектировании я о такой задачи ни разу не задумывался.

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

а не рассмотреть он мог по следующим причинам:
1. вариантов слишком много и не было достаточно времени все их рассмотреть
2. код слишком большой (или слишком сложный) для обозрения и выделения всех вариантов поведения
3. забыл рассмотреть часть вариантов
4. не подумал что бывают и такие-то варианты
5. ошибся и рассмотрел варианты не верно
6. при рассматривании и фиксации в коде одно из последних вариантов косвенно внес изменения, которые изменили поведение в предыдущих рассмотренных вариантах.
7. опечатался (варианты выделены и рассмотрены верно, но при фиксации решения внесена опечатка)
8. поведение используемых частей не соответствует ожидаемому (задокументированному)

ты же эту проблему игнорируешь.

все твои замечания сводятся к:
1. достаточно написать ForceSynchronize и все будут хорошо.
2. достаточно поменять changetick и все будет хорошо.
и т.д.

но, например, замечание с ForceSynchronize сводится к следующей работе разработчика:
1. необходимо выделить все варианты работы кода, когда происходит какое-либо использование данных, которые используются при выводе gridsync-а
2. все эти варианты необходимо зафиксировать в каком-то виде (в голове, на листочке, в какой-то программе, в комментарии к коду, в коде)
3. найти время на выделение, фиксацию, разбор и внесение изменений
4. рассмотреть последовательно все варианты
5. для каждого варианта внести изменение в код: в нужное место вставить forcesynchronize
6. убедится что при внесении изменений не было опечаток
7. убедится что варианты были рассмотрены верно
8. все пункты проделать и для каждого используемого куска кода
9. после каждого изменения выполнить данные пункты заново

честная оценка трудоемкости данной работы сверху:
кол-во изменений сделанных программистом * кол-во вариантов поведения программы
кол-во вариантов поведения программы = 2^(размер всей используемой памяти (винт, heap, stack, регистры процессора и т.д.))

при данной оценке — кол-во изменений получается неважным, т.к. основной вклад дает кол-во вариантов поведения программы, и это очень огроменное число. текущие программы (например, базы данных могут оперировать и ТБ хранимых данных)
число 2^(10^12). кол-во атомов во вселенной оцениваешь лишь в 10^80 (это меньше чем 2^(10^3))

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

и gridsync по выводу данных — решает именно эту задачу, и при использовании gridsync-а достаточно рассмотреть варианты записанные в коде, и нет необходимости рассматривать все варианты изменения данных
но при вывода оформления (а не данных) через gridsync-а — данная задача не решена, и возвращает к задаче перебора всех вариантов работы кода
Re[54]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 02.12.10 11:49
Оценка:
U>Не знаю о каких задачах ты говоришь. Но знаю, что для написания сложных систем мутабельный подход, с представлением сущностей зависящих от других сущностей в виде кэшей, а не обычных переменных, подходит намного лучше иммутабельного подхода. Соответственно если для еще более сложных систем не подходит и этот подход, то иммутабельный не подходит тем более.

ты не понял фичу с иммутабельностью, и отвечаешь на что-то не то.
нет на самом деле в ФЯ никакой иммутабельности (с точки зрения исполнения)

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

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

зы
ты кстати вообще понимаешь, что один и тот же код можно рассматривать с нескольких точек зрения, и записывать по разному — и при этом не меняя сам код?

т.е. представление кода меняется, а сам код не меняется.
Re[55]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 02.12.10 12:11
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>ты не понял фичу с иммутабельностью, и отвечаешь на что-то не то.

DG>нет на самом деле в ФЯ никакой иммутабельности (с точки зрения исполнения)

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

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

DG>и вот теперь объясни своими словами — как ты понимаешь данное утверждение. что программа одновременно мутабельна, и иммутабельна.

Откуда я могу знать, что ты понимаешь под данным утверждением? Разъясни, тогда я и смогу ответить как я его понял.

DG>зы

DG>ты кстати вообще понимаешь, что один и тот же код можно рассматривать с нескольких точек зрения, и записывать по разному — и при этом не меняя сам код?

DG>т.е. представление кода меняется, а сам код не меняется.


Ничего не понял. Что такое "код" и что такое "представление кода" и чем они отличаются друг от друга?
Re[70]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 02.12.10 12:25
Оценка:
Здравствуйте, DarkGray, Вы писали:

K>>Например, когда непосредственный доступ нарушает гарантии, которые сразу делают неработающими челый класс операций на "опосредованном" уровне.

DG>во-первых:это значит что ты не умеешь измерять мощность операций:

Думаю, что скорее наоборот.

DG>1) вариантность вида — есть возможность проводить и корректные операции и некорректные операции — мощнее, чем вариантность вида — есть возможность проводить только корректные операции.


А что мощнее — возможность проводить корректные операции или отсутствие возможности проводить корректные операции?

DG>2) вариантность вида — есть возможность проводить и корректные операции, и некорректные операции + есть возможность для определенного контекста потребовать гарантию возможности только корректных операции — мощнее, чем вариантность вида — есть возможность проводить и корректные операции и некорректные операции.


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

DG>и это означает, что компилятор плохо, и для данного случая его необходимо заменить.


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

DG>есть неэффективное место оно должно быть заменено. точка.


Неэффективное по каким критериям?

K>>Никто на себя таких обязательств и не берет. это невыполнимые обязательства.

DG>берут. и именно этим обосновывается то, что инкапсуляция ничего не нарушает, и что по парето мы получаем максимум по обоим параметрам: простота, эффективность.

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

DG>>>т.е. инкапсуляция может делаться только в обмен на гарантии: на гарантии надежности, безбажности, эффективности и т.д.

K>>Не обязательно.
DG>тогда это вредная инкапсуляция.

Для кого вредная? Если разработчик что-то инкапсулирует — это развязывает ему руки, позволяя что-то менять за "стенами" инкапсуляции и это облегчает для него соблюдения каких-то инвариантов.

DG>у тебя есть критерий — когда инкапсуляция хорошо, а когда плохо?


Есть. И не один.

DG>или для тебя всякая инкапсуляция — есть хорошо?


Нет.

DG>может тогда на разработчика вообще смирительную рубашку одеть — вообще очень хорошо все инкапсулирует.


Зависит от обстоятельств. Если разработчик психопат — это может быть полезным, наверное.

DG>у меня критерий есть, и он написан выше.


Там нет критерия — там отрицательная эвристика. Вы не пишете, когда инкапсуляция это хорошо, но пишете, когда инкапсуляция это плохо — когда нельзя дать перечисленных гарантий. Гарантии эти дать нельзя — следовательно инкапсуляция это всегда плохо и всегда не нужна. Так получается?

DG>это ты сваливаешь все в кучу. ты и язык уровня компиляции и runtime уровня компиляции называешь одним словом компилятор.


Что означают словосочетания "язык уровня компиляции" и "runtime уровня компиляции"?

K>>Уметь мало. Нужно еще и делать. Какой смысл уметь выкопать канал одной лопатой, если на практике этого не сделать?

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

Какой смысл уметь фиксировать A с помощью языка B, если на практике этого не сделать?

K>>"Емкость" и "точность" — противоречивые требования, если под точностью понимается детальность.

DG>во-первых, есть парето-фронт — который для начала стоит достигнуть
DG>во-вторых, парето-фронт для множества задач может состоять и из одной точки

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

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

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

Ну, догматизм из слов "наверное можно" и "может быть" я тоже не способен выводить. Мои возможности вообще довольно ограничены.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[59]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 02.12.10 12:52
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>но, например, замечание с ForceSynchronize сводится к следующей работе разработчика:


Какой-то жуткий формализм, который непонятно как применять на практике.

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

Но допустим, что такая задача появилась, далее качество решения можно оценить с двух позиций:
1) Насколько просто решить эту задачу не меняя код решения.
2) Насколько просто решить эту задачу изменяя код решения.

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

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

Что тебе еще надо от решения?
Re[56]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 02.12.10 15:20
Оценка:
U>samius под иммутабельностью понимал наличие в программе только иммутабельных объектов, из чего следует что внесение изменений в мир производится через создание нового экземпляра мира. Именно про эту иммутабельность я и веду речь. Если ты о какой-то другой иммутабельности, то расскажи о какой.

это способ представления кода.
компилятором на основе этого иммутабельного представления генерятся мутабельные объекты и мутабельный код.
так понятнее?


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

DG>>и вот теперь объясни своими словами — как ты понимаешь данное утверждение. что программа одновременно мутабельна, и иммутабельна.

U>Откуда я могу знать, что ты понимаешь под данным утверждением? Разъясни, тогда я и смогу ответить как я его понял.


DG>>зы

DG>>ты кстати вообще понимаешь, что один и тот же код можно рассматривать с нескольких точек зрения, и записывать по разному — и при этом не меняя сам код?

DG>>т.е. представление кода меняется, а сам код не меняется.


U>Ничего не понял. Что такое "код" и что такое "представление кода" и чем они отличаются друг от друга?


код — это запись последовательности исполнения с помощью определенных правил.
например, выражение a + b *c можно записать как (и это будут разные представления одного и того же кода):
1. a + b * c
2. a+b*c
3. a + (b * c)
4. add(a, mul(b,c))
5. + (a (*(b c))) // префиксная, она же польская запись
6. new[]{a, new[]{b, c}.mul()}.add()
7. (a (b c)mul)add
8. (a (b c)*)+ //постфиксная запись
9. a1 + a2 * a3
10. a[1] + a[2] * a[3]
11. a.x + b.x * c.x
12. x.a + x.b + x.c


и есть правила(алгоритмы) — которые позволяют одно представление преобразовать в другое представление (при этом гарантируя, что исполнение при этом не поменяется)
далее фиксируется отличие. и правила преобразования отличия
1 <-> 2. пробельные символы есть/нет. преобразование 1->2 заменить все пробелы на пусто, 2->1 вокруг знаков операций расставить по одному пробелу
1 <-> 3. 1->3 расставить скобки, которые показывают какой будет действительный порядок выполнения, 3->1 убрать скобки, которые следует из приоритетов операций
3 <-> 4. запись делается или через операции, или через функции. 3->4 каждую тройку operand op operand заменить на function(op) (operand operand)
4->3 каждую тройку function (operand operand) заменить на (operand function.op operand)
//далее правила преобразования не фиксирую, связи с экономией времени
3<->5. операция записывается до операндов или между
3<->8. операция записывается после операндов или между
3<->9. имена переменных другие
3<->10. переменные рассматриваются как хранящиеся в массиве
3<->11. переменные рассматриваются как запакованные в какой-то другой тип
3<->12. переменные рассматриваются, как часть другой структуры

зачем все это надо?
если по коду надо ответить на какой-то вопрос (решить задачу над кодом), то часто по одному из представлению задачу решить намного проще, чем по другому.

задача:
1. понять(обозреть) что вообще делается — проще решается по первому 1.
2. получить минимальный листинг, который будет еще понятен компилятору — представление 2
3. зафиксировать в каком порядке точно будут выполняться операции — представление 3
4. какие функции будут вызываться и в каком порядке? представление 4
5. если исполнитель стековая машина, то в каком порядке числа будут помещаться на стек и обрабатываться? представление 8
6. какой длины массив необходим для хранения исходных данных для выражения? представление 10
7. как выражение будет выглядеть для nullable-типа, при отсутствии перегруженных операций? представление 11
8. какую структуру необходимо сделать, чтобы хранить исходные данные выражения? представление 12.


2. можно зайти с другой стороны.
рефлектором когда-нибудь пользовался?
обращал внимание на то, что он по одному и тому же IL-у может сгенерить листинги на IL, C#, VB, Delphi, MC++, Oxygene, F#? так же еще можно и выбрать версию языка. допустим для .net-а можно выбрать 1.0, 2.0, 3.5 и 4.0
и соответственно получается, что код-то один (он в dll-ке зафиксирован, а представить мы его можно на разных языках)

3. или взять тот же var
явная(тип указан явно) запись и неявная(указывается var) эквиваленты, и это два разных представления одного и того же кода
1. у первой записи преимущества, что она позволяет явно зафиксировать тип результата, и не допускает вольных трактовок
2. вторая запись позволяет не фиксировать тип результата

для простого кода оба преимущества не критичны
var x = 1 + 4;
int x = 1 + 4;


но вот для сложного кода преимущества становятся существенными, и могут переходить в новое качество
например, использование linq без слова var почти невозможно, т.к. кучу времен уйдет на явное прописывание типа результата
использование анонимных классов невозможно без наличия неявной записи.
//одно дело записать var, другое дело - руками явно записать тип результата
var index = this.GetType().Properties().GroupBy(property=>property.Name).ToDictionary(group=>group.Key, group=>group.ToArray());
Re[60]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 02.12.10 15:35
Оценка:
U>При разработке VirtualGridSynchronizer'а закладывалось, что перерисовка должна происходить автоматически при изменении значений ячеек. Задача автоматической перерисовки грида в других случаях не ставилась.

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

U> Какой-то жуткий формализм, который непонятно как применять на практике.


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

> который непонятно как применять на практике.


для этого достаточно открыть умную книжку, или меня спросить

U>Что тебе еще надо от решения?


гарантий, что код всегда работает, работает правильно, работает правильно и максимально эффективно.

вот представь, что тебе надо допустим отправить херотень на луну. предположим, что технических проблем нет, надо только правильно все закодировать.
задача очень сложная, у тебя в подчинении 200-программистов — которые колбасят какой-то код, и каждый зуб дает, что его код уж точно не содержит ошибок.
попытка у тебя только одна, за неудачу надо отвечать лично перед товарищем Берией, который знает только одно — что если хренотень сделала что-то неправильно, то значит ты лично допустил разгильдяйство и подлежишь расстрелу.
также пока предположим, что ресурсов у тебя бесконечно для решения данной задачи.
твои действия? как тебе минимизировать неудачу и свой расстрел?
Re[71]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 02.12.10 16:20
Оценка:
K>А что мощнее — возможность проводить корректные операции или отсутствие возможности проводить корректные операции?

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

DG>>2) вариантность вида — есть возможность проводить и корректные операции, и некорректные операции + есть возможность для определенного контекста потребовать гарантию возможности только корректных операции — мощнее, чем вариантность вида — есть возможность проводить и корректные операции и некорректные операции.


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


чего? что такое "второе мощнее первого"?

DG>>и это означает, что компилятор плохо, и для данного случая его необходимо заменить.


K>На что заменять, если все компиляторы плохие?


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

DG>>есть неэффективное место оно должно быть заменено. точка.


K>Неэффективное по каким критериям?


по всем с точностью до парето-фронта

K>Ну приведите пример: язык, разработчик, "сокрытие возможности доступа", обоснование.


1. assembler->маш.код, разработчик каждого ассемблера, отсутствие возможности влиять на трансляцию, преобразование эквивалентное и там нечего менять.
2. почти все языки,, сокрытие возможности менять встроенные типы, они один в один ложатся на регистры процессора и с точки зрения эффективности выполнения менять по большому счету нечего.

DG>>тогда это вредная инкапсуляция.


K>Для кого вредная? Если разработчик что-то инкапсулирует — это развязывает ему руки, позволяя что-то менять за "стенами" инкапсуляции и это облегчает для него соблюдения каких-то инвариантов.


для определенного круга пользователей (и кстати отсутствием лишних инкапсуляций обосновывается преимущество open-source над closed-source).

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


K>Там нет критерия — там отрицательная эвристика. Вы не пишете, когда инкапсуляция это хорошо, но пишете, когда инкапсуляция это плохо — когда нельзя дать перечисленных гарантий. Гарантии эти дать нельзя — следовательно инкапсуляция это всегда плохо и всегда не нужна. Так получается?


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

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

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

и например, для open-source можно считать, что как раз предоставляется не жесткая инкапсуляция, т.к. можно в любое время исходник переписать под себя. но тут мы приходим к параметру качества исходника с точки зрения его меняемости, а также стоимости сопровождения fork-а

DG>>это ты сваливаешь все в кучу. ты и язык уровня компиляции и runtime уровня компиляции называешь одним словом компилятор.


K>Что означают словосочетания "язык уровня компиляции" и "runtime уровня компиляции"?


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

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


K>>>Уметь мало. Нужно еще и делать. Какой смысл уметь выкопать канал одной лопатой, если на практике этого не сделать?

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

K>Какой смысл уметь фиксировать A с помощью языка B, если на практике этого не сделать?


чего? что такое "А"?
а вообще это фиксируется сплошь и рядом.
Re[61]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 05.12.10 13:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>вот только ты почему это допущение забыл упомянуть — когда я говорил — что есть проблема с отрисовкой оформления ячеек при gridsync, а ты меня убеждал в обратном.


Изначально ты говорил о следующих проблемах:

1. вывод в ячейке что-то отличного от просто текста (раскраска, форматирование, вывод rich-текста и т.д.)
2. поддержка rowspan, colspan-ов
3. вывод нескольких разнородных источников на одну сетку грида

Затем ты понял, что все перечисленное не является проблемой, и перескочил на другую тему.

Проблема у подхода с кэшами на самом деле есть, но она совсем в другом. Кэши отлично отвечают на вопрос, что нужно сделать, чтобы получить правильное состояние программы, но кэши не могут ответить на вопрос — когда нужно это сделать. Соответственно в gridSynchronizer'е, как частном случае подхода с кэшами, это проблема тоже есть. И решается она через периодическое принудительное сравнение текущего состояния входа кэша с запомненным. Однако такой подход имеет очень существенный недостаток, а именно медлительность. Большая частота синхронизации чревата тормозами, а при синхронизации 1-2 раза в секунду задержка при обновлении заметна пользователю. Соответственно избавиться от ручной синхронизации не получается, после выполнения действий приходится вызывать ForceSynchronize. Однако подход с кэшами позволяет нам обновление производить простым и однообразным образом (ForceSynchronize тяжело вызвать неправильно), а подход с периодической синхронизацией гарантирует, что, даже если мы забудем в каком-то случае явно вызывать обновление, приложение все равно будет работать корректно, хоть и не идеально.

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

DG>гарантий, что код всегда работает, работает правильно, работает правильно и максимально эффективно.


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

DG>вот представь, что тебе надо допустим отправить херотень на луну. предположим, что технических проблем нет, надо только правильно все закодировать.

DG>задача очень сложная, у тебя в подчинении 200-программистов — которые колбасят какой-то код, и каждый зуб дает, что его код уж точно не содержит ошибок.
DG>попытка у тебя только одна, за неудачу надо отвечать лично перед товарищем Берией, который знает только одно — что если хренотень сделала что-то неправильно, то значит ты лично допустил разгильдяйство и подлежишь расстрелу.

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

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

Важность задачи кардинально поменяет лишь административную часть. А именно функции и тесты должны писаться в нескольких вариантах, людьми никак не связанными друг с другом, выполнение действий должно резервироваться, отдельные модули должны испытываться на реальных, но менее важных и дорогостоящих задачах.
Re[62]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.12.10 15:26
Оценка:
U> добавить в gridSynchronizer входы не связанные с ячейками дело пятнадцати минут.

любая локальная проблема решается за "15 минут", но это не дает гарантию, что:
1. после внесения изменений не возникло несколько других проблем в других местах
2. все такие проблемы могут быть решены за конечное реальное время
3. проблема будет решена до того, как она станет критичной (проблема проявилась на реальном важном пуске, нет в наличии "15 минут", нет технической возможности внести исправление)
Re[63]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 05.12.10 17:19
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>он один: доказать полностью, что программа правильно работает.


И каким образом можно доказать правильно работы не то что программы, а хотя бы одной, но достаточно сложной функции? Ту же функцию контроля расписания я тебе приводил, объясни как можно доказать ее правильность?

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


С этим согласен. И это правильный путь, в отличие от мифического доказательства правильности программ.

DG>забываешь самое главное: первая главная задача программиста доказать что обработаны все варианты поведения.

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

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

DG>[/q]

DG>2. во-вторых, платформа исполнения при локальном сбое останавливало всю систему (вместо локализации ошибки, и остановки только части исполняемого кода)
DG>

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

DG>кстати вывод коммиссии подтверждает мои слова о том, что программу надо доказывать
DG>[q]
DG>Исключительная ситуация была обнаружена, но была обработана неподобающим образом, потому что было принято считать, что ПО должно рассматриваться, как правильное, пока не доказано обратное. Комиссия имеет основания предполагать, что этот же принцип лежит в основе и других разработок ПО для Ariane 5. Комиссия придерживается противоположной точки зрения — что ПО должно изначально считаться содержащим ошибки, пока использование принятых в настоящее время самых лучших практических методов не докажет, что оно правильное.


Вывод комиссии неверен, т.к. является классическим пожеланием благих намерений, которые невозможно применить на практике. Правильный вывод такой — "ПО должно изначально считаться содержащим ошибки, поэтому должно гарантироваться, что любая одиночная непредвиденная ошибка не должна приводить к выходу программы из строя". Из этого следует, что резервироваться должна не только аппаратика, но и программый код, т.к. вероятность того, что решение задачи написанное независимо разными людьми содержит одинаковые ошибки много ниже вероятности наличия в этих же решениях разных ошибок.
Re[64]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 05.12.10 18:41
Оценка:
U>Вывод комиссии неверен, т.к. является классическим пожеланием благих намерений, которые невозможно применить на практике. Правильный вывод такой — "ПО должно изначально считаться содержащим ошибки, поэтому должно гарантироваться, что любая одиночная непредвиденная ошибка не должна приводить к выходу программы из строя". Из этого следует, что резервироваться должна не только аппаратика, но и программый код, т.к. вероятность того, что решение задачи написанное независимо разными людьми содержит одинаковые ошибки много ниже вероятности наличия в этих же решениях разных ошибок.

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

другие разработки, например, ПО для самолета C-130 делается на языке Spark (это расширение Ada-ы со статическим контролем pre/post-условий)

http://www.altran-praxis.com/spark.aspx
http://www.adacore.com/home/products/sparkpro/tokeneer/discovery/lesson_contracts/

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


теми же способами которыми доказываются теоремы. а теорема того же ферма намного сложнее чем большинство программ.
теоремы в универе доказывал? алгоритм доказательства помнишь?

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

базовые операции a+b, if, for и т.д. считаются верными на фиксированном классе значений, а дальше вперед:
для каждого куска кода фиксируется pre/post-условия, инвариант.

> Ту же функцию контроля расписания я тебе приводил, объясни как можно доказать ее правильность?


в том виде — в котором оно записано — тяжело.
если переписать в ФЯ-шный вид, намного проще.
если записать ее через сведение к стандартным алгоритмам — сортировка, поиск, поиск путей в графе, динамическое программирование и т.д. то еще проще.
твою задачу можно свести к чему-то между топологической сортировкой и поиском пути в графе.
можно также доказать ее через динамическое программирование.

при использовании динамического программирования — доказательство элементарное.
динамическое программирование исходит из того, что:
1. на каждом шаге уже есть какое-то частичное хорошее решение,
2. каждый следующий шаг улучшает это решение на 1/n
3. итого, через n-шагов будет полное решение.
доказать лишь надо, что на каждом этапе существует шаг, который улучшит результат как минимум на 1/n.

этим способом, например, легко доказать верность алгоритма сортировки прямого выбора.

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


ты это расскажи математикам — что ничего доказать нельзя.
99.9% задач которые ты решаешь — имеют готовые доказанные алгоритмы, и это еще было сделано лет 100 назад.

ты хоть чуть-чуть теорию программирование ботал? не практику, а именно теорию.
хотя бы кнута, таха и т.д. — а у них там сплошные доказательства правильности работы алгоритма.
Re[65]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 06.12.10 04:39
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>другие разработки, например, ПО для самолета C-130 делается на языке Spark (это расширение Ada-ы со статическим контролем pre/post-условий)


И как тебе pre/post условия помогают понять какие варианты надо рассмотреть? Как, к примеру, они помогают понять какие варианты надо рассмотреть для контроля расписаний?

DG>базовые операции a+b, if, for и т.д. считаются верными на фиксированном классе значений, а дальше вперед:

DG>для каждого куска кода фиксируется pre/post-условия, инвариант.

Что это дает-то? Что ты вообще собрался доказывать для функции контроля расписания? Соответствие ответа чему?

DG>при использовании динамического программирования — доказательство элементарное.

DG>этим способом, например, легко доказать верность алгоритма сортировки прямого выбора.

Ну да, потратив кучу времени таким способом можно доказать какую-нибудь примитивную ерунду, которая и так очевидна.

DG>ты хоть чуть-чуть теорию программирование ботал? не практику, а именно теорию.

DG>хотя бы кнута, таха и т.д. — а у них там сплошные доказательства правильности работы алгоритма.

Потому что в массе своей все это крайне примитивные алгоритмы, для которых можно четко сформулировать входы и критерии правильности выхода. Для реальных задач такое не прокатывает, наглядный пример тому тот же самый контроль расписания или контроль сливов топлива.
Re[72]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 06.12.10 10:41
Оценка:
Здравствуйте, DarkGray, Вы писали:

K>>А что мощнее — возможность проводить корректные операции или отсутствие возможности проводить корректные операции?


DG>если при прочих равных, то очевидно что первое (это как раз из парето и следует)

DG>но вот на вопрос, что мощнее — возможность проводить только корректные операции или возможность проводить только некорректные операции: нет однозначного ответа.
DG>в одних контекстах — может быть необходимо одно, а в других — другое.

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

DG>что такое "второе мощнее первого"?


Означает, что то что описано в пункте 2) мощнее того, что описано в пункте 1)

K>>На что заменять, если все компиляторы плохие?

DG>на менее плохой (либо на комбинацию плохих — которая в сумме менее плохая, чем каждый по отдельности).

И как вы сумму посчитаете?

K>>Неэффективное по каким критериям?

DG>по всем с точностью до парето-фронта

Еще раз, чтоб говорить о какой-то точности нужно и критерии задавать точно. И измерять характеристики точно. Как вы будете, например, агрегировать время работы программы в тиках, используемую память в байтах/тик и затраченый труд программистов в долларах/мес.?

K>>Ну приведите пример: язык, разработчик, "сокрытие возможности доступа", обоснование.


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


Это вообще не язык, раз преобразование эквивалентное.

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


Какого процессора?

K>>Для кого вредная? Если разработчик что-то инкапсулирует — это развязывает ему руки, позволяя что-то менять за "стенами" инкапсуляции и это облегчает для него соблюдения каких-то инвариантов.

DG>для определенного круга пользователей

Для пользователей это тоже полезно. Когда разработчик меняет что-то по ту сторону инкапсуляции код пользователя не ломается.

DG>(и кстати отсутствием лишних инкапсуляций обосновывается преимущество open-source над closed-source).


Умопомрачительно.

DG>т.е. разработчик не уверен, что его решение после выпуска идеальное


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

DG>и хочет его менять параллельно с тем, как другие его используют?


Да какая разница, хочет он этого или нет? Факт, что ему придется так делать.

DG>а если оно идеальное, то зачем он его хочет переписывать?


А если программист — фея, то зачем что-то писать/переписывать? Взмах волшебной палочкой — и все довольны без всякого программирования.

DG>введение инкапсуляции всегда ухудшает параметр гибкость.


Да вы что? Инкапсуляция, а точнее абстракция вводится для увеличения гибкости. Код без изоляции частей друг от друга не обладает гибкостью вообще.

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


Наоборот.

DG>разработчик использовал массив, список и т.д. хранящийся в памяти и заинкапсулировал это.

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

Наоборот, можно. И благодаря нормальной инкапсуляции и абстракции.

DG>инкапсуляция хороша только как подсказка, что вот с таким-то модулем вы можете работать через вот такой простой интерфейс, но если вам понадобится, то вы можете залезть и через более расширенный интерфейс.


И потерять возможность заменить массив в памяти на другую структуру!

K>>Что означают словосочетания "язык уровня компиляции" и "runtime уровня компиляции"?

DG>язык уровня компиляции — понятия которого существуют только на уровне компиляции, и не существуют при выполнении.

Т.е. любой компилируемый язык?

DG>runtime уровня компиляции — исполняемый код, который работает только на уровне компиляции, и отсутствует на этапе выполнения.


Это называется компайл-тайм вычисления. А рантайм компайлтайма — это оксюморон.

DG>простейшим примером первого и второго является допустим язык макросов в C и макро-процессор в C


Язык макро-препроцессора и C — разные языки. Первым вы можете хоть Хаскель препроцессить. Какой смысл их смешивать в один язык? Чтоб получать словесных монстров вроде "runtime уровня компиляции"?

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


Ничего не понимаю. Речь идет о, например, JIT динамического языка с выводом типа и специальных аннотациях, расширяющих динамический язык и делающий этот вывод возможным?

DG>чего? что такое "А"?


Что угодно.

DG>а вообще это фиксируется сплошь и рядом.


Или не фиксируется. Вот представьте, что вы знаете, как зафиксировать A на языке B. Но фиксация потребует миллиард строк на языке B и ~100000 человекомесяцев. Зафиксируете?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 06.12.10 11:03
Оценка:
Здравствуйте, samius, Вы писали:

U>Что это дает-то? Что ты вообще собрался доказывать для функции контроля расписания? Соответствие ответа чему?

S>Если ответ ничему не должен соответствовать, то нафик он нужен?

Ответ должен соответствовать представлениям диспетчеров о прохождении расписании и здравому смыслу. Соответственно для каждого конкретного случая диспетчер может разъяснить каким должен быть ответ. И как ты будешь доказывать соответствие ответа представлениям диспетчера и здравому смыслу?

Есть задачи, в которых проверка ответа на правильность проще, чем само решение задачи (например, сортировка), в таких задачах математическое доказательство иногда применимо. А есть задачи, в которых проверка ответа на правильность сравнима по сложности с решением самой задачи, вот в таких задачах от математических доказательств толку ноль.

S>return 42;

S>и все счастливы.

Ответ 42 противоречит и представлениям диспетчеров и здравому смыслу, соответственно никто не счастлив.
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.12.10 11:15
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


U>>Что это дает-то? Что ты вообще собрался доказывать для функции контроля расписания? Соответствие ответа чему?

S>>Если ответ ничему не должен соответствовать, то нафик он нужен?

U>Ответ должен соответствовать представлениям диспетчеров о прохождении расписании и здравому смыслу. Соответственно для каждого конкретного случая диспетчер может разъяснить каким должен быть ответ.

Хорошо, что хоть нашли, чему должен ответ соответствовать.

U>И как ты будешь доказывать соответствие ответа представлениям диспетчера и здравому смыслу?

Как — это уже отдельный вопрос. Но важно то, что доказанно соответствующий ответ гораздо ценнее, чем любой другой, в том числе соответствующий практически. Особенно для диспетчеров.
Если за диспетчерские ошибки "сушить" будут программистов, я думаю, что ты со мной согласишься.

U>Ответ 42 противоречит и представлениям диспетчеров и здравому смыслу, соответственно никто не счастлив.

странно что не соответствует сюда сюда
Re[73]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 06.12.10 11:40
Оценка:
K>Я говорил о разрушении контекста, в котором возможно проводить только корректные операции. Получая доступ на нижний уровень мы портим разделение на контексты, установленное верхним уровнем.

кто сказал — что это разделение было единственно верным, и откуда следует что нельзя провести другое разделение на контексты?

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

K>>>На что заменять, если все компиляторы плохие?

DG>>на менее плохой (либо на комбинацию плохих — которая в сумме менее плохая, чем каждый по отдельности).

K>И как вы сумму посчитаете?


с помощью функции newsystem sum(system1/part4, system2/part2)

K>Еще раз, чтоб говорить о какой-то точности нужно и критерии задавать точно. И измерять характеристики точно. Как вы будете, например, агрегировать время работы программы в тиках, используемую память в байтах/тик и затраченый труд программистов в долларах/мес.?


из использованим парето следует, что нет необходимости считать абсолютные величины, достаточно уметь сравнивать — что вот в этом случае затраты будут больше, чем в этом случае, в этом наоборот.
а операции сравнения для оценки в тиках, в байтах и программистах вводятся достаточно легко.
хотя бы что: F(A+B) > F(A) и F(A+B) > F(B)

K>Это вообще не язык, раз преобразование эквивалентное.


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

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

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


K>Какого процессора?


любого регистрового процессора со следующими ограничениями:
а) для языков с фиксированной размерностью типа number(и его аналогов) такой процессоров должен соблюдать правило, что в байте 8 бит, а word-ы и более состоят из byte-ов.
b) для языков с нефиксированной размерностью — достаточно ограничения, что размерность регистров достаточен для хранения размерности типа данных используемого в программе.

K>Для пользователей это тоже полезно. Когда разработчик меняет что-то по ту сторону инкапсуляции код пользователя не ломается.


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


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


дальше у тебя пошли сплошные эмоции.
обоснуй почему программа не может быть идеальной?


K>>>Что означают словосочетания "язык уровня компиляции" и "runtime уровня компиляции"?

DG>>язык уровня компиляции — понятия которого существуют только на уровне компиляции, и не существуют при выполнении.

K>Т.е. любой компилируемый язык?


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

соответственно язык шаблонов — это чисто "язык уровня компиляции".

DG>>runtime уровня компиляции — исполняемый код, который работает только на уровне компиляции, и отсутствует на этапе выполнения.


K>Это называется компайл-тайм вычисления. А рантайм компайлтайма — это оксюморон.


и тот же препроцессор входит в понятие компайл-тайм вычисления?

DG>>простейшим примером первого и второго является допустим язык макросов в C и макро-процессор в C


K>Язык макро-препроцессора и C — разные языки. Первым вы можете хоть Хаскель препроцессить. Какой смысл их смешивать в один язык? Чтоб получать словесных монстров вроде "runtime уровня компиляции"?


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

DG>>а вообще это фиксируется сплошь и рядом.


K>Или не фиксируется. Вот представьте, что вы знаете, как зафиксировать A на языке B. Но фиксация потребует миллиард строк на языке B и ~100000 человекомесяцев. Зафиксируете?


и что этот пример доказывает?

зы
вообще скучно. ты не утверждаешь ничего своего и полезного.
ты только утверждаешь, что как оно есть — это есть правильно, потому что так все делают, и так нам делать завещали предки.
т.е. у тебя ритуальных подход (обязательно надо делать так же как это делалось вчера, и тогда мы получим результат), а не научный.
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 06.12.10 12:32
Оценка:
U>Ответ должен соответствовать представлениям диспетчеров о прохождении расписании и здравому смыслу. Соответственно для каждого конкретного случая диспетчер может разъяснить каким должен быть ответ.

здравый смысл формализуется, и сводится в полную непротиворечивую систему.

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

и соответственно для каждого варианта входной последовательности тебе либо необходимо зафиксировать валидность такой последовательности
(и это у тебя пред-условие)

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

зы
и как я уже говорил, та же система тестов строится этим же путем

U> И как ты будешь доказывать соответствие ответа представлениям диспетчера и здравому смыслу?


здесь доказывается — что программа получает результат, который удовлетворяет формальной системе из предыдущего пункта.
Re[74]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Klapaucius  
Дата: 07.12.10 13:49
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

DG>кто сказал — что это разделение было единственно верным, и откуда следует что нельзя провести другое разделение на контексты?

Ниоткуда не следует. Берите и проводите другие. Но это деалется на верхнем уровне — на нижнем нечего проводить — там нет средств проведения.

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


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

K>>>>На что заменять, если все компиляторы плохие?

DG>>>на менее плохой (либо на комбинацию плохих — которая в сумме менее плохая, чем каждый по отдельности).
K>>И как вы сумму посчитаете?
DG>с помощью функции newsystem sum(system1/part4, system2/part2)

Ну конечно. Приведите пример расчета для любой пары компиляторов и сравните с оценкой для любого одного.

K>>Еще раз, чтоб говорить о какой-то точности нужно и критерии задавать точно. И измерять характеристики точно. Как вы будете, например, агрегировать время работы программы в тиках, используемую память в байтах/тик и затраченый труд программистов в долларах/мес.?

DG>из использованим парето следует, что нет необходимости считать абсолютные величины, достаточно уметь сравнивать — что вот в этом случае затраты будут больше, чем в этом случае, в этом наоборот.
DG>а операции сравнения для оценки в тиках, в байтах и программистах вводятся достаточно легко.
DG>хотя бы что: F(A+B) > F(A) и F(A+B) > F(B)

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

K>>Это вообще не язык, раз преобразование эквивалентное.

DG>обоснуй, пожалуйста, утверждение, что если преобразование эквивалентное, то языка — нет.

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

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

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

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

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

K>>Какого процессора?
DG>любого регистрового процессора со следующими ограничениями:
DG>а) для языков с фиксированной размерностью типа number(и его аналогов) такой процессоров должен соблюдать правило, что в байте 8 бит, а word-ы и более состоят из byte-ов.
DG>b) для языков с нефиксированной размерностью — достаточно ограничения, что размерность регистров достаточен для хранения размерности типа данных используемого в программе.

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

K>>Для пользователей это тоже полезно. Когда разработчик меняет что-то по ту сторону инкапсуляции код пользователя не ломается.

DG>это можно гарантировать и еще миллионом способов. инкапсуляция с точки зрения гибкости и эффективности — худший из них.

Хотелось бы увидеть пару примеров более хороших способов.

DG>обоснуй почему программа не может быть идеальной?


Дайте сначала определение идеальной программы.

DG>я утверждаю, что это различные движки управляемые разными языками.

DG>и движки — которые делает вывод типов, определение размера типа, паттерн-матчинга, шаблонов и т.д. — это все разные движки, каждый из которых управляется своим языком (который является подмножеством языка программирования, как мы его понимаем)

Такое разделение — это чистая условность. Если нам удобно рассматривать что-то как встроенный язык — можем рассматривать. Если нам это ничего не дает — можем не рассматривать.

DG>и что этот пример доказывает?


Этот пример иллюстрирует разницу между уметь и мочь.

DG>вообще скучно. ты не утверждаешь ничего своего и полезного.

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

Привести несколько подтвеждающих такие заявления цитат сможете?
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[75]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 07.12.10 14:57
Оценка:
DG>>ты кстати вообще понимаешь, что инкапсуляция делается только из-за того, что разработчик не всё записывает в коде, а большую часть знаний о работе кода оставляет у себя в голове?

K>Вообще, я понимаю, что это ваше утверждение не соотвествует действительности.


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

где ошибка в данных выводах?

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


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


K>>>Это вообще не язык, раз преобразование эквивалентное.

DG>>обоснуй, пожалуйста, утверждение, что если преобразование эквивалентное, то языка — нет.

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

K>Пример с ассемблером, таким образом, отметается — максимальная эффективность там при преобразовании не гарантируется.

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

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

языки же верхнего уровня вводят только из-за того, что у любой программы кроме конечного исполнителя, есть как минимум еще один исполнитель: разработчик. которому удобнее "исполнять" код верхнего уровня, чем низкоуровневый код.

причем есть важное отличие: разработчик при "исполнении" кода оперирует классами элементов, а не самими элементами.
и соответственно в том числе, может за секунду "исполнить" и бесконечные циклы определенных видов (например, следующий цикл for(int x=0;){x++;})

K>>>Для пользователей это тоже полезно. Когда разработчик меняет что-то по ту сторону инкапсуляции код пользователя не ломается.

DG>>это можно гарантировать и еще миллионом способов. инкапсуляция с точки зрения гибкости и эффективности — худший из них.

K>Хотелось бы увидеть пару примеров более хороших способов.


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

DG>>вообще скучно. ты не утверждаешь ничего своего и полезного.

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

K>Привести несколько подтвеждающих такие заявления цитат сможете?


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

K>Вообще, я понимаю, что это ваше утверждение не соотвествует действительности.

K>Ну конечно. Приведите пример расчета для любой пары компиляторов и сравните с оценкой для любого одного.

K>Такое разделение — это чистая условность. Если нам удобно рассматривать что-то как встроенный язык — можем рассматривать. Если нам это ничего не дает — можем не рассматривать.

K>Этот пример иллюстрирует разницу между уметь и мочь.

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


не тривиальным было только вот это утверждение

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

Re[69]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 05:37
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>и соответственно для каждого варианта входной последовательности тебе либо необходимо зафиксировать валидность такой последовательности

DG>(и это у тебя пред-условие)

Что конкретно нужно фиксировать в предусловии контроля расписаний?

DG>а для каждого выходной последовательности зафиксировать, чем эта последовательность не удовлетворяет результату

DG>например, чем нас не устраивает пустая последовательность на выходе для любого входа?

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

DG>формализованный ответ скорее всего будет:

DG>на выходе должны быть все входные точки за исключением следующих ситуаций ...
DG>так же скорее требуется фиксировать и обратное:
DG>на выходе не должны быть доп. точек, которых не было на входе, за исключением следующих ситуаций
DG>(а вот это все у тебя пост-условие)

Что конкретно должно быть в постусловии контроля расписаний? И чем это постусловие будет отличаться от полного или частичного решения задачи?

DG>зы

DG>и как я уже говорил, та же система тестов строится этим же путем

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

U>> И как ты будешь доказывать соответствие ответа представлениям диспетчера и здравому смыслу?

DG>здесь доказывается — что программа получает результат, который удовлетворяет формальной системе из предыдущего пункта.

Какой формальной системе должен удовлетворять результат контроля расписаний?
Re[76]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Константин Б. Россия  
Дата: 08.12.10 05:57
Оценка:
Здравствуйте, DarkGray, Вы писали:

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

K>>Вообще, я понимаю, что это ваше утверждение не соотвествует действительности.
DG>зачем делается инкапсуляция? зачем что-то скрывается? чтобы это скрытое не сломали

Наоборот. Чтобы изменения в этом скрытом не сломали остальное. Ну и дальше идут не верные выводы.

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

DG>но если они ошиблись и их действия ломают что-то, то почему им не может об этом сказать компилятор? не может, потому что разработчик не все записал в коде
DG>- те кто используют — тупицы и не умеют читать? нет, проблема не в этом разработчику модуля было лень писать развернутую документацию, и поэтому он заюзал инкапсуляцию

DG>где ошибка в данных выводах?
Re[66]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Воронков Василий Россия  
Дата: 08.12.10 08:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>а теперь оцени потери производительности по сравнению с исходной версией на императивном языке (C/C++/Java/CSharp и т.д.)

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

А сам-то ты, какие проблемы в этом коде видишь? Он вообще должен компилироваться в код, практически идентичный приведенному тобой императивному примеру. А вот Линковое "items.Where(item=>item > 10).ToArray()" таки к потерям неизбежно приведет.
Re[76]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 08:41
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>зачем делается инкапсуляция? зачем что-то скрывается? чтобы это скрытое не сломали


В первую очередь инкапсуляция делается для упрощения использования, а именно для уменьшения количества информации, которое нужно помнить для успешного использования. И это очень важная задача, т.к. человек способен держать в голове очень ограниченное количество информации. Ни запись всех мыслей разработчика в код, ни документация эту задачу не решают, поэтому никак не могут служить заменой инкапсуляции.
Re[77]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 09:21
Оценка:
U>В первую очередь инкапсуляция делается для упрощения использования, а именно для уменьшения количества информации, которое нужно помнить для успешного использования. И это очень важная задача, т.к. человек способен держать в голове очень ограниченное количество информации. Ни запись всех мыслей разработчика в код, ни документация эту задачу не решают, поэтому никак не могут служить заменой инкапсуляции.

инкапсуляция инкапсуляции рознь.

хорошая инкапсуляция — это рекомендация вида: для решения большинства задач достаточно пользоваться интерфейсом вот из этих двух функций, но при необходимости есть еще десять, а может еще залезть под капот — будет 50, а если перейдете на следующий уровень — то и все 375.

плохая инкапсуляция — это запрет. вот вам две функции, а остальное вы не должны хотеть.

банальный пример Stack
Stack — может предоставлять только функции Push/Pop — и это будет достаточно для 80% примений, но всегда остается 20% или 2%, или 0.2% задач, когда нужно большее, например, нужны PushRange/PopRange, RemoveAll, RemoveIf и т.д.
Re[66]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 09:45
Оценка:
U>И как тебе pre/post условия помогают понять какие варианты надо рассмотреть? Как, к примеру, они помогают понять какие варианты надо рассмотреть для контроля расписаний?

есть такая наука, называется математика — встречал такое слово? и она такую задачу решило еще лет 200-300 назад

это есть задача отображения одного пространства на другое. а программа — это лишь один из способов задания правил отображения.

DG>>базовые операции a+b, if, for и т.д. считаются верными на фиксированном классе значений, а дальше вперед:

DG>>для каждого куска кода фиксируется pre/post-условия, инвариант.

U>Что это дает-то? Что ты вообще собрался доказывать для функции контроля расписания? Соответствие ответа чему?


критерию правильности, который ты должен был, как постановщик задачи, зафиксировать.

не зафиксировал? садись — два. следующий.

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

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

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

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


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


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

соответственно на этапе постановки задачи есть задача выделение общей части задачи.

для следующей функции нельзя утверждать, что если проверены пара точек, то будут работать правильно и остальные.
int F(int x)
{
  switch (x)
  {
    case 1:
      return 5;
    case 2:
      return -5;
    case 3:
      return 4;
    case 4:
      return 7;
    case 5:
      return 12;
    case 6:
      return 5;
    case 7:
      return 3;
    case 8:
      return -3;
   //и т.д.
  }
}
Re[77]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 09:45
Оценка:
КБ>Наоборот. Чтобы изменения в этом скрытом не сломали остальное. Ну и дальше идут не верные выводы.

т.е. разработчик для остального кода — не зафиксировал когда он ломается?
Re[67]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 10:39
Оценка:
Здравствуйте, DarkGray, Вы писали:

U>>И как тебе pre/post условия помогают понять какие варианты надо рассмотреть? Как, к примеру, они помогают понять какие варианты надо рассмотреть для контроля расписаний?

DG>есть такая наука, называется математика — встречал такое слово? и она такую задачу решило еще лет 200-300 назад

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

Так откуда у тебя берется уверенность, что подход математики, не всегда работающий даже в своем мирке, будет работать в куда более сложном реальном мире?

DG>критерию правильности, который ты должен был, как постановщик задачи, зафиксировать.


Ты конкретно можешь сказать, что нужно зафиксировать в задаче контроля расписаний? В чем смысл общими словесами сыпать, если ты даже конкретную задачу не можешь решить?

DG>у тебя на самом деле есть знание, когда алгоритм правильно работает.

DG>и соответственно ты либо его не хочешь фиксировать (и тогда тебе ничем помочь нельзя), либо не умеешь его осозновать и фиксировать.

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

DG>тесты для нескольких точек имеют пользу только для задач имеющих общую формулу.

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

Именно по этой причине тесты не могут ничего гарантировать и соответственно не имеют никакого отношения к доказательству правильности кода.
Re[78]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 10:58
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>хорошая инкапсуляция — это рекомендация вида: для решения большинства задач достаточно пользоваться интерфейсом вот из этих двух функций, но при необходимости есть еще десять, а может еще залезть под капот — будет 50, а если перейдете на следующий уровень — то и все 375.


Проблема в том, что после залезания под капот верхний уровень инкапсуляции начнет работать не так как раньше. Соответственно, как минимум, при понимании работы кода всегда придется держать в голове возможность того, что код ведет себя так, а не иначе из-за того, что кто-то залез под капот.
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.12.10 11:08
Оценка:
Здравствуйте, Undying, Вы писали:

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


Видимо ты хотел подставить координаты многоугольника в формулу, выражающую центр окружности?
В остальном у математики нет проблем с этой задачей.
Re[69]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 11:10
Оценка:
Здравствуйте, samius, Вы писали:

S>Видимо ты хотел подставить координаты многоугольника в формулу, выражающую центр окружности?


Разумеется я этого не хотел.

S>В остальном у математики нет проблем с этой задачей.


И каково решение этой задачи? Как выглядит доказательство этого решения?
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 11:20
Оценка:
U>Математика живет с своем предельно упрощенном мире. И при этом даже в этом мире математики умеют решать лишь очень узкий набор задач. Например, на днях интересовался вопросом нахождения окружности минимального радиуса описывающей произвольный многоугольник, сложилось впечатление, что математика на этот вопрос ответить не может, хотя казалось бы задача примитивней некуда.

обычная задача с олимпиады по программированию уровня района города 10 класса

U>Так откуда у тебя берется уверенность, что подход математики, не всегда работающий даже в своем мирке, будет работать в куда более сложном реальном мире?


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

DG>>критерию правильности, который ты должен был, как постановщик задачи, зафиксировать.


U>Ты конкретно можешь сказать, что нужно зафиксировать в задаче контроля расписаний? В чем смысл общими словесами сыпать, если ты даже конкретную задачу не можешь решить?


начинать с очевидного и его фиксировать.

1. если предусловие: все точки различны, точки при этом уже упорядоченные, то правильный ответ — те же самые точки.
это верно? можешь доказать про свой алгоритм, что для данного класса он выдаст именно это?
2. предусловие: входная последовательность состоит из двух перемешанных последовательность: прямой и обратной. правильный ответ — на выходе должна остатся только прямая
верно? есть доказательство, что текущий алгоритм это всегда отрабатывает?
и т.д.

также стоит зайти со стороны общей постановки.
у тебя задача — убрать шум или задача — восстановить образец?
это как раз помогает зафиксировать ответ на вопрос — точки в выходную последовательность добавляются или нет?
т.е. для последовательности a1, a3, правильный ответ: a1, a3 или a1, a2, a3.
Re[79]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 11:24
Оценка:
U>Проблема в том, что после залезания под капот верхний уровень инкапсуляции начнет работать не так как раньше. Соответственно, как минимум, при понимании работы кода всегда придется держать в голове возможность того, что код ведет себя так, а не иначе из-за того, что кто-то залез под капот.

эту задачу должен делать компьютер. а не может он это делать, потому что разработчик большую часть информации в компьютер не вносит.
как ты, например, в задаче с расписанием.
Re[68]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 11:35
Оценка:
U>И при этом даже в этом мире математики умеют решать лишь очень узкий набор задач.
...
U>Именно по этой причине тесты не могут ничего гарантировать и соответственно не имеют никакого отношения к доказательству правильности кода.
..
U>Ну да, потратив кучу времени таким способом можно доказать какую-нибудь примитивную ерунду, которая и так очевидна.

всем этих утверждениях четко выражена мысль "я это делать не умею, поэтому это никто в мире делать не умеет".

зы
мантру "все остальные такие же тупые, как я" — стоит повторять по чаще.
она точно ведет к успеху
Re[71]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 12:37
Оценка:
Здравствуйте, samius, Вы писали:

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


А если многоугольник невыпуклый?

S>Затем берем вершину ВО с максимально острым углом и несложным итеративным процессом выбираем еще две вершины выпуклой оболочки таким образом, что бы описывающая окружность содержала все остальные вершины выпуклой оболочки и ее радиус был минимальным.


S>Единственный неочевидный момент в доказательстве будет лишь тот, который будет доказывать что вершина с максимально острым углом ВО будет лежать на искомой окружности. Я думаю что это не составит проблемы.


Как будет выглядеть доказательство? Сколько у тебя займет запись этого доказательства? Что гарантирует, что в процессе доказательства не было допущено ошибок?

S>Хотя, ВО нужна лишь для того, что бы уменьшить число итераций и зафиксировать первую вершину.

S>В остальном задача решается полным перебором троек вершин

Центр окружности где будет находится?

S>и доказательство решения сводится к "очевидно".


И чем это "очевидно" отличается от "мамой клянусь, что в коде нет ошибок"?
Re[72]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 12:50
Оценка:
S>>Для начала несложно показать что окружность будет одинаковая для всего множества многоугольников, чья выпуклая оболочка будет совпадать с выпуклой оболочкой заданного многоугольника.

U>А если многоугольник невыпуклый?


ответ на твой вопрос уже есть в процитированном тобой утверждении samius-а

U>Как будет выглядеть доказательство? Сколько у тебя займет запись этого доказательства? Что гарантирует, что в процессе доказательства не было допущено ошибок?


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

S>>Хотя, ВО нужна лишь для того, что бы уменьшить число итераций и зафиксировать первую вершину.

S>>В остальном задача решается полным перебором троек вершин

U>Центр окружности где будет находится?


а если чуть-чуть подумать?

S>>и доказательство решения сводится к "очевидно".


U>И чем это "очевидно" отличается от "мамой клянусь, что в коде нет ошибок"?


слово "очевидно" в данном случае означает, что если чуть-чуть подумать, то все остальные выкладки "тривиальные".
Re[73]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 13:57
Оценка:
Здравствуйте, DarkGray, Вы писали:

U>>Центр окружности где будет находится?

DG>а если чуть-чуть подумать?

Давай конкрентно — явки, пароли. Что за дурацкая манера не отвечать на прямо поставленный вопрос?
Re[74]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 08.12.10 14:04
Оценка:
S>>В остальном задача решается полным перебором троек вершин
U>>Центр окружности где будет находится?
DG>а если чуть-чуть подумать?

U> Давай конкрентно — явки, пароли. Что за дурацкая манера не отвечать на прямо поставленный вопрос?


центр окружности будет находится в центре окружности, проходящей через три данные вершины
Re[75]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 15:00
Оценка:
Здравствуйте, DarkGray, Вы писали:

U>> Давай конкрентно — явки, пароли. Что за дурацкая манера не отвечать на прямо поставленный вопрос?

DG>центр окружности будет находится в центре окружности, проходящей через три данные вершины

Правда? И для вытянутого ромба тоже? Через какие такие три вершины будет проходить центр минимальной описывающей окружности в этом случае?
Re[73]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 15:03
Оценка:
Здравствуйте, samius, Вы писали:

S>Назови мне ВУЗ, который ты заканчивал. Буду рекомендовать его некоторым знакомым, которые боятся перегрузить голову.


Тебя, как и Darkgray'я, тоже в элитном вузе учили, что окружность минимального радиуса описывающая многоугольник должна проходить не менее чем через три точки?
Re[76]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: samius Япония http://sams-tricks.blogspot.com
Дата: 08.12.10 15:25
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, samius, Вы писали:


S>>Меня этому не учили, но для меня это очевидно.


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


Да, поймал. Однако этот аспект не придает задаче принципиально иную сложность.
В свою очередь выражаю недоумение по поводу "вытянутого ромба". Что такое ромб — знаю.
Re[77]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: Undying Россия  
Дата: 08.12.10 16:58
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>согласен. есть такой вырожденный случай. для него центр окружности будет в центре самой отдаленной пары вершин.


Для космических кораблей ты также собрался алгоритмы доказывать? Этот алгоритм работает правильно, т.к. его доказательство очевидно? А когда космический корабль упадет будешь говорить, что ничего страшного, зато узнали, что у доказательства был вырожденный случай?

DG>зы

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

И где строгое доказательство для данной задачи?
Re[78]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 09.12.10 07:49
Оценка:
Здравствуйте, Undying, Вы писали:

U>И где строгое доказательство для данной задачи?


Как для выпуклого многоугольника построить описывающую окружность очевидно?
Re[78]: OOD vs SA/SD (ну или OO vs FP раз уж на то пошло)
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 09.12.10 12:48
Оценка:
U>Для космических кораблей ты также собрался алгоритмы доказывать? Этот алгоритм работает правильно, т.к. его доказательство очевидно? А когда космический корабль упадет будешь говорить, что ничего страшного, зато узнали, что у доказательства был вырожденный случай?

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

U>И где строгое доказательство для данной задачи?


для строгого доказательства необходимо доказать, что ответ — является решением (все точки в него входят), и при этом ответ — является минимальным решением (меньше построить нельзя)

базовое утверждение 1 — окружность задается не больше, чем тремя точками (это есть следствие того, что через любые три точки можно провести _единственную_ окружность), остальные точки тоже могут лежат на окружности, но они не требуются для ее задания.
назовем такие точки опорными.

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

диаметр описанной окружности равен длине стороны поделенной на синус противоположного угла (D = a / sin A)

для первого случая (остроугольный) — если окружность не касается одной из вершин, то можно построить треугольник со следующими вершинами (две оставшиеся + одна на окружности) причем такой, что исходный треугольник лежит внутри него.
у исходного треугольника и у данного треугольника — опорная сторона общая при этом у нового треугольника угол более острый, и на основе формулы диаметра и того, что sin a1 < sin a2 (при 0 < a1 < a2 < 90), получаем что у нового треугольника диаметр окружности больше.
для второго случая — меньше диаметра расстояний в окружности не бывает, поэтому построить окружность меньшего размера нельзя.
при этом тупая вершина входит в окружность построенной на большей стороне.


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

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