Прийшов час осідлати справжнього Буцефала🏇🏻Приборкай норовливого коня разом з Newxel🏇🏻Умови на сайті
×Закрыть

Kyiv Haskell Study Group Fall 2019

Радий повідомити, що ми запускаємо набір на Haskell Study Group! Більше інфо на kyivlambda.com/haskell-study-group

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Коли буде наступний набір?

Гарне питання :) Поки що невідомо, чи буде взагалі. Слідкуйте за анонсами twitter.com/kyivlambda та twitter.com/kyivhaskell , а також приєднуйтесь до Discord/Slack/Telegram kyivlambda.com

Есть возможность участвовать удаленно?

Ви можете самостійно проходити матеріал та задавати питання в Slack-каналі, не бачу проблем.

Есть крупные компании, у которых в проде есть хаскель.Тинькоф, например.

Мм, та ні. Вони замінили DSL (на чому він там реалізований я не знаю), на розробку якого витрачалося багато сил, та який був спеціалізованим для фб, на Хаскел, при цьому отримавши кращу швидкодію, паралелізм, та зробивши так, що люди тепер практикуються на Хаскелі замість закритої спеціалізованої мови.

Ось більш широкий список: github.com/erkmos/haskell-companies

Плюс є такі стартапи типу мого, яких там очевидно поки нема.

Якщо цікаво опенсорс приклад реального веб апп — подивіться на мій meetup.events

На моїй поточній та минулій роботі більше однієї людини)) але архітектура від цього особливо не змінюється.

1. Сколько времени будет занимать процесс «накарирования» и частичного приминения этих самых модулей под нужды в конкретном сервисе?

Що таке «накарирование модулей»? Дуже незрозуміле питання. Нічим подібним займатись не доводиться.

2. Чисто даже теоретически как карирование и частичное приминение (ручное объявление графа зависимостей) может быть сравнимо с DI (автоматическое объявление графа зависимостей)

Граф залежностей визначається тим, яка функція яку викликає. Знову ж таки, буду вдячний за більш доступний опис.

3. Допустим хочется логировать. И хочется делать это в рандомных слоях. Что делать?

Викликати функцію logInfo (або logError). В чому проблема?

4. Инфраструктура и библиотеки?

Все є!

Викликати функцію logInfo (або logError). В чому проблема?

Наверное в том, что логирование — это IO, что в pure functions делать не получится.

А, ну так, більшість коду як правило і є в IO. Якщо хочеться логіювати код не з IO — поверніть дані, які хочете логіювати, в IO, та там його логіюйте.

main = do
let (res, stuffToLog) = myPureComputation
log stuffToLog

Будь добр, потрудись раскрыть мысль, чтобы было понятно про какие эффекты ты говоришь в pure functions.

typelevel.org/...​t/typeclasses/effect.html вот это. Заметание сайд эффектов под ковёр среды исполнения, так чтобы код оставался максимально похожим на pure. НЯЗ, в хаскеле прямо встроенные средства для этих целей есть.

Да, есть еффекты, но разе logInfo или logError — это эффекты?

Если есть небезопасное взаимодействие с внешним миром, то вполне себе да. Если ваша приложунька вертится в GCP и пишет в Stackdriver, то это самый настоящий эффект.

Я так розумію, мається на увазі щось типу Writer Monad, де ви можете чистий код писати, додаючи операцію log ніби у вас код не чистий, а воно загорнетьсяв по суті повертання всіх лог-записів kseo.github.io/...​7-01-21-writer-monad.html

Звичайно, в реальному житті мало кому це все потрібно, і зазвичай, якщо чистий код потребує логінг, він перестає бути чистим (точніше ділиться на чистий код «до» та «після» логгінгу).

github.com/...​stopherDavenport/log4cats вот пример библиотеки которая делает логи.

Берите скалу, для реального мира более чем подходит.

Штука в том, что, когда код хорошо стрктурирован, логировать где-попало не нужно, логика получается pure, а IO выносится на верхний уровень. Вот интересная статья и доклад по теме: blog.ploeh.dk/...​-to-dependency-rejection www.youtube.com/watch?v=cxs7oLGrxQ4 и еще вот это blog.ploeh.dk/...​1/asynchronous-injection.

Есть уметь в проектирование, то обработка каждой команды будет

на несколько файлов аля лабораторка

Так лапшать можно на любом языка. На фунциональном труднее, наверное. А на какие вопросы нет ответа? DI и логирование разобраны по ссылкам, которые я привел выше.

Марк, как раз, пишет, что зависимости не нужны.

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

Мы в команде используем похожий подход. У нас C#, а не Haskell и без наворотов, как у Марка, но принципы те же.

Проект довольно большой и уже использовали C#, когда я пришел. Переписывать на F# нецелесообразно на данный момент. Плюс это learning curve для всей команды, а мы сейчас двигаемся а k8s, что тоже требует много времени на обучение. Так что пока другие приоритеты 🙂.

Понял. Просто тоже прошел через похожий paradigm shift: C# -> functional-oriented C# -> F#. Переписал (в спартанском режиме, правда, за неделю) кое-что на F# — эффект поразительный, codebase ужался многократно, простота и поддерживаемость выросла. (Дело конечно не только в языке, изменилась парадигма и подход, поэтому тут не только вина C# против F#...).

А порог вхождения в F# кстати может быть «сглажен», ведь язык очень демократичный и кстати имхо довольно простой, намного проще той же Скалы. Долгое время будучи лютым фанатом C# я тоже считал, что для многих вещей F# вообще не нужен, хватит и C#, и поначалу пробовал все эти симановские/ФПшные штучки пихать в C#, но когда попробовал F#, возвращаться к C# больше вообще не хочется)

думаю, вам просто надо решиться, позже = никогда !

Нет, конечно, вы что-то неправильно прочитали/поняли.

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

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

Так как у нас Mongo, мы используем oplog tailing чтобы паблишить ивенты из записанной сущности, а так как большая база кода, некоторые ивенты мы генерим неявно по полям, которые изменились в сущности, чтобы сохранить обратную совместимость. Получаются общие ивенты Created, Updated, Deleted. В общем случае это антипаттерн.

Наведіть конкретний приклад проблеми, яку ви вирішуєте. Зазвичай di називають просто передачу функцій в якості параметрів.

В нас закритий код та продукт в поточній та минулій компанії, ссилку давати нікуди, але принципово не розумію що це змінює. Така ж архітектура, ті ж проблеми. Що ж, шкода що не змогли порозумітись.

Подивився приклад, він дійсно жахливий, але з трохи інших, більш простих причин. Можливо я просто чогось не розумію та ви їх роз’ясните?

Одже, в першій частині blog.ploeh.dk/...​/02/dependency-rejection має пояснюватись проблема, яку ми вирішуємо. Там наведено http handler, що валідує дані та робить резервацію (або кидає помилку).

Далі автор пише:

> They are dependencies. Could you make the Post method take them as arguments?

Навіщо це робити? Яку це проблему вирішить?

На що вам не відповіли? Я попросив уточнити формулювання, що не мають сенсу. З задоволенням на все відповім більш розгорнуто.

Проблема циклічних залежностей, як правило, виникає, коли два компоненти один від типів іншого, як правило вирішується додатковим модулем «.Types», в якому зберігаються типи, та залежність розбивається на окремо залежність від типів та модулів. ООП-мови страждають, тому що в них дані та методи відділяти важче. На моєму багаторічному проекті цього було достатньо для боротьби з цією проблемою.

П.с.2 под словом di я подразумеваю внедрение зависимостей на основании типов, которое используется при ооп парадигме

Ви можете виконувати інший код залежно від типу за допомогою тайп-класів, але знову ж таки, важко сказати що краще використовувати без більш конкретного опису проблеми, більш точними термінами. Більшість DI-проблем в ООП-мовах, які я бачив, в функційних мовах просто не виникає, через те, що тут відділяють типи, дані та функції.

Я досі не розумію, чому воно погано на вашу думку працює в більших кодових базах. Мені навпаки, здається що чим більше кодова база, тим більший бенефіт, бо ви менше боїтесь торкатись чужого коду. На Хаскелі, принаймі, в мене саме такий досвід, що я можу взяти чужий код річної давнини та спокійно його рефакторити та змінювати.

Це просто неправда. Карування можете не використовувати якщо не хочете, я за останні шість років функцію curry викликав разів п‘ять. Не розумію звідки у вас настільки хибні уявлення про фп.

Ну, воно використовується іноді для зручності, але теж не є якоюсь центральною частиною побудови програм, і я досі не розумію значення ось цієї фрази

Как минимум потому что чисто функциональный подход предполагает ручную композицию функций через частичное приминение

В ООП виклик методу не є ручною композицією? Взагалі не розумію що таке ручна композиція і що таке неручна.

Список репозиториев с лабораторками на несколько файлов: github.com/...​?l=haskell&o=desc&s=stars

Да и в проектах побольше. И там она даже получше работает чем ИП+ООП ибо настолько взрывного эффекта снежного кома там не возникает.

Вопрос был не про нужно/не нужно, а «что делать, если хочется?». Хочется логировать, хоть всрись!

Хочется — логируй. В чем проблема?

1. Сколько времени будет занимать процесс «накарирования» и частичного приминения этих самых модулей под нужды в конкретном сервисе?

ну это же всё просто вызов функции либо Config => Module либо Config => F[Module]. Иногда он бывает ассинхронный, если в какой-то сервис надо сходить и коннекшн открыть.

ожет быть сравнимо с DI

зачем нужно DI в языках типа хаскеля и скалы?

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

docs.scala-lang.org/...​erviews/core/futures.html Условно, «конфигурация» операции map и flatMap в стандартной скала-фьюче, которая говорит на каком пуле потоков нужно её исполнять.

Ну раз такой пример не нравится, вот тебе физз-баз. Код писал от балды, ибо цель была продемонстрировать как тут работают имплиситы. Внимание на то, что ни энв ни продукт не был вписан в параметры, оно нашлось само компилятором. scastie.scala-lang.org/...​/efLILMS2S4i7z4OiRe7gCg/1

Если необходимость сократить количество писанины — пользуйте тайпклассы, импортите инстансы те которые нужно, и IDE (INTELLIJ по крайней мере) умеет искать какой имплисит куда залетает, но обычно, есть правило, если есть тип, то один инстанс и без шедоуинга. Для упрощения есть ньютайпы, и какая-то либа для специального менеджмента инстансов тайпклассов по модулям а-ля DI по фп шному. Parital application — по прежнему самая good looking thing на мой взгляд, если не сетапить там флоу с разветвлениями и не разрастать его до килострочек. Writer это точно дичь, и использовать его для этих целей не нужно.

тестировать все эти инстансы функций

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

целого DAG

никогда не испытавал проблем по этому поводу, приложения на ФП получаются обычно меньше в терминах архитектурных излишеств(сущностей которые нужно непосредственно просовывать вне тайпклассов и имплиситов очень и очень мало), и если у вас не ОАО «Монолит», то особо там ничего прописывать и не нужно. Слышал товарищи пишут магию с солвером на типах, «чтоб как в кошерном DI», но в релизе пока этого нет, наверное потому что никто монструозных аппов не пишет.

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

Если хочется узнать про прямо таки сириоус бузинесс, то это лучше к инженерам тинька обращатся, у них большая контора.

какой размер кодобазы, сколько слоев, сколько сервисов

сам факт использования фп вырезает несколько слоёв абстракции. Например если у вас есть необходимость кодирования в несколько форматов обмена типа json /bson/etc вы просто бахаете github.com/danslapman/morphling и не паритесь. −1 слой. Если нужно городить мапперы из одной модели в другую, вы бахаете github.com/milessabin/shapeless или магнолию. Ещё −1 слой. Если вам нужно городить «сложную логику» с перобразованием для моделей — slick.lightbend.com или doobie, или ещё что. Если нужно городить сложную штуку для всякого-там стриминга и прочей реактивной лабуды, решения типа fs2 тоже есть. В итоге от моструозного аппа с тоннами слоёв и «зе коде из солид» остаётся только чуть-чуть, и читабельность семантика не ломается.

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

Где вы были когда я был студентом?

Фигасе список спонсоров, я там надеюсь везде хаскель в прадакшене юзают ?

Ні, в основному це ініціатива співробітників цих компаній, що були на минулій групі по Хаскелю. Але всі компанії зі списку люблять функційне програмування, це факт.

В чем профит от таких групп для изучающаго? Проще самому изучить. Более того, материала полно.

Для изучающих хз, а вот на продаже книги кто-то явно заработает))

Ага, автори отримають суму, що приблизно дорівнює половині дня роботи програмістом в США. Скажені гроші!

А это не важно)
Важно как это выглядит со стороны))

Дякую за вашу думку, якщо з‘явиться ідея — перефразую щоби виглядало краще.

У всіх свої підходи до вивчення, якщо вам більше підходить самостійне вивчення — я тільки за.

Зі свого досвіду проведення груп з навчання та від відгуків тих, хто на них був:

— в групі ви отримуєте можливість подивитись код інших (а в деяких домашках у нас буде взагалі peer to peer review)
— на зустрічах ви можете запитати все, що вас цікавить, отримати допомогу з домашок, які не вийшло зробити
— зазвичай я намагаюсь на проекторі додатково розказати щось цікаве
— багато кому (мені в тому числі) разом щось вчити — веселіше

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

З досвіду минулої групи — по різному, студентів майже не було

Зараз приєднатись ще не пізно?

Не пізно, хоч через 10 тижнів. Слідкуйте за розкладом та приходьте в будь-який момент з домашками того тижня!

Добре, що займаєшся викладанням

Але слово Fall звучить як Fail, краще придумати більш звучну назву для теми

Fall — це осінь в перекладі з американської англійської

Подписаться на комментарии