Forwarded from Scala Nishtyaki Channel
У скалалаза появился теперь свой канал, где можно и посмотреть тлдр о выпуске и даже прослушать его; жойнитесь!
https://www.tg-me.com/scalalaz_podcast
https://www.tg-me.com/scalalaz_podcast
Telegram
Scalalaz Podcast audio feed
постим сюда копии аудио - пока в ручную
Кстати говоря у нас есть репа https://github.com/scalalaz-podcast/scalalaz-gen/ так что если есть опечатки или еще какие проблемы, можно и пры делать и ишши создавать
Кстати говоря у нас есть репа https://github.com/scalalaz-podcast/scalalaz-gen/ так что если есть опечатки или еще какие проблемы, можно и пры делать и ишши создавать
Копаясь в скала-коде восьмилетней выдержки, узнал, как раньше скалисты парсили json. Был в стандартной библиотеке модуль parser-combinators для описания разного рода грамматик. Ну а в нём, соответственно, готовый парсер json.
Как можно представить json в языке с сильной системой типов и мощным компилятором? Через ADT, покрывающее типами все возможные варианты значений? Можно, но есть вариант попроще —
Ну и функция для парсинга, возвращающая
Сейчас всё это дело удалено из стд, задепрекейчено и остаётся висеть на гитхабе артефактом древних времён https://github.com/scala/scala-parser-combinators/tree/1.1.x
Как можно представить json в языке с сильной системой типов и мощным компилятором? Через ADT, покрывающее типами все возможные варианты значений? Можно, но есть вариант попроще —
Map[String, Any]
. А массив джсонов — List[Any]
.Ну и функция для парсинга, возвращающая
Option[Any]
, где в Any
может быть либо Map[String, Any]
, либо List[Any]
😊. Не смотрел по истории коммитов, был ли уже в стандартной библиотеке на момент написания этого кода тип Either
, но вряд ли он бы сильно помог. Короче, такое вот тайплевельное программирование на максимуме, это вам не в circe кодеки макросами выводить.Сейчас всё это дело удалено из стд, задепрекейчено и остаётся висеть на гитхабе артефактом древних времён https://github.com/scala/scala-parser-combinators/tree/1.1.x
Вчера вышел релиз ZIO 1.0, и по этому поводу Дегуз написал большой блогпост про разработку библиотеки от прототипа до консалтинговой компании. История подробная, с упоминанием основных технических решений, их мотивации, и людей, работающих над ними. Редко получается проследить историю развития софта в живом рассказе, а не по коммитам.
https://ziverge.com/blog/zio-1.0/
https://ziverge.com/blog/zio-1.0/
Я сделал ещё один канал, на который буду сбрасывать понравившуюся мне музыку. Преимущественно электронная сцена. Существенную часть этой музыки я слушаю во время работы, так что может быть другим программистам она тоже будет интересна.
Милости прошу к своей кибердиджейке — @choreus
Милости прошу к своей кибердиджейке — @choreus
Нашёл маленький, едва заметный шанс на то, что в третьей скале исправят одну из самых раздражающих меня штук:
Тут компилятор выводит тип результата по первому списку аргументов как
Удручает то, что в пулл-реквесте с исправлением не было коммитов с мая, но вдруг случится чудо https://github.com/lampepfl/dotty/pull/9076
Ещё там подробно и простым языком расписано решение, так что можно понять, что происходит, не разбираясь в кишках компилятора.
Option(42).fold(Nil)(x => List(x, x, x)) // not compiles
Тут компилятор выводит тип результата по первому списку аргументов как
Nil
, и не может догадаться, что List[Int]
является его супертипом. В итоге приходится писать тип рукамиOption(42).fold(List.empty[Int])(x => List(x, x, x))
Удручает то, что в пулл-реквесте с исправлением не было коммитов с мая, но вдруг случится чудо https://github.com/lampepfl/dotty/pull/9076
Ещё там подробно и простым языком расписано решение, так что можно понять, что происходит, не разбираясь в кишках компилятора.
Забавные коаны про гит. О консистентности комманд прямо в точку
https://stevelosh.com/blog/2013/04/git-koans
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 выглядит очень наглядно
https://zio.surge.sh/
Покрыты пока далеко не все фичи, но особенно на Schedule выглядит очень наглядно
Очень подробный рассказ про конкарренси под капотом у скаловых монадок. Понятно расписано, как работают легковесные потоки (файберы) поверх jvm-тредпулов, сами тредпулы, и как всё это взаимодействует с нашими цепочками
https://github.com/slouc/concurrency-in-scala-with-ce
.flatMap
. Более цельной и детальной информации на эту тему пока не видел, автор определённо заслуживает звёздочки на гитхабе 😉https://github.com/slouc/concurrency-in-scala-with-ce
GitHub
GitHub - slouc/concurrency-in-scala-with-ce: Introduction to concepts of asynchronous and concurrent programming in Scala, based…
Introduction to concepts of asynchronous and concurrent programming in Scala, based on the Cats Effect library. - slouc/concurrency-in-scala-with-ce
Долгий интересный разговор про использование ReasonML в продакшене, и почему не тайпскрипт (потому что ансаунд). ResonML — это попытка фейсбука адаптировать OCaml под нужды фронтенда. Синтаксис, конечно, испортили скобочками, но в остальном это тот же самый окамл.
При попытках работать с тайпскриптом меня удручала его «особенность» компилировать код, в котором типы на самом деле не сходились. На втором месте по уровню раздражения была необходимость постоянно помогать компилятору в местах, где он не может вывести типы. Ризон этих проблем лишён, но количество программистов на рынке, конечно, хех мда.
https://www.youtube.com/watch?v=nZDN6XCM1X0
При попытках работать с тайпскриптом меня удручала его «особенность» компилировать код, в котором типы на самом деле не сходились. На втором месте по уровню раздражения была необходимость постоянно помогать компилятору в местах, где он не может вывести типы. Ризон этих проблем лишён, но количество программистов на рынке, конечно, хех мда.
https://www.youtube.com/watch?v=nZDN6XCM1X0
YouTube
TypeScript - это трата времени. Год с #ReasonML на продакшене
Почему TypeScript - трата времени, Flow чуть получше, но все равно победил ReasonML? Про сильные стороны и фейспалм.
Антон Тужик, Frontend Developer из SEMrush рассказывает про год использования ReasonML в продакшене.
00:00 - Вступление
00:33 - Из геолога…
Антон Тужик, Frontend Developer из SEMrush рассказывает про год использования ReasonML в продакшене.
00:00 - Вступление
00:33 - Из геолога…
Alexandru Nedelcu опубликовал блогпост с размышлениями о flow-sensitive typing на примере старого-доброго
Такое активно используется в тайпскрипте и котлине.
И что могу сказать: ДА, ОЧЕНЬ ХОЧЕТСЯ. Казалось бы, уже в 2.13 появились literal types, а в третьей скале будут дизъюнкции типов. Поэтому есть надежда, что через какое-то время отпадёт необходимость запрещать
https://alexn.org/blog/2020/11/12/i-like-option-get.html
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 для логирования типа выражения.
Тем более библиотека состоит из макроса на три строчки, который можно просто стащить себе в проект.
https://github.com/tpolecat/typename
И, раз такое дело, грех не вспомнить библиотеку sourcecode, которой очень удобно вытаскивать названия функций и автоматически подставлять их в названия метрик.
@ 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://www.tg-me.com/dereference_pointer_there/1366
Задумался о том, как написать то же самое в скале. Оказалось, что с 2.13 уже и писать ничего не надо: в стандартной библиотеке есть решение для матчинга не просто префиксов, а любых частей интерполированных строк!
Задумался о том, как написать то же самое в скале. Оказалось, что с 2.13 уже и писать ничего не надо: в стандартной библиотеке есть решение для матчинга не просто префиксов, а любых частей интерполированных строк!
"I love Scala" match {Работает эта радость за линейное время по вот такому алгоритму: https://research.swtch.com/glob
case s"I $feeling $language" => Map(language -> feeling)
case other => Map.empty
}
Telegram
Блог*
#prog #rust #моё
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
Параллельная компиляция и диаграммы билдов в новой версии скала-плагина для IDEA — огонь. Выражаю признательность разработчикам JetBrains.
Авито уже два года держит на гитхабе и актуализирует описание своей организационной структуры. Там всё: грейды разработчиков и руководителей, структура команд, perfomance review.
Из того, что было наиболее интересно:
→ Архитектурный комитет. Дизайн-ревью проектов принято проводить не только внутри команды, но и с привлечением экспертов из других команд. По идее это помогает избежать взращивания внутри команды несогласованных с остальной компанией подходов. И сразу же получить взгляд со стороны внешних сервисов, которые могут быть негативно затронуты новым решением;
→ Исследованием инцидентов и управлением работой над ошибками занимаются QA, а не разработчики или SRE. А ведь действительно логично, что аварии в продукте не проходят мимо ответственных за качество продукта 🙂
→ Сформулировали самое важное требование для джуна, которое никак не могло кристаллизоваться в моей голове — «Не повторяет одинаковых ошибок»;
→ Инженерное визионерство прописано в требованиях только для Lead-разработчика, для Senior — только проактивное исправление проблем в текущей архитектуре. В моих влажных мечтах эти требования сдвинуты на грейд ниже: визионером должен быть уже Senior, а зоркий глаз на проблемы в проекте и миддлам неплохо бы иметь;
→ Много внимания уделено доведению глобальных задач. Уже джун должен понимать, как его задачи в спринте связанны с целями компании на квартал. А сеньор должен участвовать в постановке таких целей.
Я почитал с огромным удовольствием: https://github.com/avito-tech/playbook
Из того, что было наиболее интересно:
→ Архитектурный комитет. Дизайн-ревью проектов принято проводить не только внутри команды, но и с привлечением экспертов из других команд. По идее это помогает избежать взращивания внутри команды несогласованных с остальной компанией подходов. И сразу же получить взгляд со стороны внешних сервисов, которые могут быть негативно затронуты новым решением;
→ Исследованием инцидентов и управлением работой над ошибками занимаются QA, а не разработчики или SRE. А ведь действительно логично, что аварии в продукте не проходят мимо ответственных за качество продукта 🙂
→ Сформулировали самое важное требование для джуна, которое никак не могло кристаллизоваться в моей голове — «Не повторяет одинаковых ошибок»;
→ Инженерное визионерство прописано в требованиях только для Lead-разработчика, для Senior — только проактивное исправление проблем в текущей архитектуре. В моих влажных мечтах эти требования сдвинуты на грейд ниже: визионером должен быть уже Senior, а зоркий глаз на проблемы в проекте и миддлам неплохо бы иметь;
→ Много внимания уделено доведению глобальных задач. Уже джун должен понимать, как его задачи в спринте связанны с целями компании на квартал. А сеньор должен участвовать в постановке таких целей.
Я почитал с огромным удовольствием: https://github.com/avito-tech/playbook
Гетерогенные списки из коробки в Scala 3!
Как обычно позже всех узнал, что помимо прочих фич для тайп-левельного программирования, в стандартной библиотеке скалки основательно переделали тюплы. Завезли множество полезных операций, для которых в Scala 2 надо тащить в зависимости shapeless и использовать HList.
Для тюплов будут доступны почти все операции над коллекциями, например, конкатенация, взятие элемента по индексу,
Накидал несколько примеров использования новых фич.
Внутри это всё построено на механизме Match Types, а узнал я об этом из блогпоста с программированием списка длинны, известной во время компиляции.
Как обычно позже всех узнал, что помимо прочих фич для тайп-левельного программирования, в стандартной библиотеке скалки основательно переделали тюплы. Завезли множество полезных операций, для которых в 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 до сих пор не умеет без костылей проверять, что метод ни разу не был вызван 🤦♂️
Самое крутое там — это понятная ошибка компиляции. То, что вываливает компилятор при ручном вайринге ZLayer, у меня вызывает флешбэки со стенами нечитаемых ошибок от компилятора C++
https://github.com/kitlangton/zio-magic
И раз уж речь зашла о проблемах ZIO-экосистемы... Библиотека для моков в zio-test до сих пор не умеет без костылей проверять, что метод ни разу не был вызван 🤦♂️