• 0
    Пожалуй, нужно ответить более развернуто. Да, я согласен, что в TPL с обработкой ошибок все здорово. Гораздо лучше, чем при работе с Thread напрямую. Да, сильно сложнее с TPL не становится. Я говорю о том, что с TPL появляются дополнительные нюансы.

    var t = a.ContinueWith().ContinueWith().ContinueWith(); t.Wait();

    Этот код не имеет практического применения. Какой смысл использовать асинхронную модель, чтобы потом принудительно ее «синхронизировать» с помощью t.Wait()?

    Я имел в виду следующие особенности:

    • Fire & Forget: не все разработчики одинаково полезны ответственно относятся к обработке исключений. Кто-то просто напишет так и ошибка будет потеряна.
      Task.Run(() => {
          // ...
          throw new Exception("please help me")
      }; // Fire & Forget
    • Про AggregateException.Flatten для TaskCreationOptions.AttachedToParent нужно знать, иначе можно потерять часть исключений.
      void Handle(AggregateException ex)
      {
          foreach (var exception in ex.Flatten().InnerExceptions)
          {
              Console.WriteLine(exception.Message);
          }
      }
    • Возможность обработать исключение с помощью TaskContinuationOptions.OnlyOnFaulted, а не try/catch — еще один exit point.
    • Можно потерять одно из исключений при использовании Task.WhenAll (да, они ССЗБ).
    • UnobservedTaskException — настраиваемое поведение
    • Wrapping / Unwrapping AggregateException при использовании await или t.Wait() — нужно внимательно следить, что мы ловим в try/catch.

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

    Спасибо за комментарий. Пока отвечал понял, что зря вообще докопался до TPL. Мне больше не понравилась идея строить на исключениях control-flow на самом деле, а TPL как-то под «замес» попал:)
    «Паттерны» функционального программирования
  • 0
    А если Customer'у потребуется менять email, то добавляем такое?
    public void UpdatePrimaryEmail(Email email)
    {
        _primaryEmail = email;   
    }
    
    public void UpdateSecondaryEmail(Email email)
    {
        _seconaryEmail = email;   
    }
    
    public void ClearSeconaryEmail()
    {
        _seconadryEmail = null;
    }
    Functional C#: Primitive obsession (одержимость примитивами)
  • 0
        [Required(ErrorMessage = “E-mail is required”)]
        [RegularExpression(@”^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$”, ErrorMessage = “Invalid e-mail address”)]
        [StringLength(100, ErrorMessage = “E-mail is too long”)]
        public string Email { get; set; }

    Этот код работал с ORM «из коробки». Можете привести пример как вы рекомендуете мапить обертки?
    Functional C#: Primitive obsession (одержимость примитивами)
  • –1
    синхронный код:
    try
    {
        var a = someMethodThrowingArgumentException(123);
        var b = someMethodThrowingInvalidOperationException(a);
        var c =  someMethodThrowingGenericException(b);
        return c.ToString();
    }
    catch(ArgumentException)
    {
        retrun "ArgumentException happened";
    }
    catch(InvalidOperationException)
    {
        retrun "InvalidOperationException happened";
    }
    catch(Exception)
    {
        retrun "Ooops!";
    }
    

    С TPL:
    someTask.ContinueWith(a => {
        try
        {
            someSyncMethod(a);
            someAsyncMethod(a).ContunueWith(b => {
                try
                {
                    // ну и так далее
                }
                catch(InvalidOperaionException)
                {
                     // только для синхронного метода
                     return "InvalidOperationException happened";
                }
            })
        }
        catch(ArgumentException)
        {
             return "ArgumentException happend"
        }
    })
    

    Да, есть async/await. Но код с async/await только выглядит императивным, а компилируется в нечто другое, работающее с помощью SyncronizationContext и по духу ничем не отличается от монад. Т.е. в чисто-императивном коде без «примочек» придется писать try/catch в каждом ContinueWith. Код становится менее читаемым, exit points «размазываются» по разным callback'ам и их приходится «собирать». Основная проблема такая.
    «Паттерны» функционального программирования
  • 0
    Стиль изложения материала у автора намеренно упрощен, его даже обвиняют в популизме. При переводе я не стал корректировать, потому что тогда получилось бы уж совсем вольное изложение по мотивам, а это и так рерайт.
    «Паттерны» функционального программирования
  • –1
    «react+redux» не имеет никакого отношения к ФП
    и
    У Редакса есть элементы ФП. Код там процедурный. Диспатч — процедурный. В языке С sqrt — тоже чистая функция, которая не изменяет свой аргумент, но от этого весь язык не становится функциональным

    Спорите со мной уже вы про Абрамова. А оригинальный вопрос был:
    Вот например какие паттерны мне надо применить при проектирование GUI библиотеки?

    React и Redux — это примеры применения элементов ФП в UI-библиотеках. Это максимально точный ответ. В комментариях мне пишут, что «react и redux не имеют отношения» а потом «содержат элементы».

    Содержать элементы уже != иметь отношение?

    Очевидно, что react и redux — не хаскель. Это никто утверждать не будет. Кстати, если перейти на ссылку с видео то там он утверждает ровно тоже самое «redux использует идеи функционального программирования. Они не новые».

    Суть вопроса «какие есть примеры ФП в UI» уже утратила актуальность. В ветке мы обсуждаем недобросовестный маркетинг и девочек.

    вы признаете, что были неправы?

    В чем конкретно я не прав? Может и признаю, пока не понял.
    «Паттерны» функционального программирования
  • –2
    По-моему, вы просто переходите на личности. Ну не нравится он вам и все. Остальное уже не важно, главное похейтить. Вот вам не нравится его pr. Вы делаете pr на хейте Абрамова. У него хотя-бы не вторично.
    «Паттерны» функционального программирования
  • 0
    … ни одна функция из определенных в обсуждаемом тексте не имеет явной сигнатуры! Тут не то что о наличии «красных путей», тут в принципе о типах аргументов и возвращаемых значений надо догадываться!

    В статически-типизированных все хорошо с сигнатурами, просто их можно опускать, потому что вывод типов работает лучше. Но можете и объявлять везде.
    «Паттерны» функционального программирования
  • 0
    Вы вырываете из контекста. Я сослался на мейнтейнера. У меня к redux много вопросов, особенно к процедурному стилю. Приходится писать очень много boilerplate или не идиоматичный redux'у код (проблема с обучением новых сотрудников).
    «react+redux» не имеет никакого отношения к ФП.

    Вы и другие участники ветки уже признали, что отношение есть: react / redux используют элементы ФП. Очевидно, что в них много побочных эффектов, потому что в web-ориентированном UI по-другому быть вообще не может.

    В JS идеи начали просачиваться в том числе из-за проблем с data-flow и callback hell. Оказалось, что есть продолжения и с ними все попроще. А вот монады в JS пока никому не нужны, потому что никто целей чистоты, как в хаскеле не ставит.

    Есть проблема — асинхронный код, который есть в 90% приложений и необходимость его как-то поддерживать и развивать. Есть решение — промисы. Копнули чуть дальше, оказывается еще и чистые функции есть. Подход прагматичный и инструментальный.
    «Паттерны» функционального программирования
  • –1
    Аналогично «виртуальный метод» — паттерн для процедурных языков, но для ООП уже есть простое готовое решение.
    А, в ФП некоторые фичи встроенные в язык заменяют ООП-паттерны (стратегия, декоратор).

    Не смотря на свойственную Мартину сварливость в статье есть коротко-сформулированный и важный тезис: ФП и ООП — вещи не взаимоисключающие, а наоборот — дополняющие.
    OO VS FP
  • +1
    Вы не поверите, это юмор:) Лисп — старейший из «выживших» ЯП. На коболе и фортране никто уже нового не пишет, а Clojure — это современный диалект Лиспа.
    «Паттерны» функционального программирования
  • 0
    У него консалтинговая компания. Есть клиенты, вероятно собирают статистику. Если бы совсем не работало, наверное со временем его услугами перестали бы пользоваться. С моим опытом большинство утверждений Фаулера согласуются. Конкретные цифры конечно подтвердить не могу.
    OO VS FP
  • –1
    Вы по ссылке пройдите все-таки. Там ещё один полуторачасовой доклад, посвященны этой теме. С примерами и доскональным разбором как же эта магия работает. Продолжительность доклада «паттерны фп» — ещё полтора часа. Если тема будет востребована, я могу попробовать собраться с силами и перевести и его:)
    «Паттерны» функционального программирования
  • 0
    Я целенаправленно скачал лекции по лябда-исчислению и даже посмотрел первые три. Кому как, конечно, но мне с вишенками и яблочками «заходит» лучше. Для математики такие аналогии смехотворны. Но мы же программы пишем, а не теоремы доказываем.
    «Паттерны» функционального программирования
  • 0
    Ошибки там не игнорируются. Возвращается первая ошибка, дальше выполнение не идет. Druu верно отметил: есть разница между Maybe и Either. Кстати, Скотт не кисло глумится над тем, как обычно объясняют монады апологеты ФП и какое впечатление это производит.
    «Паттерны» функционального программирования
  • +1
    В данном случае проблема вообще в нарушении SRP изначально как мне кажется. Исключения и доступ к БД уже сверху наложились.

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

    В данном случае есть «правильный» вариант (болты). Нужно было их сразу ставить. Была бы дополнительная сложность, кривая обучения, но я заметил, что по примеру джуниоры копипастят код разного качества примерно с одной эффективностью. Лучше учить копипастить сразу хороший:)

    Я строго на стороне дяди Боба: ФП и ООП — инструменты, не заменяющие, а дополняющие друг-друга. Полезно знать и применять при необходимости приемы и той и другой.

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

    Практическая применимость и tool-support таких концепций — отдельный вопрос. Я не считаю, что IO — супер-элегантное решение проблемы ввода-вывода в хаскеле: «посмотрите это выглядит как императивный код, но это не он»:)
    «Паттерны» функционального программирования
  • 0
    Вы правы, что сам по себе TPL не при чем. Просто в многопоточном / асинхронном коде проблемы обработки исключений (exception handling) становятся более очевидными, особенно то, что касается отслеживания exit points.

    Вообще монады vs исключения vs коды возврата тема, мягко говоря, спорная:)
    «Паттерны» функционального программирования
  • 0
    Чтобы жестко зафиксировать последовательный порядок применений функций, требуется использовать специальную монаду IO, с которой программирование фактически становится императивным.
    Все-таки точнее сказать: «код выглядит как императивный». IO позволяет отделить вычисления от исполнения.
    «Паттерны» функционального программирования
  • –2
    Интересно, а без хаскеля примера нет?
    «Паттерны» функционального программирования
  • +1
    Такие проблемы не появляются на ровном месте, а если вы с нею столкнулись, то у вас проблемы гораздо большего масштаба, чем «у нас в коде везде throw».
    Случай из жизни. Жили были программисты. Совместили они логику валидации и прасинга документов. И выбрасывали они исключения для валидации. И нормально все было, пока не стали присылать сводные xls-файлы на несколько десятков миллионов строк. И, нет-нет, нельзя клиенту объяснить, что обмен xls-файлами такого размера не самое оптимальное решение.

    Ждать сутки для разбора этого файла последовательно — не вариант, тем более, что железо на проде позволяет и не все строки файлов связаны. Map / Reduce — прям то, что нужно. В итоге не контролируемые побочные эффекты (функции валидации, дергающие БД и выбрасывающие исключения) значительно затруднили мне тот самый Map / Reduce.

    У Either есть сильные и слабые стороны. Вы продолжаете настаивать на том, что есть один православный способ на все случаи жизни, а все остальное к дело не относится и вообще другой случай. У автора пример тоже максимально простой, чтобы не пугать монадами и прочими эндофункторами. В ASP.NET MVC с обработкой ошибок действительно хорошо — можно обработать все декларативно. Но вы точно уверены, что у вас все исключения должны возвращать код 500? 401, 412, 422, не? Посмотрите доклад про rop целиком, прежде чем судить. Там есть много здравых мыслей.
    «Паттерны» функционального программирования
  • 0
    У меня студия на i7 с ssd и 12гб оперативки знатно так подтормаживает, особенно при наборе текста. Райдер работает значительно шустрее. Кажется, про проблему открыть проект «Решарпер» в VS2015 со включенным «решарпером» упоминал serjic в одном из интервью про Rider.
    «Паттерны» функционального программирования
  • +1
    Судя по всему, потому что для дяди Боба полиморфизм — это прежде всего удобство не возиться с указателями. Думаю, чтобы прочувствовать эту точку зрения, нужно написать много кода на чистом C.
    OO VS FP
  • +1
    Потому этот кейс не стоит брать во внимание – там другие правила

    Если вас кейс на данный момент не слишком волнует, это не значит, что его не стоит брать во внимание. Вот был у вас однопоточный код, стал он выполняться двое суток. Надо параллелить, а у вас внутри везде throw. Весь код на помойку, переписываем на TPL с нуля? Весело, но дорого.
    «Паттерны» функционального программирования
  • +1
    Просто используйте неизменяемые коллекции

    Всегда и везде и память ваша закончится:) Кроме шуток, R# перестал работать в VS2015 как раз из-за неизменяемых коллекций в Roslyn, которые выжрали всю оперативку. Анализаторы Roslyn выключить нельзя. Пришлось JetBrains запилить Rider.
    «Паттерны» функционального программирования
  • –1
    ФП вариант с проверкой ошибок соответствует ООП варианту без проверки, где каждый метод может кинуть RuntimeException в случае ошибки.

    Здесь я с вами согласен, но только для однопоточного кода. С TPL вариант с exception'ами уже не такой хороший. Кроме этого, нужно гарантировать, что в программе только один catch, иначе высок риск «проглатывания» ошибок.
    «Паттерны» функционального программирования
  • +3
    Позвольте. Редюсеры должны быть чистыми функциями, состояние не должно изменяться, вместо этого мы возвращаем новое состояние. Кажется это принципы функционального программирования. Пока вы не привели никакой аргументации, кроме прямых обвинений в недобросовестной рекламе.
    «Паттерны» функционального программирования
  • 0
    А черешня — не вишня? Это самая важная деталь, из-за которой в переводе весь смысл метафоры потерян?:)
    «Паттерны» функционального программирования
  • –3
    Да? Абрамов несколько иного мнения 29:00.
    «Паттерны» функционального программирования
  • 0
    Вот например какие паттерны мне надо применить при проектирование GUI библиотеки?
    Рекомендация «используйте react+redux» не подойдет? Функциональное программирование на UI.
    «Паттерны» функционального программирования
  • 0
    Этот доклад раздражает не только вас. Подобным образом отреагировал и Дядя Боб. Кстати, его пост-ответ тоже заслуживает перевода.
    «Паттерны» функционального программирования
  • 0
    Все же есть много новичков пишущих s1+s2+s3+s4+s5 в цикле. Есть и много людей требующих любую конкатенацию из двух строк заменять стрингбилдером или string.Format.
    Без сомнения. Я имел в виду, что лучше задать вопрос «строки — это ref или value type». Чаще всего говорят ref. Потом спрашиваешь, «а почему же они не изменяемые»? И кто такой StringBuilder? Если уже в этом контексте кандидат упомянет интернирование — честь ему и хвала, но на практике моих собеседований такого не происходило :) Может не те джниоры приходят? А «те» только в Москве?
    Как я проходил собеседования на позицию Junior .Net Developer
  • +4
    Вот без интернирования строк джун ну никак не проживет. Живо себе представляю, как младший разработчик начинает заниматься оптимизацией memory traffic и первым делом приступает к написанию unsafe-кода. Тут ему как раз и помогают эти знания.
    Как я проходил собеседования на позицию Junior .Net Developer
  • 0
    Короче, дьявол в деталях. Кто хочет и умеет работать дома — пусть работает, приходит в офис столько, сколько нужно. Этот процесс организовать сложнее, чем процесс «с 8 до 17», но зато дает некислую нематериальную мотивацию. Кто не хочет / не умеет / не может, пусть работает в офисе. Пусть каждый *** как он хочет… и умеет:)
    Начальник, хочу работать из дома
  • 0
    Возвращаемся к моей первой формулировке:
    Я имел в виду ситуации, когда человек именно не умеет организовывать свою работу эффективно, а не когда ему мешают
    Вам сложно самостоятельно организовать свою работу без участия коллег и менеджеров. Как в фильме «Римские приключения»: один из героев спокойно пел только в душе, так что пришлось вытащить душевую кабинку на сцену. Это не делает вас плохим или хорошим, просто у вас нет такого навыка. Кто-то хочет этому учиться, кто-то нет.

    Именно потому что это личный выбор человека, многие руководители настороженно относятся к полностью удаленной работе.
    Начальник, хочу работать из дома
  • +1
    Ну хотя бы затем, что стоимость такого сотрудника = его оклад + стоимость нахождения его начальника в офисе. Менеджерам свойственно выезжать на встречи и вообще всячески бегать по офису как электровенник. Если менеджер нужен только, чтобы сидеть и грозно смотреть на Васю, Вася дорого стоит. Кроме этого, Вася только первое время будет бояться менеджера, а потом просто поставит монитор «лицом» к стене и выучит комбинацию alt+tab.
    Начальник, хочу работать из дома
  • +2
    третьему нужен начальник, который может внезапно появиться за спиной и вломить за игру вместо работы

    по-моему проще с такими личностями прощаться.
    Начальник, хочу работать из дома
  • 0
    Согласен. Я имел в виду ситуации, когда человек именно не умеет организовывать свою работу эффективно, а не когда ему мешают. В комментариях многие уже справедливо отметили, что не всем удобно работать дома, особенно если офис хорошо оборудован и в компании существует культура, запрещающая «дёргать» программистов. У меня есть возможность работать всю неделю удаленно. Не смотря на то что живу загородим, предпочитаю работать в офисе.
    Начальник, хочу работать из дома