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
Забавные коаны про гит. О консистентности комманд прямо в точку

https://stevelosh.com/blog/2013/04/git-koans
Не люблю зашитые в код недетерменированные функции, например, получение текущего времени. В передовых методиках функционального программирования можно заинъектить часы в код через F[_]: Clock или ZIO[Clock, E, A], но даже без них гораздо лучше сделать

trait Clock {
def nanoTime(): Long
}


и прокидывать в свои классы его, а не хардкодить там System.nanoTime.

Тогда в тестах можно будет подставить константу вместо настоящего времени и проверить, что она корректно прописывается во все нужные места.

Аналогично для всяких рандомов, гуидов и прочего.
Ух ты, что есть — анимированная документация по основным комбинаторам ZIO

https://zio.surge.sh/

Покрыты пока далеко не все фичи, но особенно на Schedule выглядит очень наглядно
Очень подробный рассказ про конкарренси под капотом у скаловых монадок. Понятно расписано, как работают легковесные потоки (файберы) поверх jvm-тредпулов, сами тредпулы, и как всё это взаимодействует с нашими цепочками .flatMap. Более цельной и детальной информации на эту тему пока не видел, автор определённо заслуживает звёздочки на гитхабе 😉

https://github.com/slouc/concurrency-in-scala-with-ce
Долгий интересный разговор про использование ReasonML в продакшене, и почему не тайпскрипт (потому что ансаунд). ResonML — это попытка фейсбука адаптировать OCaml под нужды фронтенда. Синтаксис, конечно, испортили скобочками, но в остальном это тот же самый окамл.

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

https://www.youtube.com/watch?v=nZDN6XCM1X0
Alexandru Nedelcu опубликовал блогпост с размышлениями о flow-sensitive typing на примере старого-доброго Option#get из скалы. Если вкратце, flow-sensitive typing — это когда

if (option.nonEmpty) {
println(option.get) // ← проходит проверку компилятора
} else {
println(option.get) // ← упадёт с ошибкой
}


Такое активно используется в тайпскрипте и котлине.

И что могу сказать: ДА, ОЧЕНЬ ХОЧЕТСЯ. Казалось бы, уже в 2.13 появились literal types, а в третьей скале будут дизъюнкции типов. Поэтому есть надежда, что через какое-то время отпадёт необходимость запрещать Option#get в линтерах.

https://alexn.org/blog/2020/11/12/i-like-option-get.html
Роб Норрис опубликовал маленькую библиотечку, которая умеет получать название типа в рантайме. Такая легковесная альтернатива TypeTag для логирования типа выражения.

@ import org.tpolecat.typename._
import org.tpolecat.typename._

@ def log[T](expr: T)(implicit typeName: TypeName[T]): String = s"expression of type ${typeName.value} with value ${expr}"
defined function log

@ log(List(1, 2, 3))
res3: String = "expression of type List[Int] with value List(1, 2, 3)"


Тем более библиотека состоит из макроса на три строчки, который можно просто стащить себе в проект.

https://github.com/tpolecat/typename

И, раз такое дело, грех не вспомнить библиотеку sourcecode, которой очень удобно вытаскивать названия функций и автоматически подставлять их в названия метрик.
Увидел в канале про Rust (кстати, рекомендую) пост о том, как сделать паттерн-матчинг строк с выделением их составных частей. Например, разматчить строку по известному префиксу: https://news.1rj.ru/str/dereference_pointer_there/1366

Задумался о том, как написать то же самое в скале. Оказалось, что с 2.13 уже и писать ничего не надо: в стандартной библиотеке есть решение для матчинга не просто префиксов, а любых частей интерполированных строк!

"I love Scala" match {
case s"I $feeling $language" => Map(language -> feeling)
case other => Map.empty
}

Работает эта радость за линейное время по вот такому алгоритму: https://research.swtch.com/glob
Параллельная компиляция и диаграммы билдов в новой версии скала-плагина для IDEA — огонь. Выражаю признательность разработчикам JetBrains.
Авито уже два года держит на гитхабе и актуализирует описание своей организационной структуры. Там всё: грейды разработчиков и руководителей, структура команд, perfomance review.

Из того, что было наиболее интересно:
Архитектурный комитет. Дизайн-ревью проектов принято проводить не только внутри команды, но и с привлечением экспертов из других команд. По идее это помогает избежать взращивания внутри команды несогласованных с остальной компанией подходов. И сразу же получить взгляд со стороны внешних сервисов, которые могут быть негативно затронуты новым решением;
→ Исследованием инцидентов и управлением работой над ошибками занимаются QA, а не разработчики или SRE. А ведь действительно логично, что аварии в продукте не проходят мимо ответственных за качество продукта 🙂
→ Сформулировали самое важное требование для джуна, которое никак не могло кристаллизоваться в моей голове — «Не повторяет одинаковых ошибок»;
→ Инженерное визионерство прописано в требованиях только для Lead-разработчика, для Senior — только проактивное исправление проблем в текущей архитектуре. В моих влажных мечтах эти требования сдвинуты на грейд ниже: визионером должен быть уже Senior, а зоркий глаз на проблемы в проекте и миддлам неплохо бы иметь;
→ Много внимания уделено доведению глобальных задач. Уже джун должен понимать, как его задачи в спринте связанны с целями компании на квартал. А сеньор должен участвовать в постановке таких целей.

Я почитал с огромным удовольствием: https://github.com/avito-tech/playbook
Гетерогенные списки из коробки в Scala 3!

Как обычно позже всех узнал, что помимо прочих фич для тайп-левельного программирования, в стандартной библиотеке скалки основательно переделали тюплы. Завезли множество полезных операций, для которых в Scala 2 надо тащить в зависимости shapeless и использовать HList.

Для тюплов будут доступны почти все операции над коллекциями, например, конкатенация, взятие элемента по индексу, filter, map. А компилятор при этом любовно выведет типы, проверит, что нет index out of bounds. Ну не красота же?

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

Внутри это всё построено на механизме Match Types, а узнал я об этом из блогпоста с программированием списка длинны, известной во время компиляции.
Lil Functor
Ух ты, что есть — анимированная документация по основным комбинаторам ZIO https://zio.surge.sh/ Покрыты пока далеко не все фичи, но особенно на Schedule выглядит очень наглядно
Человек, который сделал анимированную документацию по ZIO, написал вот ещё библиотеку на макросах для полуавтоматического вайринга зависимостей: достаточно перечислить нужные компоненты без ручного указания горизонтальных/вертикальных связей.

Самое крутое там — это понятная ошибка компиляции. То, что вываливает компилятор при ручном вайринге ZLayer, у меня вызывает флешбэки со стенами нечитаемых ошибок от компилятора C++

https://github.com/kitlangton/zio-magic

И раз уж речь зашла о проблемах ZIO-экосистемы... Библиотека для моков в zio-test до сих пор не умеет без костылей проверять, что метод ни разу не был вызван 🤦‍♂️
Sam Halliday интересно рассказал о потенциальных уязвимостях в библиотеках для парсинга JSON. А ещё о том, как боролся с ними в своей библиотеке

Красивая фраза в описании доклада: «Scala has more JSON libraries than Go has language features!»

https://youtu.be/3Cz6D8JLSSA
Доклад Adam Warski о том, как метапрограммировать в третьей скале

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

Видео: https://www.youtube.com/watch?v=leIB5tvDY64
Исходники из доклада: https://github.com/adamw/scala3-macro-pres
Forwarded from Consensus
📚 Классный open source курс по распределенным системам от PingCap:
👉 https://github.com/pingcap/talent-plan

В этом курсе можно зафигачить Raft и Percolator на rust.
Либо на golang сделать распределенную key-value или relational базу данных.

В курсе все подробно расписано по шагам. Подойдет для тех, кто имеет минимальный опыт на golang/rust и умеет пользоваться гитом. Курс не подойдет тем, кто хочет выучить язык с нуля(вначале придется прочитать Rust Book или пройти A Tour of Go, этого будет достаточно).
Разбор «бессерверных» архитектур на сайте Фаулера заставил крепко задуматься. С одной стороны FaaS даёт максимальную гранулярность компонент и легчайшее горизонтальное масштабирование. С другой стороны добавляются проблемы с задержкой из-за холодных стартов и оркестрацией циклопических графов зависимостей между серверлесс-компонентами. А серверлесс — это не только самописные функции, но и внешние проприетарные бэкенды, с которыми тоже надо как-то жить (например, Auth0).

Касательно применимости кажется, что реалтаймовые API в FaaS особо не засунешь как раз из-за холодных стартов. А вот консюмеры-шедулеры на формат FaaS ложатся отлично: им задержка на старте не страшна. Это удобно, потому что сбой отдельного процесса проще мониторить в изоляции от остальных, ну и автоскейлинг в придачу. Для переиспользования кода можно держать несколько функций в одном репозитории, как и в обычном сервисе. Провайдеру доставлять джарник с общим кодом и указание в конфиге, какую из функций надо дёрнуть.

Всё это выглядит как неминуемо приближающееся будущее.

https://martinfowler.com/articles/serverless.html
Forwarded from PONV Daily (Danila Matveev)
#scala #tf

Опубликовали лекцию с рассказом и кодом о тэглесс файнал. Она адресована прежде всего тем кто не знает, что это такое, или изучавшим по твиттам Де Гуза, Трампа и роскомнадзора. Но полезна может быть всем.

Если вам интересна эта тема, хотите видеть продолжения, готовы поддержать лектора и его команду:
* Подписывайтесь на ютуп канал.
* Ставьте колокольчик.
* Задавайте вопросы в комментариях ютупа, в этом чате, в тофу чате.
* Пишите код на работе и в личных проектах, помогайте кодом и документацией чужим опен сорсам.

https://www.youtube.com/watch?v=ZNK57IXgr3M
Отладка grpc-сервисов с радостью и улыбкой

Ну очень крутая штука для отладки grpc-сервисов (если на сервере включена рефлексия).

https://github.com/fullstorydev/grpcui

Просто пишешь в терминале grpcui -plaintext localhost:6000 , чтобы в браузере появилась админка к сервису, построенная по его прото-схеме. Причём там не просто отображается список методов, но и поля запроса рендерятся в нужный тип UI-контролов.

Для запросов не из UI, а из командой строки есть grpcurl. Там тоже можно получить список методов сервиса и прочие ништяки.

И в отличие от http это всё идёт из коробки, не надо генерировать или описывать сваггер.
К началу 2021 года уже забыл о существовании goto, но оказалось, что в голанге его вполне себе пишут. С помощью @oleg_log нашёл пример даже элегантного использования: внутри итерации цикла возврат на её начало с изменением внешнего стейта.

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

https://github.com/VictoriaMetrics/VictoriaMetrics/blob/e59de98384481d7873c8eca35be8d0ad9d598bb6/lib/storage/part_search.go#L229-L277
Простая статья о том, как будет работать варианс в пересечённых и объединённых типах Scala 3. Если вкратце, то интуитивно, кроме контравариантных правил, которые моей интуиции почему-то не поддаются :c

Для ковариантного C:
C[A] | C[B] <: C[A | B]
C[A & B] <: C[A] & C[B]

Для контравариантного C:
C[A | B] <: C[A]
C[A | B] <: C[B]
C[A | B] <: C[A] & C[B]


https://ayushm4489.medium.com/union-and-intersection-types-in-scala-3-6b5f7e818dc4