Lil Functor
795 subscribers
57 photos
1 file
183 links
Pure functional and composable channel

Чат: https://t.iss.one/+L-xb_m_4lnY3Y2Fi
Download Telegram
Scala Puzzlers

Книжка на пару вечеров про подводные камни компилятора скалы. Содержит 36 примеров того, как не надо программировать.

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

Вышло видео доклада John A. De Goes с отличной критикой современного состояния Scala-экосистемы. Позитивная повестка довольно абстрактна, но это не проблема, потому что это доклад про «Кто виноват?», а не «Что делать?».

Озвученные проблемы:

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

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

3. Маркетинг скалы сосёт. Пока голанг продаётся, как язык для быстрой разработки эффективных высоконагруженных приложений, скалку подают под соусом возможности совмещать ООП и ФП. Акцент делается не на решении задач бизнеса, а на академических интересах;

4. Есть вероятность (примерно 100%), что грядущий релиз Scala 3 создаст такой же коллапс с параллельным развитием версий, как у питона. Крупным компаниям будет тяжело обновиться со второй версии;

5. Утечка кадров из сообщества, внутренние междусобойчики, политика внутри инженерного сообщества;

6. В Scala 3 пытаются пропихнуть пару фич, которые не нужны ни одной из частей скала-сообщества. Фичи ради фич приведут к усложнению языка (куда уж больше?), но не принесут реальной пользы, потому что часть людей уже использует библиотеки, реализующие то же самое, а остальным это в принципе не нужно.

Предложения:

1. Брать пример с Котлина: больше документации, больше тулинга, больше надёжности;

2. Не делать мертворождённых проектов ради PhD у аспирантов Одерски;

3. Не распыляться в попытках впихнуть весь опыт компьютерных наук в один язык. Делать меньше вещей, но делать их лучше;

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

Видео выступления: https://www.youtube.com/watch?v=v8IQ-X2HkGE
Продолжаем унижение скалистов. Есть такая шина для передачи сообщений — Apache Kafka. Биг дата, распределённые системы, все дела.

В своё время она была написана на Scala, а сейчас 70% кодовой базы — это отборный Java-код. Последний коммит в .scala файл датируется 2016 годом, а проект находится в состоянии перехода Scala -> Java с 2015 года.

Почему? Может быть дело в языковых конструкциях, высоком пороге входа? Или в долгой компиляции? Или в экосистеме языка? Нет. Просто у Scala нет бинарной совместимости между версиями. И разработчикам приходилось билдить и тестировать артефакты для 2.8, 2.9, 2.10, 2.11... версий компилятора. В конце концов им это надоело, и всё, кроме ядра системы, было переписано на джяву.
Решил перед сном посмотреть ленту гитхаба, и не зря.
Li Haoyi, один из самых значимых людей в скала-сообществе, сегодня дропнул новую библиотеку — requests-scala. Это портирование отличной питоновской библиотеки requests на скалу. Либа имеет то же самое апи и практически идентичную реализацию.

Почему это важно?

Есть много http клентов для скалы. Многие из них являются частью массивных фреймворков (Akka-http, Play, http4s). Некоторые сами по себе большие и сложные проекты (sttp, dispatch). Ещё доступны клиенты из джява-мира (apache). Все они имеют тонну конфигураций, предназначены для больших нагрузок, обработки массы крайних случаев, интеграции со сторонними апи...

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

Haoyi сверхестественно талантливый разработчик. Он имеет уникальное чутьё на проблемы, которые всех раздражают, но никто не берётся их осмыслить и решить. Хотите написать быстрый и удобный парсер? fastparse. Покрыть проект тестами, но не заморачиваться с фреймворками для тестирования? utest. Дефолтный репл скалы вроде бы устраивает, но хочется большего? ammonite. Создать небольшой проект и не париться с конфигами sbt? mill. И это всё сделал один человек!

Его проекты всегда простые. Для сложных задач нужны сложные решения. Но не все задачи сложны, многие из них банальны. Хочется простого и понятного инструмента, чтобы быстро с ними справится. И тут на помощь приходит Haoyi. Его проекты отлично написаны, имеют великолепное интуитивное api и подробную документацию.

Haoyi — тот человек, с которого стоит брать пример. А ещё у него очень интересный блог.
Сравнение размеров формальных грамматик разных языков программирования. Совершенно неожиданно «сложные» языки Scala и Haskell описываются проще, чем Swift, Kotlin и Java 🙃
Довольно интересный доклад для расслабленного прослушивания.

Основные тезисы:
* Обозначать идентификаторы можно как угодно, главное, чтобы не возникало вопросов «что это?» и «зачем это?»
* Может быть, ваша функция на 8 строчек понятна и с переменными p, pc, ac понятна сама по себе. Но она существует как часть кодовой базы из десятков тысяч строк, и отдельно от контекста её никто читать не будет.
* Надо помнить про кошелёк Миллера: человек может держать в голове одновременно только 5-9 объектов. Не надо перегружать читателя, пожалуйста.

И самое, на мой взгляд, важное: код пишется отрывками, но читается полностью.

https://www.youtube.com/watch?v=z5WkDQVeYU4
Время ломать стереотипы

Бытует мнение, что программистская нотация x = x + 1 контринтуитивна, потому что в математика значок = всегда означает равенство объектов.

На самом деле это не так, и в математике существует куча способов использования этого знака. Например, для перечисления элементов множества
A = { n/2 : n = 1, 2, 3, ..., 100 }
или Big-O нотации
f(x)=O(g(x)).

Так что программистское присваивание — это не исключение из правила, а n+1 способ использования символа =.
Оказывается, в Disney программируют на Scala, и даже составляют еженедельные дайджесты интересных событий из скала-мира.

Из текущего дайджеста мне больше всего понравились две статьи:

* Akka anti-patterns: too many actors TL;DR: не надо плодить сущности без необходимости (иначе будет страдать производительность системы). А ещё в этом блоге есть список из 15 антипаттернов для Akka. Можно поиграть в бинго на своём проекте 🐭

* Kinds of types in Scala, part 1: types, what are they? объяснение сути строгой типизации как таковой и её реализации в Scala. Вывод типов, ADT и вот это всё на базовом уровне.
Годные ссылочки на сегодня:

Подборка Scala Best Practices от Alexandru Nedelcu — контрибьютора typelevel, автора Monix и cats-effect. Последнее изменение было в 2016 году, но документ совершенно не устарел. Много примеров кода и несколько годных паттернов.

Choose an open source license — сайт с подсказками по выбору лицензии для Open Source проектов, краткое изложение сути лицензий, их плюсы и минусы. TL;DR если проект маленький и в планах нет монетизации, можно брать MIT и не париться.

#ссылки
В стандартной библиотеке джявы есть очень интересный класс java.util.Date. И у него есть конструктор Date(int year, int month, int date), помеченный deprecated. Мне всё время казалось странным то, что такой удобный конструктор зачем-то убрали и предлагают создавать объекты Date, указывая время в милисекундах. Ведь иногда так удобно указать просто год, месяц и день.

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

Преклоняю колени.
This media is not supported in your browser
VIEW IN TELEGRAM
Монада — это просто моноид в категории эндофункторов

Сегодня я наконец-то нашёл действительно понятное объяснение этой фразы: The Proof - Monad as a Monoid in Category of Endofunctors. Великолепная статья с разбором основ теорката для тупых. Последовательные определения моноида, моноидальной категории, моноида в категории и категории эндофункторов схлопываются в максимально простое доказательство. И, самое главное, все утверждения в статье сопровождаются кодом на скале!
Вышла Scala 2.13-M5

Самое интересное в этом майлстоуне:

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

* Грандиозное обновление scala.concurrent.Future. Пока команды scalaz и typelevel мерялись производительностью своих IO-монадок, стандартная библиотека считалась медленной по умолчанию. После релиза многие бенчмарки придётся пересмотреть 🚀

* Завезли by-name implicits — возможность лениво передавать неявные аргументы. Благодаря этому снижается потребность в сторонних библиотеках для метапрограммирования (ну вы поняли, shapeless).

* Улучшили скорость компиляции, сделали типизацию более умной, добавили функцию pipe (аналог эрланговского |>) и scala.util.Using (аналог Bracket из котоэффектов).

В целом релиз получился очень сочный. Радует, что это последний майлстоун перед окончательным выходом 2.13
Тем временем в Go всё-таки обещают завезти дженерики

Больше не придётся писать свою функцию max для интов!
Scala's Types of Types [я вернулся]

Вчера узнал о существовании великолепного руководство по системе типов скалы — ktoso.github.io/scala-types-of-types.

Его несколько лет поддерживает Konrad Malawski, бывший участник команды разработки Akka (8 место в рейтинге контрибьюторов). Он собрал в одном месте описание буквально всего, что в языке связано с типизацией. Пособие написано максимально просто и лаконично, с обилием примеров. Этот материал определённо мастрид для всех, кто начинает изучать скалу. Мне тоже было интересно его прочитать, чтобы освежить и систематизировать знания. А сразу после прочтения добавил ссылку в свой список образовательных материалов по скале.

А ещё заработал сайт impurepics.com, на котором собраны все картинки про функциональное программирование из замечательного твиттера I'm purr-e pics 😸
А вы удивляетесь, что IDEA тормозит
Один из принципов функционального программирования — это отделение описания программы от исполнения. Есть два распространённых способа добиться этого при программировании сервисов, взаимодействующих с окружающим миром:
1. Free monad
2. Tagless Final

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

Из приведённых примеров понятно, почему практически всё Scala-сообщество последние пару лет тащится от паттерна Tagless Final. По сравнению с ним фри манатки кажутся дико переусложнённым подходом с кучей бойлерплейта.
Слайд из проекта. А вот библиотека, которая позволяет делать такие классные слайды.
eto ya тащу монадки в проект
GitHub и Travis CI — это пример блестящей интеграции облачных сервисов.

Предвкушая настройку автоматического билда и прогона тестов для своего репозитория, я готовился к классической боли: огромные конфиги, настройка окружений, установка зависимостей...

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

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

Раньше стандартной практикой для кодирования на джяве были названия пакетов в духе org.apache.kafka.clients вместо просто kafka.clients. С появление скалы, кложи и котлина обновлённое сообщество критически пересмотрело эту традицию. В молодых jvm-based языках авторы библиотек называют пакеты по-человечески, чтобы видеть в коде
import cats.data.NonEmptyList
вместо
import org.typelevel.cats.data.NonEmptyList

А люди, которые очень любят доменные имена, просто регают домены, соответствующие названию самой либы. Таким образом и соблюдается традиция, и не зашумляются импорты:
import org.http4s.dsl._

Это относится как к библиотечным модулям, так и к приложениям. Больше не обязательно в своём проекте создавать лишний слой вложенности ради домена. Вместо package com.enterprise.rogaandcopyta ничто не мешает создать package rogaandcopyta.