Lil Functor – Telegram
Lil Functor
797 subscribers
57 photos
1 file
183 links
Pure functional and composable channel

Чат: https://news.1rj.ru/str/+L-xb_m_4lnY3Y2Fi
Download Telegram
Forwarded from Scala Nishtyaki Channel
Акка сенсоры в чяте!

Интересная статья + библиотека по акке и обсервабилити за авторством @zeehond:

Медиум: https://jacum.medium.com/observability-of-a-reactive-system-48d520c4cf69
Гитхаб: https://github.com/jacum/akka-sensors

Да, присылайте ваши билиотеки в личку, будем постить.
Спивак опять красиво расписал про файберы

Какую проблему решают, в чём разница по сравнению с работой на тредах напрямую, как можно их шедулить.

https://typelevel.org/blog/2021/02/21/fibers-fast-mkay.html
Сайт Мартина Фаулера — это кладезь энциклопедических знаний по разработке ПО. Помимо вещей, касающихся непосредственно программирования, у него формализованы подходы к IT «с высоты»: структура организаций, паттерны распределённых систем, процессы.

Continuous Delivery и Continuous Integration — короткие и понятные определения CI/CD, ключевые критерии, построение процессов;

Data Mesh Principles and Logical Architecture — управление большими аналитическими данными в децентрализованных организациях;

DevOpsCulture — просто нормальное определение DevOps;

Patterns of Distributed Systems — сборник паттернов вокруг консенсуса узлов распределённой системы;

How to break a Monolith into Microservices и How to extract a data-rich service from a monolith — пошаговые инструкции по выделению микросервисов из монолита.
Доклад Alexander Ioffe о выводе тайпклассов в третьей скале. В начале он рассматривает проблему рефлексии против макросов при сериализации классов. Я жил с интуитивным пониманием, что макросы быстрее рефлексии, но ленился померять, насколько. А вот докладчик не поленился! Дальше идёт хардкорное метапрограммирование, о котором кому, как не кор-контрибутору quill рассказывать.

Видео: https://www.youtube.com/watch?v=E9L1-rkYPng
Исходники из доклада: https://github.com/deusaquilus/derivation_examples
Бытует мнение, что в Scala сложно вкатиться начинающему программисту: всем нужны разработчики middle+ уровня. Это близко к правде, я сам довольно долго искал первую работу. Но теперь рынок труда перевернулся и вакансия для начинающих скалистов есть!

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

Подать заявку на стажировку -> https://yandex.ru/jobs/vacancies/dev/intern_backend_auto/

А ещё у нас грандиозные планы по найму «взрослых» программистов. Подробно почитать про вакансию можно здесь -> https://telegra.ph/Vakansiya-behkend-razrabotchika-na-Scala-03-04.

TL;DR:
- делаем auto.ru, Я.Недвижимость и Я.Объявления
- любим ФП;
- открыты к общению как с опытными скалистами, так и разработчиками из других стеков (желательно около-jvm);
- есть команды с интенсивной продуктовой разработкой, есть команды, занимающиеся инфраструктурными решениями;
- всегда нужны тимлиды, приходите к нам и становитесь руководителями;
- total складывается из оклада, премий, RSU и кучи неденежных компенсаций (ДМС, скидки у партнёров);
- надо пройти два собеса: общие вопросы с лайвкодингом и system design.

CV и вопросы можно писать мне в личку @poslegm
Forwarded from Anton Trunov
Всем привет! Мы хотим организовать неформальную летнюю школу по формальным методам и всяким родственным штукам (см. WIP сайт школы https://лялямбда.рус).
Планируются мини-курсы/воркшопы/доклады/нетворкинг/развлечения.
Темы курсов и воркшопов ещё пока только определяются (предложите свою!) и простираются от рандомизированного тестирования/фаззинга и модел-чекинга, до кубических (и не только) пруверов, логики некорректности, верифицированных компиляторов и слабых моделей памяти. Мы приветствуем участников с любым уровнем знаний — планируются несколько треков, чтобы каждый мог выбрать себе тему по своему бэкграунду.

Чтобы понять больше о наших потенциальных участниках и о том, какой формат школы выбрать, нам нужна ваша помощь: если бы вы хотели поехать, заполните, пожалуйста, небольшую форму https://docs.google.com/forms/d/e/1FAIpQLScfJ3tguxHNgxwHX_XpsWOiABTwB2R74sKh6OXEmcpYCCQqOQ/viewform.
Лонгрид Профессора об экспериментальном механизме контроля исключений в Scala 3

Пока закрыто экспериментальным флагом компилятора. Выглядеть будет так:

def f(x: Double): Double canThrow LimitExceeded =
if x < limit then x * x else throw LimitExceeded()

@main def test(xs: Double*) =
try println(xs.map(f).sum)
catch case ex: LimitExceeded => println("too large")


Чем мотивируется? Асинхронный код на Scala пишется с использованием какой-то монадки, в которую контроль ошибок так или иначе встроен. Но для синхронного кода надо или жить с unchecked эксепшенами, либо втаскивать монадку Either только чтобы зафиксировать ошибку в сигнатуре.

Джавовые checked эксепшены неудобны и требует дыры в виде RuntimeException. Поэтому Одерски придумал новую механику. Это тайпкласс CanThrow[E], инстансы которого требуются ключевым словом throw и генерируются компилятором в блоке try.

Для примера выше компилятор сгенерирует код

@main def test(xs: Double*) =
try
erased given ctl: CanThrow[LimitExceeded] = ???
println(xs.map(x => f(x)(using ctl)).sum)
catch case ex: LimitExceeded => println("too large")


Механика позволит отказаться от лишних монадок в некотором коде. Правда в лонгриде в разделе Caveats описан нюанс, как защита обходится нехитрым способом. Возможно, потом это исправят.

Чтобы canThrow не создавал оверхеда в рантайме, для него используется новое ключевое слово erased. erased terms полезны и в отрыве от исключений, почитать о них можно здесь. Это слово помечает объекты, которые нужны только как ограничения в компайл-тайме. Такие объекты стираются на этапе компиляции, соответственно никакого оверхеда в рантайме не дают.

Про исключения: https://github.com/dotty-staging/dotty/blob/add-safe-throws-2/docs/docs/reference/experimental/canthrow.md
Про erased: https://github.com/dotty-staging/dotty/blob/master/docs/docs/reference/metaprogramming/erased-terms.md
Внимание!

Появился русскоязычный телеграм-чат про ZIO

@ru_zio
@ru_zio
@ru_zio

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

Спасибо за внимание.
Наткнулся на старый тикет, в котором Travis Brown померял производительность вызова fold по сравнению с обычным паттерн-матчингом. Замеры он делал для cats.data.Validated, но результаты актуальны и для аналогичных контейнеров (Either, Option). А результаты неутешительные — fold медленнее заинлайненного паттерн-матчинга в четыре раза.

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

sealed abstract class Validated[+E, +A] {
// ...
def fold[B](fe: E => B, fa: A => B): B = this match {
case Invalid(e) => fe(e)
case Valid(a) => fa(a)
}
// ...
}

Validated // <- медленно
.valid(42)
.fold(e => println(s"error $e"), res => println(s"result $res"))

Validated.valid(42) match { // <- быстро
case Invalid(e) => println(s"error $e")
case Valid(res) => println(s"result $res")
}

Просадка производительности связана с тем, как в jvm реализованы лямбды: для каждой лямбды аллоцируется объект в куче. Соотвественно fold только и делает, что аллоцирует лямбды для своих аргументов.

Что с этим делать? Да ничего. Если у вас есть горячий код с фолдами, то вы, скорее всего, уже давно всё заинлайнили. Если код холодный, то оверхед вы и не заметите.

https://github.com/typelevel/cats/issues/1951
В качестве упражнения с макросами накодякал библиотечку, которая генерит конструкторы для кейс-классов с зарефайненными полями.

https://github.com/poslegm/brief

Зачем это нужно:

1. Типобезопасно провалидированные поля кейс-классов;
2. Вместо fail-fast валидации аккумулировать ошибки по всем полям;
3. В сообщениях об ошибках видеть названия проблемных полей и что пошло не так;
4. При этом не писать тонны бойлерплейта.

В планах устранение ограничений (не поддерживаются классы с тайп-параметрами и тайп-алиасы для полей) и миграция на Scala 3. Зависимость только на refined.

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

До начала работы над этой либой макросы устрашали, а оказалось, что нехитрая кодогенерация на них делается без особых сложностей.
Adam Warski написал блогпост с подробным разбором context functions из Scala 3. Если вкратце, это возможность описать тип функции с implicit параметром. Например:

type Executable[T] = ExecutionContext ?=> Future[T]

Изначально я их воспринимал просто как возможность задавать красивые тайп-алиасы, чтобы не писать постоянно (implicit ec: ExecutionContext). Но всё же это более мощный механизм, и Adam в своём посте это раскрывает.

У меня глаз зацепился за один из примеров применения — проброс соединения к БД через методы для объединения их вызовов в одну транзакцию. То есть использование некоего Connected[IO[T]] вместо ConnectionIO[T] из doobie.

Это даёт больше гибкости в коде, но пропадает одна из моих любимых особенностей скаловых библиотек для работы с RDBMS: функции, обращающиеся к базе, оперируют специфичной монадкой (ConnectionIO/DBIO), которая композится только с себеподобными, и не позволяет без костылей вкорячить в транзакцию какой-нибудь тормозной сайд-эффект. Разделять транзакционный код вокруг базы и внешние эффекты приложения на уровне типов — это здорово и безопасно.

https://blog.softwaremill.com/context-is-king-20f533474cb3
Deadline

Прочитал «Deadline» Тома Демарко. Хорошая книжка по руководству проектами, читается за два вечера. Уровень графомании приемлемый, буллщитометр критических отметок не достигал. Начинающим менеджерам смело рекомендую.

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

Управление проектом — это управление людьми, работающими над проектом.

Работа руководителя делается не в час Х, а до него. Во время интенсивной работы над проектом команда уже должна знать, что делать, и идти по налаженным процессам. Задача руководителя — подготовить команду и процессы.

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

Не существует краткосрочных мер увеличения производительности команды. Производительность — результат долгосрочных усилий.

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

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

Коллективной принятие решений эффективно. Собрать вокруг себя близких по духу профессионалов — залог успешного принятия решений.

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

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

https://www.youtube.com/watch?v=-xRfJcwhy7A
Наткнулся на гитхабе на экспериментальную библиотеку, улучшающую читаемость скаловых стектрейсов

https://github.com/VirtusLab/stacktracebuddy

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

Делается это забавным образом: джавовый стектрейс содержит имя файла и номер строки кода. По этим данным ищется соответствующий TASTy файл, сгенерированный компилятором, и из него извлекается скала-специфичная информация.

К проду не готово, да и перфоманс не блещет (на каждый стектрейс читается TASTy), но концептуально красиво.
Постов давно не было, потому что ушёл в чтение литературы по управлению. Дочитал супер-крутую книжку по менеджменту: Первые 90 дней (Майкл Уоткинс). Максимально содержательное чтиво, ни капли воды. Систематизированное повествование о том, что руководитель должен сделать в свои первые три месяца на новой должности. Хотя акцент сделан на адаптационном периоде, это самые качественно структурированные знания по руководству как таковому. Поэтому читать книгу есть смысл в любой карьерный момент.

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

Во время чтения собирал конспект, но однозначно рекомендую читать оригинал, потому что информация в нём и так подаётся в лаконичном виде.
В EPFL не только релизят третью скалу, но и продолжают шатать монадки. Вслед за заходами в async/await и effects as abilities появилась экспериментальная библиотека Monadic Reflection (от создателя не менее экспериментального scala-effect).

И это очередная попытка избавиться от необходимости писать flatMap или for-comprehension при работе с монадками. То есть вместо

for
_ <- f()
_ <- g()
yield ()

Предлагается написать

f()
g()

А дальше оно само скомпозится.

Библиотека работает только с Project Loom (если до сех пор не знаете о Loom, бегом читать / смотреть). Каждый шаг монадической композиции запускается на лумовом continuation. Вот примерчик с ZIO.

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

Выглядит интересно, и возможно такие эксперименты приведут индустрию в светлое будущее со ссылочной прозрачностью императивного кода без накладных расходов на синтаксис. Но на мой взгляд написание флэтмапов не сильно снижает продуктивность разработчика, поэтому непонятна выгода от их оптимизации. Те же abilities выглядят интереснее.
Мелочь, а приятно: в третьей скале можно не придумывать имена для контекстных параметров.

def f(fut: Future[Int])(using ExecutionContext): Future[String] =
fut.map(_.toString)

вместо

def f(fut: Future[Int])(implicit ec: ExecutionContext): Future[String] =
fut.map(_.toString)

из второй скалы.

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

Подробнее о контекстных абстракциях хорошо написано в документации.
Написал небольшую библиотеку с интеграцией ZIO и MUnit

https://github.com/poslegm/munit-zio

Мне нравится MUnit за его простоту, минималистичность и наглядные сообщения об ошибках. Чего нельзя сказать о «нативном» для ZIO zio-test: это очень сложный фреймворк с кучей ассершенов, незадокументированных методов провайдинга зависимостей и аспектов.

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

А ещё вся документация по munit-zio умещается в README, а полной документации по zio-test в принципе не существует.