Здравствуйте, vdimas, Вы писали:
V>То бишь юмор был в том, что программа на Хаскеле, составленная из чистых ф-ий, на самом деле НЕ МОЖЕТ быть выполнена в чистой манере. И даже не потому, что в main подается IO, а потому что вычислитель конечный, и этот конечный вычислитель ОБЯЗАН упорядочивать вычисления, невзирая на то, что порядок якобы не важен. Механизм упорядочивания в Хаскеле автоматический — на ленивости, мемоизации и гарантиях порядка вычислений аргументов при if-then-else и в конструкциях ПМ. Вот то надо выучить, чтоб от зубов отскакивало, это принципиально. Так вот, принципиально, что порядок этот гарантируется и программист может на него можно полагаться в "чистой" программе. То бишь, если бы программы на Хаскеле писали исходя из предположения, что они будут выполняться абстрактным вычислителем, который вычисляет аргумнты ф-ий в произвольном порядке, согласно их чистоты, то эти программы надо было бы писать по-другому. Вот всё что было сказано, не надо было изборетать лишнего.
Ты лучше пример покажи, а то я чет не понимаю, какая то новая концепция в хаскеле, что надо запоминать какой то механизм упорядочивания. Может я не те книги по Хаскелю купил
Здравствуйте, vdimas, Вы писали:
V>То бишь юмор был в том, что программа на Хаскеле, составленная из чистых ф-ий, на самом деле НЕ МОЖЕТ быть выполнена в чистой манере. И даже не потому, что в main подается IO, а потому что вычислитель конечный, и этот конечный вычислитель ОБЯЗАН упорядочивать вычисления, невзирая на то, что порядок якобы не важен. Механизм упорядочивания в Хаскеле автоматический — на ленивости, мемоизации и гарантиях порядка вычислений аргументов при if-then-else и в конструкциях ПМ. Вот то надо выучить, чтоб от зубов отскакивало, это принципиально. Так вот, принципиально, что порядок этот гарантируется и программист может на него можно полагаться в "чистой" программе. То бишь, если бы программы на Хаскеле писали исходя из предположения, что они будут выполняться абстрактным вычислителем, который вычисляет аргумнты ф-ий в произвольном порядке, согласно их чистоты, то эти программы надо было бы писать по-другому. Вот всё что было сказано, не надо было изборетать лишнего.
Хм. В таком случае чистых функций вообще не существует, поскольку в лямбда-исчислении могут получаться разные результаты в зависимости от выбраной стратегии редукции (я имею в виду, что при аппликативном порядке редукции нормальная форма не всегда достижима).
Здравствуйте, vdimas, Вы писали:
V>>>Дык, именно в этом соль. AVK>>Соль в том, что ты неверно трактуешь понятие чистоты функции, не смотря на довольно простое и однозначное определение.
V>Потому что не в этом определении соль
Нет, соль именно в нем. И вся математика ФЯ посторена с учетом свойств чистых функций. Если не считать определение чистоты важным, разговор о ФП лишен смысла.
V>, а в том, что само простое определение опирается на определение побочного эффекта, а вот оно уже вызывает постоянные споры.
Это оно только у тебя вызывает споры.
V>чистая ф-ия -> порядок вычисления аргументов не важен, так?
Что такое "вычисление аргументов"?
V>То бишь юмор был в том, что программа на Хаскеле, составленная из чистых ф-ий, на самом деле НЕ МОЖЕТ быть выполнена в чистой манере.
Что такое "выполнена в чистой манере"? И какая связь между этим загадочным термином и происхождением ФП от структурного?
AVK>>Порядок вычислений в семантику чистого Ф-кода не входит, в отличие от императивного. V>Для Хаскеля именно что входит.
Как из этого следует развитие ФП из структурного?
... << RSDN@Home 1.2.0 alpha 5 rev. 61 on Windows 7 6.1.7601.65536>>
Здравствуйте, DarkGray, Вы писали:
AVK>>Что такое атомарный api и как он должен выглядеть?
DG>Фактически — это то, как ты сейчас для себя определяешь правильный дизайн системы.
Как я его определяю? Ты хоть на один вопрос можешь прямо ответить?
DG>Надеюсь мы друг друга поняли, и можно не расписывать это детально.
Зря надеешся, я тебя почти не понимаю, потому что вместо четких и ясных ответов на конкретные вопросы получаю какое то малопонятное философствование.
AVK>>Зачем? И с какой стати ты решил, что в понятийной модели пользователя хозоперация является частью кредитного счета? DG>потому что для меня как для руководителя, знающего фин. менеджмент — каждая операция тесно связана с каким-то из счетов в момент совершения.
Ну вот, опять. Этот ответ логически равноценен ответу "потому что я так хочу". Ты, как руководитель, знающий финансовый менеджмент, можешь привести конкретный юзкейс, когда в бухгалтерии нужно переходить от кредитного счета к созданию хозоперации? Если да — юзкейс в студию. Если нет — о чем мы тогда говорим?
AVK>>Что такое CLI?
DG>command-line interface, командная строка
Пользователь, работающий с бухгалтерской системой через командную строку? Можно название продукта?
DG>>> и скриптами AVK>>Пользователю со скриптами? Ты ничего не перепутал?
DG>Конечно, любой сотрудник с высшим образованием должен уметь (или как минимум должен способен научиться) автоматизировать свою работу, в том числе с помощью скриптов. Иначе непонятно за что ему выдали диплом о высшем образовании..
Можно название продукта, позволяющего обычному пользователю-бухгалтеру писать свои скрипты? 1С, если что, не позволяет.
AVK>>Пользователю разговаривать напрямую с программистами? Все страньше и страньше.
DG>Всё тот же вопрос: зачем мне как руководителю платить деньги еще кому-то за испорченный телефон, если эффективнее напрямую соединить пользователя и программиста?
Затем что бизнес-аналитик, это не испорченный телефон, это специальный, очень важный человек, который, с одной стороны, досконально знает предметную область и реальные потребности клиентов, а с другой, в отличие от клиентов, понимает как формализовать требования.
DG>Или зачем мне держать программиста который не может поговорить с пользователем
Т.е. ты предполагешь, что программист будет ходить по предприятию, общаться с заказчиками и не вылазить из командировок? Или ты рассматриваешь исключительно ситуацию внутренней автоматизации илир конторы с меньше чем десятком заказчиков?
DG>>>В идеале — объектная оболочка строится автоматически, требуя минимальных трудозатрат. AVK>>Ух ты. Автоматически на основании чего? И зачем какая то оболочка, не привносящая в систему новой информации?
DG>Потому что способности человека по комбинированию и запоминанию информации сильно ограничены, в отличии — от компьютера.
Пример в студию.
DG>Соответственно, такая объектная оболочка — уменьшает временные затраты человека за счет того, что все необходимые данные для конкретной операции собраны вместе, а также благодаря тому — что большинство настроек выставлены автоматически на основе лучших рекомендаций от лучших консультантов. И соответственно, человек вводит только ту информацию и принимает только те решения, которые действительно необходимы в этот момент.
Пример в студию.
AVK>>Продемонстрируй. Пока что я вижу только лозунги, что все круто и никакой конкретики.
DG>каким образом тебе это можно продемонстрировать?
Примером.
AVK>>Начни с описания одной подобной задачи. Реальной, а не "сижу, примус починяючеки разбираю". Потому что если реальной задачи нет — все это превращается в очередной бредогенератор типа ветки про открывание двери.
DG>1. На основе данных за год из учетных систем (бухгалтерской и тайм-менеджмента) выдать рекомендации, что выгоднее: заключить контракт (и по какому тарифу?) на курьерское обслуживание с компанией "Скороход" или выгоднее продолжать в качестве курьера гонять Смирнова из отдела продаж и доплачивать ему за бензин?
Где там нужна возможность создания хозоперации по кредитному счету?
DG>2. Заказчик прочухался и шандарахнул на счет сразу куча бабла. Получить рекомендации от бух. системы, как эти деньги лучше дальше распределить и оформить, чтобы минимизировать расходы на налоги и минимизировать "заморозку" денег.
Где там нужна возможность создания хозоперации по кредитному счету?
DG>3. На основе данных из учетных систем посчитать норму прибыли для каждого сотрудника за последний год, и сравнить ее с нормой прибыли сотрудников в других компаниях из той же отрасли.
Где там нужна возможность создания хозоперации по кредитному счету?
... << RSDN@Home 1.2.0 alpha 5 rev. 61 on Windows 7 6.1.7601.65536>>
Здравствуйте, DarkGray, Вы писали:
AVK>>Что то я окончательно перестал тебя понимать. Ты предлагаешь отказаться от статической типизации или завести на каждого Иванова отдельное свойство в объекте предприятия?
DG>1. автоматически завести отдельное свойство в объекте орг. структуры предприятия
И перекомпилировать при каждом изменении?
DG>2. статически проверять валидность операций
Каких операций? Как проверять? Кому проверять?
AVK>>Но я так и не получил от тебя ответов на кучу заданных вопросов. Я правильно понимаю, что для ввода первички и формирования хозопераций объект Счет все таки не нужен?
DG>Необходимо сначала договориться о терминах: что такое первичка, и что такое счет?
И?
DG>Также для меня Иванов.Начисленный_Доход, Иванов.Отработанные_Дни, Иванов.Расходы_из_его_собственных_средств — это тоже Счета, но уже больше в парадигме финансового и управленческого учета.
Слова все знакомые, а смысл полностью ускользает.
DG>>>поэтому я и утверждаю, что пример ужасный, не смотря на то, что он реальный AVK>>Приведи другой реальный, но не ужасный.
DG>Я его привел:
Где скриншот формы? Я что то не приметил.
DG>1. сначала начисляем Иванову зарплату на основании трудового договора и табеля об отработанных днях DG>2. затем закрываем обязательства перед Ивановым в размере 20тыс. рублей
Вот ты даже не понял. Иванов в видео, это не кому зарплату начисляют, это получатель денег из кассы. Там оснований может быть вагон и маленькая тележка. Для реальной выдачи зарплаты вообще бухгалтерия не используется, есть специальный программный продукт, Зарплата, и там есть специальный документ на выдачу зарплаты, зарплатная ведомость, которая формируется автоматически. В бухгалтерии же либо импортируют это все из зарплаты, либо вообще формируют на всю зарплату подразделения один расходник, и в таком случае Иванов это работник, выдающий зарплату.
"Иванов.Начисленный_Доход, Иванов.Отработанные_Дни, Иванов.Расходы_из_его_собственных_средств" — вообще ни в каком известно мне сценарии не нужны, потому что все зарплатные операции групповые, минимум по подразделению.
DG>хочется видеть как это делается в парусе: как через Gui (в виде скринкаста), так и через CLI или скрипт (в виде примера кода).
Это другой продукт, и он только в декабре релизится, так что никаких скринкастов нет. И никакого доступного коммандлайна для пользователя тоже нет. Но во всех зарплатах, что я видел, это делается примерно так:
Начисление:
foreach (var empl in Empls.Select(...))
{
CalculateIncome(empl);
CalculateTaxes(empl);
}
Выдача зарплаты
var payList = new PayList();
foreach (var empl in Empls.Select(...))
{
var salary = GetSalary(empl, date);
if (salary > 0)
payList.Add(empl, salary);
}
AVK>>Я не знаю что ты так уцепился за финансовый менеджмент и анализ, но на практике с ним тоже никаких проблем нет.
DG>потому что для меня как для руководителя — фин.менеджмент — это первично, а бух. учет в разрезе кодов КБК — это вторично
Если ты руководитель, тебя вообще не должны колыхать внутрипрограммные модели. Ты получаешь готовый продукт и документацию к нему, а не конструктор "напрограммируй чего нибудь через командную строку". А теперь давай вернемся к программистам, только для которых software architect и разрабатывает дизайн.
... << RSDN@Home 1.2.0 alpha 5 rev. 61 on Windows 7 6.1.7601.65536>>
DG>>1. автоматически завести отдельное свойство в объекте орг. структуры предприятия
AVK>И перекомпилировать при каждом изменении?
да. инкрементальные компиляторы уже давно не редкость.
DG>>2. статически проверять валидность операций
AVK>Каких операций? Как проверять? Кому проверять?
Для всех операций проверять (до выполнения самой операции):
соответствие идентификаторов справочникам и реестрам,
соответствие свойств друг другу: если Иванов в июне в отпуске, то нельзя в июне выпускать документы от его имени.
AVK>>>Но я так и не получил от тебя ответов на кучу заданных вопросов. Я правильно понимаю, что для ввода первички и формирования хозопераций объект Счет все таки не нужен?
DG>>Необходимо сначала договориться о терминах: что такое первичка, и что такое счет?
AVK>Очень странные вопросы ты задаешь. А ведь только что упрекал в некомпетентности. Это базовые термины.
Как минимум необходимо тогда добавлять, что это бухучет по-российски, что к реальному бухучету имеет отдаленное отношение, и тем более имеет слабое отношение к фин. анализу, которые тем не менее строится поверх бухгалтерского учета.
Принципиальное различие российской и американской учетных систем можно заметить сразу, как только мы чуть более внимательно присмотримся к их определению. В общепризнанном американском определении финансового учета говорится, что “Финансовый учет — процесс, заканчивающийся приготовлением финансовой отчетности относительно предприятия в целом, которая используется как внешними, так и внутренними пользователями... Эта отчетность обеспечивает последовательную и непрерывную выраженную в денежном измерении историю экономических ресурсов и обязательств предприятия и экономической деятельности, которая изменяет эти ресурсы или обязательства”. Определение же бухгалтерского учета по российской традиции несколько отличается: “Бухгалтерский учет — это система наблюдения, измерения, регистрации, обработки и передачи информации в стоимостной оценке об имуществе, источниках его формирования (обязательствах), и хозяйственных операциях хозяйствующего субъекта (юридического лица)”.
Основное различие можно выделить в том, на что обращено основное внимание определяющего. В первом случае, учет — это процесс, приводящий к результату (финансовой отчетности), правильное представление которого и является целью учета. Основным является не сам процесс, а именно результат. Во втором случае учет рассматривается как система, которая существует ради самого процесса.
Цели учета в России и США достаточно сильно различаются. Если выделять главное требование, предъявляемое к отчетности, то можно сказать, что если в США главное требование — разумность и полезность информации для принятия пользователем коммерческих решений, то в России главное требование — соблюдение различных правил ведения учета, предоставление формально правильной информации контрольного характера
тут тоже сразу стоило тебе добавить, что и понятие "первичный документ" и "бух.счет" ты понимаешь в узком жестком смысле, как это зафиксировано в России бюджетными контролирующими органами.
Какое это отношение имеет к реальным "первичным документам" и "бух. счетам" — это вопрос отдельного рассмотрения..
AVK> Но во всех зарплатах, что я видел, это делается примерно так:
при этом сразу появился и объект для каждого сотрудника, и императивщина.
AVK>Ну вот, опять. Этот ответ логически равноценен ответу "потому что я так хочу". Ты, как руководитель, знающий финансовый менеджмент, можешь привести конкретный юзкейс, когда в бухгалтерии нужно переходить от кредитного счета к созданию хозоперации?
Здравствуйте, DarkGray, Вы писали:
AVK>>Ну вот, опять. Этот ответ логически равноценен ответу "потому что я так хочу". Ты, как руководитель, знающий финансовый менеджмент, можешь привести конкретный юзкейс, когда в бухгалтерии нужно переходить от кредитного счета к созданию хозоперации?
DG>погасить долг перед контр-агентом Zzz
И зачем там бухгалтерский счет?
... << RSDN@Home 1.2.0 alpha 5 rev. 61 on Windows 7 6.1.7601.65536>>
Здравствуйте, DarkGray, Вы писали:
AVK>>И перекомпилировать при каждом изменении?
DG>да.
Собственно, дальше уже стало совсем не интересно. Твои рассказы ничего общего с реальными системами не имеют.
AVK>>Каких операций? Как проверять? Кому проверять?
DG>Для всех операций проверять (до выполнения самой операции): DG>соответствие идентификаторов справочникам и реестрам,
Жесть то какая. Т.е. код пишется ровно под одно единственное предприятие? Так о какой, все таки, системе идет речь? Открой уже секрет, жутко интересно где при добавлении записи в справочник физлиц происходит кодогенерация и полная перекомпиляция прикладного кода.
DG>Принципиальное различие российской и американской учетных систем
Ну то есть вся проблема в российских стандартах бухучета? Именно они не позволяют правильный ОО дизайн использовать? Жжешь.
DG>тут тоже сразу стоило тебе добавить, что и понятие "первичный документ" и "бух.счет" ты понимаешь в узком жестком смысле, как это зафиксировано в России бюджетными контролирующими органами.
Ты уже забыл с чего эта нитка началась? С Re[24]: хихи
— и именно там я явно сказал о каком именно счете идет речь.
Ну да бог с ним. Я так понимаю, что ты согласен с тем, что для систем бухучета, рассчитанных на стандарты РФ, твой дизайн не годен?
DG>Какое это отношение имеет к реальным "первичным документам" и "бух. счетам" — это вопрос отдельного рассмотрения..
Ну да, переключение разговора на спор о терминах очень удобно. Мы ведь не проблемы дизайна ПО обсуждаем, а особенности американского бухучета.
AVK>> Но во всех зарплатах, что я видел, это делается примерно так: DG>при этом сразу появился и объект для каждого сотрудника, и императивщина.
Объект в ОО дизайне для сотрудника будет в любом случае, в том числе и в твоих примерах кода он есть. Если без объекта, то это будет другая модель. Отсутствие императивщины тоже вроде бы никто не обещал. Да и твои примеры ее отсутствием не страдают. Но может вернемся к теме? Где в этом коде вдруг понадобится объект Счет или специальное статически контроллируемое свойство для каждой записи в справочнике физлиц.
... << RSDN@Home 1.2.0 alpha 5 rev. 61 on Windows 7 6.1.7601.65536>>
Здравствуйте, Sinclair, Вы писали:
S>>>Смотрите, в чём затык: для вывода баланса на экран придётся построить новый счёт и попросить данные у него: S>>>
S>>>BalanceLabel.Text = (new Account("03")).CalcCurrentBalance().ToString();
S>>>
SV.>>Нет, поскольку где ж вы возьмете идентификатор? Вообще, идентификатор сугубо служебен и снаружи вам не виден. S>Как это "не виден"? Да он в плане счетов написан крупным шрифтом. То, что вы дали счёту какой-то внутренний служебный идентификатор — ваше личное решение; нужды в нём никакой нет.
После таких слов Лука Пачоли в гробу перевернулся.
Ваш план счетов — это один-единственный аспект, отчетный. А вы на основе его идентификаторов делаете уникальные ключи, хотя это всего лишь внешние атрибуты (и то, не факт, что прямые, очень может быть, что вычисляемые).
Во-первых, план счетов — хронотопический стандарт, он действует на территории отдельного государства, и его средняя продолжительность жизни — пять лет. По уму, место его — в справочнике. Чтобы любое количество реальных счетов можно было отнести на счет из текущего плана, а исчезновение из плана идентификаторов не приводило к необходимости переоткрывать счета. Если подумать, из счета даже ссылаться на справочник текущего плана напрямую нельзя. Нужно делать промежуточную таблицу с историей ссылок.
Во-вторых, план счетов — внешний по отношению к организации стандарт. Есть ведь и другие аспекты помимо налогово-отчетных. В реальной организации на один внешний счет, включенный в отчет, может приходиться 10 внутренних, которые вообще в вышеупомянутом аспекте не видны.
Тут ниже кто-то остроумно написал, что банковский счет это одно, а бухгалтерский — другое. Когда для банков изобретут одни деньги, а для налоговой — другие, тогда это станет правдой. Но не раньше.
Короче, тут не прокладку менять, то есть ООП обсуждать, тут всю систему менять надо. Бухгалтерия — это план счетов, оказывается. Зашибись.
SV.>>Да, хотел дописать почти теми же словами, но решил, что и так понятно. Это некий шорткат, который можно реализовать по-разному (хоть бы и дефолтным значением параметра). S>Это — плохой способ. Вы прячете ту функциональность, которая должна быть на виду.
"Это" — это что? Сделать шорткат от Current'а на Date.Now?
SV.>>Зрение бывает у дизайнера, а не у дизайна. Как и точка, откуда дизайнер зрит. Это так, к слову. S>Ну давайте не будем
А почему не будем? Очень даже будем. Дизайн — он безответный, и, прикрываясь его интересами (которых у него нет), можно что угодно запроектировать. Вы ровно это и делаете. Берете произвольное решение, которое нравится вам ("надо его выносить наружу"), и пишете "с точки зрения правильного дизайна". Пойди поспорь. Или надо соглашаться, или начнется совершенно идиотский спор "какой дизайн трушнее". Который закончится взаимным посыланием нафиг и тем, что каждый останется при своем мнении.
Я предлагаю совершенно иной подход — обратить свое внимание на людей, которые будут пользоваться плодами вашей архитектуры. Я с этого начал тему (кто забыл может еще раз прочитать заглавное сообщение) и от нее уходить не собираюсь. Надо каждый раз представлять себе Васю, вчерашнего студента, который пришел на ваш проект, имея представление о счете, как о чем-то с номером, на котором деньги лежат. Зато он знает jQuery и бог в веб-интерфейсах.
Например, Васе поставили задачу — "построение таблицы [счет]-[текущий баланс]". Если вы опять напишете про своих теток, которые паразитируют на реальном труде, приводя сведения о реальном бизнесе в соотетствие с порождением советского Госплана (а откуда же еще высрались эти планы счетов?), которым такая таблица не нужна, не надо, пожалуйста. Мир не крутится вокруг СССР. У других, знаете, тоже бывает бухгалтерия, в которой баланс счета — сумма проводок, а не состояние.
Так вот, выше я предложил сделать шорткат на основе дефолтного параметра. Что вы изволили назвать плохим решением. Видимо, с точки зрения "Правильного Дизайна", который вы тут представляете на манер Лебедева. С точки зрения не Дизайна, а Васи, у него есть объект acc, у которого можно нажать точку и посмотреть, что будет. Вывалится список методов, среди которых не будет никакого CurrentBalance. А будет CalcBalance(Date forDate = Date.Now). Вася, НЕ ЧИТАЯ ДОКУМЕНТАЦИИ, НЕ ИЗУЧАЯ БУХГАЛТЕРИЮ, приобретет новое знание — что баланс счета есть функция от даты и текущий баланс лишь частный случай. При этом Вася останется в блаженном неведении о проводках. Пока что. Пока он находится в рамках своей задачи.
Теперь заменим Васю на Sinclair'а. Он, конечно, сразу решит, что CalcBalance сводит дебит с кредитом по записям в БД о проводках. И ошибется. Поскольку фабрика на запрос с идентификатором из плана счетов вернет ему сложную реализацию, делегирующую собственно суммирование по проводкам более простым реализациям, сидящим на базе. А сама она будет отбирать реальные счета, отнесенные на интересующий его счет из плана. И суммировать их. А он об этом даже не узнает. Не узнает о том, что система различает реальные счета, и счета из плана. Пока что. Пока он находится в рамках своей задачи. Такой вот фокус-покус.
Дальше начинается самое интересное. По мере того, как они будут получать новые задачи и решать их, они будут углубляться в объектную модель. Sinclair увидит, что не все счета базируются на проводках. Вася увидит, что CalcBalance() возвращает не Decimal, а Money. У которого есть члены Amount и Currency. И Вася сразу поймет, что он не в шарашкиной палатке работает, а в международной палатке, и счета тут мультивалютные. Следовательно, решит он, должен быть и способ задать интересующую его валюту. Валюту-то он задаст, а получать баланс все равно будет в рублях. И вот Вася задается осмысленным вопросом (НЕ ЧИТАЯ ДОКУМЕНТАЦИИ! НЕ ИЗУЧАЯ БУХГАЛТЕРИЮ В КОНКРЕТНО ВЗЯТОМ ПРЕДПРИЯТИИ!!): почему я передаю в CalcBalance Currency.USD, а мне все приходят наши, деревянные? А если архитектор еще подумает, "No connection to Forex" — ответит Васе на его вопрос исключение.
Резюмируя, ООП решает такие задачи, которые Sinclair перед собой даже не ставит. И автор вопроса о наследовании интерфейсов, мой воображаемый друг, тоже не ставит. Им не нужен Вася, который через полчаса начнет писать код, как будто он всю жизнь работал на проекте. Первый заставит Васю разбираться во всех тонкостях плана (сам не понимая, что план — аспект, как он это показал выше). Второй нахерачит констрейнтов, чтобы Васе жизнь медом не казалась. Разумеется, нахрена им после этого ООП. И так же все работает.
SV.>>С какой точки зрите вы, я не знаю. Мой поинт в том, чтобы сложность разложить по полочкам. Поставьте себя на место гуёвого программиста, которому дела нет до идентификаторов и базы. Зато у него на входе есть счет, который сводит дебит с кредитом по запросу. И полученный таким образом результат можно запихать в форму и отдать операционисту. S>Я не понимаю вашу терминологию. Вы придумали какое-то решение и хотите общаться только в рамках него? S>Ну, а я вижу это совершенно по-другому. Конечно же у гуёвого программиста на входе есть исключительно идентификатор. Потому, что ему приехал запрос .../ShowAccountTransactionHistory.aspx?Acc=78.01 S>И теперь ему из этого номера счёта нужно получить всю нужную по ТЗ информацию. Либо ему надо заниматься порождением нафиг ненужной объектной модели, либо можно скормить этот параметр в метод хелперного объекта AccountingService и получить всё, что нужно.
Гуёвый программист не занимается порождением объектной модели. Он отдает 78.01 в метод хелперного объекта AccountingService, и получает объект Account, который можно изучать через IDE. Оба они, AccountingService и Account, а также все реализации Account, описанные выше, являются частью объектной модели, создавать которую (и упаковывая реализацию в которую) дело архитектора.
SV.>>Это зависит от точки зрения дизайнера на responsibility. Если у вас есть дополнительные требования к работе с БД (допустим, поддержка в качестве БД чего угодно, в том числе NoSQL) — ну, введем посредника, который будет делать выборки и другие реляционные операции по чему ему скажут (а Account ему скажет — по проводкам). Если нет — ради бога, прячьте сиквел в реализацию, получите быстрособранную систему, которая жестко завяжется на структуру таблиц. И то, и другое будет понятной объектной моделью, но с разными достоинствами и недостатками в других областях. S>Это будет нарушением SRP.
Вы не читаете, что ли? Я же сказал: это зависит от точки зрения дизайнера на responsibility. Если думать о responsibility в терминах "функциональность по расчёту баланса", "функциональность по работе с базой" — тогда да, это нарушение SRP. Если считать responsibility этого класса "предоставить Васе доступ к балансам", тогда нет. Вот когда Account начнет заодно курсы валют возвращать, тогда это будет нарушение SRP.
Еще раз. Вы просто не ставите такой задачи, которую решает ООП, допустим, в том же самом MS ShP.
Здравствуйте, Wolverrum, Вы писали:
S>>Это будет нарушением SRP. W>И чо? W>Индусы код не поймут? W>Система работать не будет? W>Цена поддержки многократно вырастет? W>Чувству прекрасного будет нанесен невосполнимый урон?
Как сказал один журналист, то, что одному — статья 134 УК РФ, другому — большая и чистая любовь. То есть, это всё конкретные правовые системы, в то время как преступление — понятие межсистемное.
Так же и здесь. Нарушение SRP обычно очень плохо, вне зависимости от подхода к проектированию. Если вы сами видите, что нарушаете SRP, надо исправлять. Другое дело, что один и тот же класс может нарушать SRP или нет, в зависимости от того, что считать его ответственностью.
Почему нарушение SRP очень плохо? С моей точки зрения, потому, что Васе такую систему понять труднее. Или Раманатану, в контексте вашего вопроса. Например, когда один и тот же класс возвращает балансы счета и курсы валют, это неочевидное для Раманатана поведение. Что бы там не говорили об индусах. Даже если они такое пишут, читать такое они обламываются.
Почему плохо, когда один класс суммирует проводки в базе по идентификатору, это спрашивайте у того, кто так утверждает.
S>>То получится так называемая Anemic Model, в которой логика написана так, что её легко понять и отладить, без попыток сделать "чёрными ящиками" сущности, лишённые тонкостей внутренней структуры. W>Выделенное плохо? W>Подчеркнутое обязательно?
Подчеркнутое не то, чтобы не обязательно, это просто неправда. У счета может быть такая тонкая структура, как агрегатор других счетов согласно плану (циркуляру, спущенному Минфином, между нами говоря — исключительно в его, минфиновских, целях). ООП же нужен для того, чтобы Sinclair и дальше продолжал думать, что у счета нет никакой тонкой структуры.
>>anemic model: >>"Logic cannot be implemented in a truly object-oriented way"
W>Какая невосполнимая потеря
Я бы сказал, вот что бывает, когда думаешь о Дизайне с большой буквы Ъ, а реальных людей (Васи и Раманатана) в упор не замечаешь.
Здравствуйте, Sinclair, Вы писали:
SV.>>А хранение и вычисление где будут реализованы? S>В операциях, заданных над этим ADT. Для этого нет необходимости в ООП.
...на мосту мочало, начинай все сначала. Вот ниже вы пишете Wolverrum'у:
С точки зрения функциональных требований все парадигмы совершенно одинаковы — см. тезис Чёрча. То есть в принципе нет такой программы, которую можно было бы написать на ФП, но нельзя на ООП — как и наоборот.
Отличия — только в нефункциональных требованиях. Например, в том, сколько стоит отладка (т.е. доказательство корректности, хотя бы и нестрогое) и внесение изменений. Или в том, насколько эффективный код получается в результате.
Ну так вот понятность кода напрямую влияет на стоимость его поддержки.
Возможность изолировать эффекты локальных изменений — тоже.
Именно ради неё Кей вводил эти "чёрные ящики", а не потому, что они как-то особенно подходят к устройству мозга.
Если вы в самом деле это понимаете, как у вас рука поворачивается написать: "Для этого нет необходимости в ООП"? Да, для этого нет необходимости в ООП. ЕЕ ВООБЩЕ НИКОГДА НЕТ. БЕЗ ООП ВСЕГДА МОЖНО ОБОЙТИСЬ. ОНО ОБХОДИМО.
Покажите, где и как будут реализованы хранение и вычисление, чтобы мы могли сравнить стоимость отладки. Нет, не кода, который хранит и вычисляет, а кода, который будет написан для расчета линейных уравнений на его основе. И не надо писать "в операциях, заданных над этим ADT". Это не значит НИЧЕГО. Конкретизируйте. Я, если угодно, сделаю то же для ООП. Не сделал только потому, что верю, что все и так представляют, как это будет выглядеть.
Здравствуйте, grosborn, Вы писали:
>> G>Интерфейс должен описывать отсылку сообщения, а сообщение может поддерживать разные форматы. >> >> Нет, это не тот ООП, который выбираем мы. Когда вы пишете в скайп, вы всегда отправляете абстрактное сообщение, частным случаем которого является текст или файл? Вы в самом деле так мыслите? Или вы все же отправляете тексты и файлы?
G>Писать хороший код, это как раз не делать как мыслить или моделировать реальность, а использовать соответствующие правильные методики для решения конкретных задач, опробованные и одобренные. G>Вот как я понял, этот пример кода это написано как "автор мыслил", то есть в стиле ООПГМ. И мне сразу видно, что код неправильный, неоптимальный. В моем замечании я исходил из опыта, как такие задачи решаются в типовых случаях — сообщение поддерживающее разные форматы данных. G>Ведь задача программиста не смоделировать реальность, а кратчайшим путем решить поставленную задачу, с учетом некоторых требований и условий. G>Может быть в ООПГМ и есть свои преимущества, но приведенный пример их никак не продемонстрировал, понятности коду не добавил.
К счастью, авторы Skype'а до такого бреда не додумались ни на уровне протокола, ни на уровне объектной модели. У них есть чат, есть файлтрансферт. Сообщения, частным случаем которого является текст или файл, у них нет. А вашей объектной моделью пусть мои враги пользуются.
Здравствуйте, elmal, Вы писали:
E>Ладно. Другой пример. В проекте все данные хранятся в DTO. Пришел запрос с клиента, этот запрос десериализуется в DTO и путем цепочек преобразований попадает частично в локальный кеш, частично уходит через вебсервисы на сторону. DTO никаких зависимостей на другие классы не содержит, и если там есть логика, то тривиальная. E>Запросы идут параллельно много, преобразования тоже идут параллельно. Да, проект представляет собой набор классов, и даже в некоторых случаев наследование там, вот только эти классы все stateless, существуют в единственном экземпляре и хоть и имеет приватные проперти, но они все инициализируются фреймворком, упрощающим dependency injection. SOLID, кстати, в основном соблюдается. Это считаем ОО подходом или нет? Учитывая что объекты не хранят состояния, и если б не были нужны фичи вроде АОП и удобного тестирования, то вообще б по существу там были б сплошные статические методы.
> К счастью, авторы Skype'а до такого бреда не додумались ни на уровне протокола, ни на уровне объектной модели. У них есть чат, есть файлтрансферт. Сообщения, частным случаем которого является текст или файл, у них нет. А вашей объектной моделью пусть мои враги пользуются.
И тут мы вдруг понимаем, что ты обсуждаешь то в чем не имеешь ни малейшего опыта. Предположить, что содержимое файла упаковывается в сообщение, мог только абсолютно не разбирающийся в теме человек.
Здравствуйте, grosborn, Вы писали:
>> К счастью, авторы Skype'а до такого бреда не додумались ни на уровне протокола, ни на уровне объектной модели. У них есть чат, есть файлтрансферт. Сообщения, частным случаем которого является текст или файл, у них нет. А вашей объектной моделью пусть мои враги пользуются.
G>И тут мы вдруг понимаем, что ты обсуждаешь то в чем не имеешь ни малейшего опыта. Предположить, что содержимое файла упаковывается в сообщение, мог только абсолютно не разбирающийся в теме человек.
Называется, "сначала я пишу так, что не понять, потом злобно кусаюсь, когда меня пытаются понять и не понимают" (кстати, не факт, что не понимают — упаковка это ваши домыслы, приписанные мне). Дискурс а-ля рюс. Когда меня не понимают (пример ниже, где мой вопрос не понимает Sinclair), я же не быкую, а переписываю другими словами.
К вопросу об опыте. Каких только экземпляров для кунсткамеры я не повидал в реальных проектах! Сообщение для скайпа на их фоне — семечки.
Ладно, вернемся к теме. Вот ваши слова:
>Интерфейс должен описывать отсылку сообщения, а сообщение может поддерживать разные форматы.
Что сие значит? Напишите так, чтобы исключить домыслы.
> Ладно, вернемся к теме. Вот ваши слова: > >>Интерфейс должен описывать отсылку сообщения, а сообщение может поддерживать разные форматы. > > Что сие значит? Напишите так, чтобы исключить домыслы.
Что тут непонятного? Обсуждаемый интерфейс, тот пример, является интерфейсом транспортного уровня, ибо для предметного он вообще непригоден, ибо сообщение это НЕ только текст или только файл. И для транспортного уровня он тоже неграмотен, ибо на транспортном уровне содержимое сообщения для интерфейса должно быть абстракцией. Выбор же послать с использованием протокола коротких сообщений или протокола передачи файлов должен осуществляться в зависимости от объема передаваемых данных. То есть грубо говоря небольшие файлы будут отосланы по протоколу коротких сообщений. И вообще, на транспортном уровне не должно быть метода .ПослатьФайл(), ибо файлы вообще-то в отличие от реального мира не передаются, а скачиваются по запросам принимающей стороны после разбора сообщения о передаче файла и если на принимающей стороне вообще разрешено принимать файлы.
S>видишь ли, под пунктом 2 управляющая структура, которая выполняет подпрограммы. хаскель-if их не выполняет, а лишь выбирает ветку. У нас есть гарантия что выбранная ветка будет вычислена хоть когда-нибудь?
Я так и знал. )))
Молодца, ты попался на тривиальный очевидный момент. Потому что поторопимшись. Давай ты напишешь пример, где предикат при if ОБЯЗАТЕЛЬНО вычисляется, но не будет вычислена возвращаемая if ветка. Ты увидишь кое-что важное, когда наконец сможешь этот пример породить. Что именно? А достаточно будет сравнить полученный вариант с вариантом работы некоего вычислителя на энергичной технике и попробовать найти отличия в семантике. Будет тоже самое, что в энергичной технике исполнения, близкой к императивному способу вычислений. Просто ты упускаешь тот момент, что семантика ленивого и энергичного вычисления должна сохраняться идентичной, а в энергичной семантике предикат при if ОБЯЗАН быть вычисленным раньше любой ветки... иначе у тебя банальная ф-ия вычисления факториала может уйти в вечную рекурсию по ложным веткам.
Так что ваш аргумент, по-сути, о том, что ф-ия if, как и все остальные ф-ии Хаскеля — ленивые. Это был, конечно, очень крутой и правильный аргумент. Только ни о чем, бо он сугубо о семантике низлежащего вычислителя. Т.е. ты имеешь полное право писать свои чистые ф-ии вовсе не заботясь о низлежащей семантике вычислителя. Где-то так...
S>По другим пунктам тоже можно поглядеть. S>1. — сиквенсинг в хаскеле нужен лишь для организации побочных эффектов. Никакое вычисление в нем не нуждается.
Я таки вижу, что именно само вычисление раскладывают на шаги: сначала задают промежуточные данные (let var=...), потом из них — конечные (in expr). Опять и снова, тот факт что вычисление производится в ленивой манере — ненужные подробности. Теперь найди отличия в описании шагов таких вычислений от описаний точно таких же шагов, записанных в императивном языке (порой с точностью до синтаксиса в compile-time и конечного кода в runtime). Другая модель? Хмм... арифметика, она и в Африке арифметика, как раз на арифметике можно абстрагироваться от любых низлежащих моделей вычислетелей.
S>А Бём-Якопини говорили именно о вычислении функций. Вобщем первый пункт пролетает.
Ну, если подходить догматически, расставить рамки и т.д. то пролететь может что угодно. А если рассматривать лямда-исчисление только как входные описания для некоего вычислителя на машине Тьюринга (а оно так и есть) — то я имею право искать похожие механизмы. ИМХО, ветвление и разложение сложных вычислений на более простые шаги — это фундаментальные практики, и там и там.
S>3. Выполнение подпрограммы пока ...уже бессмыслица в хаскеле, т.к. подпрограмма это выражение, которое сколько не выполняй, результат будет тот же самый ... пока булево выражение является true — тоже бессмысленно, т.к. в хаскеле выражение чему равно, тому и равно, сколько его не вычисляй, и выполнение подпрограммы на результат выражения не влияет.
Цикл — это повтор одного и того же кода. И ты тут пытаешься манипулировать, бо результат подпрограммы будет один и тот же только при одних и тех же входных данных. А если входные аргументы на каждом шаге цикла разные, то и результат будет разный. Почему-то комбинатор неподвижной точки так и называют — циклом или рекурсией, а вы тут упрямитесь? ))
S>В итоге, все 3 пункта не о хаскеле.
Да ради бога. Мне просто опять прикольно как ты скачешь с теории на сугубо подробности (ленивое выполнение в случае if) и потом обратно. Эдак даже не получается ровненько провести границы догм, приходится бегать подправлять?
V>>Это явное переключение потока исполнения. И ты мне так и не показал принципиальное отличие от императива для такого случая применения if. ИМХО, там всей разницы, что в императиве мы переводим стрелки непосредственно перед поездом, а в Хаскеле — немного раньше, а поезд пускаем затем по уже сформированному пути. Но кроме бла-бла я так и не услышал от тебя внятных пояснений, почему ты эти два сценария считаешь принципиально различными? Сможешь без юления четко сформулировать свою мысль? S>выше две мысли. Одна — if не выполняет ветки, вторая — (*)побочные эффекты не влияют на вычислимость функций, о которой писали авторы теоремы.
S>Если ты хочешь притянуть за уши ФП к СП, то тебе придется обойтись без IO. Потому что (*). А так же потому что имея IO, мы можем на ФП спародировать любую императивную программу. Но ведь ФП Тьюринг-полна вовсе не потому что IO, так ведь?
Ес-но, она Тьюринг-полна, потому что может быть исполнено на конечном вычислителе, который ВЫНУЖДЕН аргументы некоторых ф-ий считать в определенном порядке.
На самом деле вы тут фигней маетесь, но мне было лень расписывать, думая, что вы и так знать должны. Само использование сочетания комбинаторов I/K таково, что упорядочивание происходит как упорядочивание вызовов ф-ий I(K/KI?(x,y)), то бишь происходит такое же упорядочивание как на монаде IO, технически реализуемое как вложение вызовов ф-ий друг в друга. То бишь, даже если в синтаксисе выражения if-then-else все аргументы выглядят как аргументы одного уровня иерархии вычислений, на самом деле одни из них вкладываются в низлежащие вызовы, при росписи этого дела на комбинаторах. И хорошо видно, что для того, чтобы раскрыть цепочку комбинаторов, СНАЧАЛА надо определиться с составом самой этой цепочки (K/KI?), то бишь с аргументом при if — true или false, иначе дальнейшие комбинаторные преобразования в конечный исполняемый код будут невозможны. Я так-то не собирался грузить всей этой догматической чепухой, полагая очевидным здравому смыслу, что аргумент при if, если он вычисляется, он вычисляется всегда РАНЬШЕ нужной ветки (даже если ветка не вычисляется вовсе затем), т.е. считал, что такое де-факто упорядочивание очевидно здравому смыслу в любой технике исполнения ФП, что в энергичной, что в ленивой.
Здравствуйте, Ikemefula, Вы писали:
V>>Зато использование IList в коде сжирает любой предполагаемый профит. А что надо делать с иммутабельностью — я тебе уже говорил там, где скипаешь неудобные аргументы. IList по дизайну нифига не иммутабельный.
I>Не любой, он только инлайниться не будет,
А вообще по опыту вылизывания критического кода до микросекунд — разница м/у использованием List<> и IList<> в коде от 3-х до ~10-ти раз (от стоимости тела цикла зависит). В первом случае итератор будет представлен в бинарнике значением регистра, а во втором — будут два честных виртуальных вызова на каждом шаге.
I>зато этот интерфейс поддерживается во всяких оптимизациях например в Linq2Objects.
Эта мелочь в самом конце вычислений. Просто на задаче ручной сериализации я получил сначала выигрыш порядка 5-8 раз. А как только я попросил всех отказаться от IList<> в коде (и оп-па!!! это произошло абсолютно безболезненно), то тот же самый код на конкретных типах стал давать прирост до 50 раз в ручной бинарной сериализации в сравнении со встроенной. И сама задача обрела черты заведомо решаемой на дотнете. До этого были обоснованные сомнения.
I>Иммутабельный не IList, а пустой массив, это именно то что говорил Синклер
Синклер-то прекрасно знает, на какой неиммутабельный дизайн я ему намекал. Недавно я показывал всю кривизну такого подхода в споре о const. То бишь, все эти рассуждения у меня вызывают только иронию и мысль о поговорке "мыши плакали, кололись...", а далее ты в курсе. ))
Здравствуйте, grosborn, Вы писали:
G>Тоже очень интересно про зависимость уборки мусора от количества типов и протухание кэша. Новые для меня концепции.
Тогда это тебе не надо.
Но если любопытно, то понаблюдать самому проще простого: попробуй на досуге автонагенерить несколько сотен каких-нить синтетических тестов, надо чтобы их код не бы в бинарнике взаимно повторно используемым (можно брать пару десятков синтетических тестов и раширить их на несовместимые типы: int, long, double, float, complex<float>, complex<double>, coordinate<xxx> и т.д., можно это наполовину автоматизировать на генериках + value type). Затем, тем же автогенеренным кодом надо прогнать сначала в цикле каждый из синтетических тестов в отдельности, чтобы длительность каждого была сотню миллисекунд минимум, запомнить медиану результатов и вывести общую стоимость прогона, если бы каждый тест прогнали по 1-му разу. Затем надо все вместе тесты гонять по 1-му разу в цикле с паузой 100ms, 10ms, 1ms, 100us, 50us, 20us (пауза м/у полными циклами переборов тестов). Над результатами медитировать.