Здравствуйте, Undying, Вы писали:
U>Вот к примеру алгоритм определения прохождения расписания:
U>
U>
U>Объясните как такие задачи решать в чисто функциональном стиле?
Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.
Здравствуйте, Undying, Вы писали:
L>>Тогда тем более непонятно зачем вводить FirstOrNull, если он не решает тех проблем, которые есть у FirstOrDefault.
U>Не понял ответа. Если разделять ситуации коллекция пуста и первый элемент коллекции null не требуется, то использовать функции FirstOrNull и FirstOrNullable безопасно, в отличии от функции FirstOrDefault.
А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
Здравствуйте, Ikemefula, Вы писали:
U>>Объясните как такие задачи решать в чисто функциональном стиле?
I>Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.
Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние. Если задача по своему условию требует сложного промежуточного состояния, то рефакторинг здесь помочь ничем не может. Вот мне и хотелось бы увидеть, как в чисто функциональном стиле решаются задачи со сложным промежуточным состоянием.
Здравствуйте, Lloyd, Вы писали:
L>А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
В том что если FirstOrNull подсунуть коллекцию структур компилятор выдаст ошибку, а FirstOrDefault это не просто проглотит, но и в рантайме ошибку мы получим не по месту внесения, а хрен знает где и когда.
Здравствуйте, Undying, Вы писали:
U>Т.е. если у нас есть коллекция int'ов, то ее надо явно преобразовывать в коллекцию Nullable<int>? Это очень удобно?
Обычно в запросе все равно есть проекция, в которой и можно к int? преобразовать заодно.
U>Функция FirstOrDefault в фрамеворке это ошибка дизайна, если бы вместо нее были бы функции FirstOrNull для коллекций классов и FirstOrNullable для коллекций структур, то проблем не было бы в принципе.
Ну так добавь, делов то.
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
Здравствуйте, Undying, Вы писали:
L>>А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
U>В том что если FirstOrNull подсунуть коллекцию структур компилятор выдаст ошибку, а FirstOrDefault это не просто проглотит, но и в рантайме ошибку мы получим не по месту внесения, а хрен знает где и когда.
в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
Здравствуйте, Undying, Вы писали:
U>Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние. Если задача по своему условию требует сложного промежуточного состояния, то рефакторинг здесь помочь ничем не может. Вот мне и хотелось бы увидеть, как в чисто функциональном стиле решаются задачи со сложным промежуточным состоянием.
Ты считаешь, что задач со сложным промежуточным состоянием в природе не существует? Или что в функциональном стиле такие задачи решаются легко?
Если второе, то хотелось бы увидеть пример решения задачи со сложным промежуточным состоянием в функциональном стиле.
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, Ikemefula, Вы писали:
U>>>Объясните как такие задачи решать в чисто функциональном стиле?
I>>Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.
U>Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние. Если задача по своему условию требует сложного промежуточного состояния, то рефакторинг здесь помочь ничем не может.
Здравствуйте, Undying, Вы писали:
U>Ты считаешь, что задач со сложным промежуточным состоянием в природе не существует? Или что в функциональном стиле такие задачи решаются легко?
Я считаю, что в очень многих случаях сложное состояние удается отделить.
А не согласен я со следующим:
Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние.
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
Здравствуйте, Ikemefula, Вы писали:
U>>Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние. Если задача по своему условию требует сложного промежуточного состояния, то рефакторинг здесь помочь ничем не может.
I>Не понял идею.
Например, по условию задачи нужно хранить следующие промежуточные состояния:
int certifiedStationIndex = -1; //последняя остановка пройденная по расписанию
StationIntervalWithIndex unexpectedInterval = null; //остановка пройденная вне очереди (если есть)
Dictionary<Tuple2<int, DateTime>, bool> undoneArrivalIntervals = new Dictionary<Tuple2<int, DateTime>, bool>(); //остановки, на которые мы в текущий момент уже въехали, но еще из них не выехали
Объясни каким образом рефакторинг поможет избавиться от этих промежуточных состояний?
Здравствуйте, Undying, Вы писали: U>Объясни каким образом рефакторинг поможет избавиться от этих промежуточных состояний?
Всю задачу я не понимаю. Но есть опасения что приведенный кусок кода выдернут из функции которая раз в 5 больше этого куска.
Если для написавшего ее, она легко читается и ее не прийдется менять, то никаких проблем. Если нет то ее лучше было бы как-то измельчить, порубать на более мелкие. Неважно в функциональном стиле или нет. Для алгоритмов как правило всегда существует много вариантов реализации.
Например:Тут вот похоже два потока данных rawArrivals, rawDepartures, каждый оборот внутреннего цикла выдергивает и обрабатывает один элемент либо из первого либо из второго потока. Это уже можно вынести, в отдельную функцию возвращающую перечисление currentInterval, и если надо информацию откуда выдернуто.Небольшая но все-таки декомпозиция. Не факт что это сильно улучшит, остального кода я не видел (да и не стал бы разбираться с пол-тысячей строк).
Интересно было бы только время жизни этих данных. И есть ли какая-то топ-функция у который вполне конкретный вход и выход, которая вызывает остальные функции, и которая скрывает какие-то промежуточные данные(время жизни которых не выходит за пределы этой функции).
Здравствуйте, Undying, Вы писали:
U>Здравствуйте, Ikemefula, Вы писали:
I>>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае
U>Главная проблема чисто функционального подхода, что на нем непонятно как писать сложные алгоритмы. U>Вот к примеру алгоритм определения прохождения расписания:
По человечески объясни что код делает, уверен что моментально напишут функциональное решение.
Здравствуйте, Undying, Вы писали:
U>А что делать в тех случаях (пусть немногих), в которых сложное состояние отделить не удается?
Ах, уже немногих. Это неколько контрастирует с исходным заявлением. Что делать? Думать. Серебрянной пули нет.
U>Можно пример сложного алгоритма без сложного промежуточного состояния?
В каком виде пример? Форматтер исходников в ешарпере сгодится?
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
Все методы во фреймворке для IEnumerable сделаны как:
1. по возможности ленивы
2. не меняющие состояние перечисления или объектов в нем (хотя это сложно запретить полностью и при большом желании поменять таки можно)
Создавая свои экстеншены которые выглядят и используются также как и библиотечные, но имеющие логику противоположную ленивости и иммутабельности вы рискуете быть непонятыми и люди пользующиеся вашими экстеншенами будут создавать больше ошибок. Lloyd правильно заметил, что не стоит смешивать получение данных и операции над ними. По этому поводу писал Липперт(емнип) и была бурная дискуссия в .NET.
I>
I>if (GetRouting(selection).AtLeastOne())
I>
I>GetRouting — ленивая коллекция, обработка отдельно от сбора была сделана в тот момент, когда понадобилась проверка.
Это Any() изобретено чтоли?
Z>Все методы во фреймворке для IEnumerable сделаны как: Z>1. по возможности ленивы Z>2. не меняющие состояние перечисления или объектов в нем (хотя это сложно запретить полностью и при большом желании поменять таки можно) Z>Создавая свои экстеншены которые выглядят и используются также как и библиотечные, но имеющие логику противоположную ленивости и иммутабельности вы рискуете быть непонятыми и люди пользующиеся вашими экстеншенами будут создавать больше ошибок. Lloyd правильно заметил, что не стоит смешивать получение данных и операции над ними. По этому поводу писал Липперт(емнип) и была бурная дискуссия в .NET.
ОК, а если тот же DisposeAll не является методом-расширением, то всё ОК?
Здравствуйте, gandjustas, Вы писали:
G>Не прикидывайся, ты прекрасно знаешь что и почему было.
Пока что все знают, что не хуже до сих пор в очень многих разделах современного ПО. И смысл рекламировать тот или иной подход вообще, когда рассматриваются частности?