Продолжаем унижение скалистов. Есть такая шина для передачи сообщений — Apache Kafka. Биг дата, распределённые системы, все дела.
В своё время она была написана на Scala, а сейчас 70% кодовой базы — это отборный Java-код. Последний коммит в .scala файл датируется 2016 годом, а проект находится в состоянии перехода Scala -> Java с 2015 года.
Почему? Может быть дело в языковых конструкциях, высоком пороге входа? Или в долгой компиляции? Или в экосистеме языка? Нет. Просто у Scala нет бинарной совместимости между версиями. И разработчикам приходилось билдить и тестировать артефакты для 2.8, 2.9, 2.10, 2.11... версий компилятора. В конце концов им это надоело, и всё, кроме ядра системы, было переписано на джяву.
В своё время она была написана на 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 — тот человек, с которого стоит брать пример. А ещё у него очень интересный блог.
Li Haoyi, один из самых значимых людей в скала-сообществе, сегодня дропнул новую библиотеку — requests-scala. Это портирование отличной питоновской библиотеки requests на скалу. Либа имеет то же самое апи и практически идентичную реализацию.
Почему это важно?
Есть много http клентов для скалы. Многие из них являются частью массивных фреймворков (Akka-http, Play, http4s). Некоторые сами по себе большие и сложные проекты (sttp, dispatch). Ещё доступны клиенты из джява-мира (apache). Все они имеют тонну конфигураций, предназначены для больших нагрузок, обработки массы крайних случаев, интеграции со сторонними апи...
Но иногда хочется просто отправить запрос и получить ответ. Без конфигураций, без чтения доков, без асинхронности, без обработки всех возможных ошибок и HTTP-кодов. Просто синхронный запрос и ответ. Для таких случаев теперь есть копия requests.
Haoyi сверхестественно талантливый разработчик. Он имеет уникальное чутьё на проблемы, которые всех раздражают, но никто не берётся их осмыслить и решить. Хотите написать быстрый и удобный парсер? fastparse. Покрыть проект тестами, но не заморачиваться с фреймворками для тестирования? utest. Дефолтный репл скалы вроде бы устраивает, но хочется большего? ammonite. Создать небольшой проект и не париться с конфигами sbt? mill. И это всё сделал один человек!
Его проекты всегда простые. Для сложных задач нужны сложные решения. Но не все задачи сложны, многие из них банальны. Хочется простого и понятного инструмента, чтобы быстро с ними справится. И тут на помощь приходит Haoyi. Его проекты отлично написаны, имеют великолепное интуитивное api и подробную документацию.
Haoyi — тот человек, с которого стоит брать пример. А ещё у него очень интересный блог.
Довольно интересный доклад для расслабленного прослушивания.
Основные тезисы:
* Обозначать идентификаторы можно как угодно, главное, чтобы не возникало вопросов «что это?» и «зачем это?»
* Может быть, ваша функция на 8 строчек понятна и с переменными
* Надо помнить про кошелёк Миллера: человек может держать в голове одновременно только 5-9 объектов. Не надо перегружать читателя, пожалуйста.
И самое, на мой взгляд, важное: код пишется отрывками, но читается полностью.
https://www.youtube.com/watch?v=z5WkDQVeYU4
Основные тезисы:
* Обозначать идентификаторы можно как угодно, главное, чтобы не возникало вопросов «что это?» и «зачем это?»
* Может быть, ваша функция на 8 строчек понятна и с переменными
p, pc, ac понятна сама по себе. Но она существует как часть кодовой базы из десятков тысяч строк, и отдельно от контекста её никто читать не будет.* Надо помнить про кошелёк Миллера: человек может держать в голове одновременно только 5-9 объектов. Не надо перегружать читателя, пожалуйста.
И самое, на мой взгляд, важное: код пишется отрывками, но читается полностью.
https://www.youtube.com/watch?v=z5WkDQVeYU4
YouTube
Как называть переменные / Григорий Петров [Python Meetup 27.06.2015]
Григорий посмотрит на несерьезную и простую тему именования переменных со свойственных ему неожиданных ракурсов. Вас ждет увлекательное приключение к истокам Венгерской нотации, летопись борьбы со сложностью, обзорная экскурсия по запихиванию в код метаинформации…
Время ломать стереотипы
Бытует мнение, что программистская нотация
На самом деле это не так, и в математике существует куча способов использования этого знака. Например, для перечисления элементов множества
или Big-O нотации
Так что программистское присваивание — это не исключение из правила, а n+1 способ использования символа
Бытует мнение, что программистская нотация
x = x + 1 контринтуитивна, потому что в математика значок = всегда означает равенство объектов. На самом деле это не так, и в математике существует куча способов использования этого знака. Например, для перечисления элементов множества
A = { n/2 : n = 1, 2, 3, ..., 100 } или Big-O нотации
f(x)=O(g(x)). Так что программистское присваивание — это не исключение из правила, а n+1 способ использования символа
=.Math ∩ Programming
For mathematicians, = does not mean equality
Every now and then I hear some ridiculous things about the equals symbol. Some large subset of programmers—perhaps related to functional programmers, perhaps not—seem to think that = should only and ever mean “equality in the mathematical sense.” The argument…
Оказывается, в 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 и вот это всё на базовом уровне.
Из текущего дайджеста мне больше всего понравились две статьи:
* 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 и не париться.
#ссылки
Подборка Scala Best Practices от Alexandru Nedelcu — контрибьютора typelevel, автора Monix и cats-effect. Последнее изменение было в 2016 году, но документ совершенно не устарел. Много примеров кода и несколько годных паттернов.
Choose an open source license — сайт с подсказками по выбору лицензии для Open Source проектов, краткое изложение сути лицензий, их плюсы и минусы. TL;DR если проект маленький и в планах нет монетизации, можно брать MIT и не париться.
#ссылки
В стандартной библиотеке джявы есть очень интересный класс
Сегодня мне понадобилось создавать даты за конкретное число, и я решил воспользоваться именно этим способом. Но код почему-то не работал. Оказывается, проблема была в гениальном дизайнерском решении разработчиков первых версий джявы:
— год указывается, как номер года - 1900
— а месяцы начинаются с нуля.
Преклоняю колени.
java.util.Date. И у него есть конструктор Date(int year, int month, int date), помеченный deprecated. Мне всё время казалось странным то, что такой удобный конструктор зачем-то убрали и предлагают создавать объекты Date, указывая время в милисекундах. Ведь иногда так удобно указать просто год, месяц и день.Сегодня мне понадобилось создавать даты за конкретное число, и я решил воспользоваться именно этим способом. Но код почему-то не работал. Оказывается, проблема была в гениальном дизайнерском решении разработчиков первых версий джявы:
— год указывается, как номер года - 1900
— а месяцы начинаются с нуля.
Преклоняю колени.
Монада — это просто моноид в категории эндофункторов
Сегодня я наконец-то нашёл действительно понятное объяснение этой фразы: The Proof - Monad as a Monoid in Category of Endofunctors. Великолепная статья с разбором основ теорката для тупых. Последовательные определения моноида, моноидальной категории, моноида в категории и категории эндофункторов схлопываются в максимально простое доказательство. И, самое главное, все утверждения в статье сопровождаются кодом на скале!
Сегодня я наконец-то нашёл действительно понятное объяснение этой фразы: The Proof - Monad as a Monoid in Category of Endofunctors. Великолепная статья с разбором основ теорката для тупых. Последовательные определения моноида, моноидальной категории, моноида в категории и категории эндофункторов схлопываются в максимально простое доказательство. И, самое главное, все утверждения в статье сопровождаются кодом на скале!
Вышла Scala 2.13-M5
Самое интересное в этом майлстоуне:
* Несколько небольших изменений в библиотеке коллекций, делающих её более удобной и эффективной. И наконец-то пометили deprecated отвратительный метод mapValues, смысл существования которого был исключительно в том, чтобы доставить разработчикам проблемы с сериализацией
* Грандиозное обновление
* Завезли by-name implicits — возможность лениво передавать неявные аргументы. Благодаря этому снижается потребность в сторонних библиотеках для метапрограммирования (ну вы поняли, shapeless).
* Улучшили скорость компиляции, сделали типизацию более умной, добавили функцию
В целом релиз получился очень сочный. Радует, что это последний майлстоун перед окончательным выходом 2.13
Самое интересное в этом майлстоуне:
* Несколько небольших изменений в библиотеке коллекций, делающих её более удобной и эффективной. И наконец-то пометили 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 😸
Вчера узнал о существовании великолепного руководство по системе типов скалы — ktoso.github.io/scala-types-of-types.
Его несколько лет поддерживает Konrad Malawski, бывший участник команды разработки Akka (8 место в рейтинге контрибьюторов). Он собрал в одном месте описание буквально всего, что в языке связано с типизацией. Пособие написано максимально просто и лаконично, с обилием примеров. Этот материал определённо мастрид для всех, кто начинает изучать скалу. Мне тоже было интересно его прочитать, чтобы освежить и систематизировать знания. А сразу после прочтения добавил ссылку в свой список образовательных материалов по скале.
А ещё заработал сайт impurepics.com, на котором собраны все картинки про функциональное программирование из замечательного твиттера I'm purr-e pics 😸
Один из принципов функционального программирования — это отделение описания программы от исполнения. Есть два распространённых способа добиться этого при программировании сервисов, взаимодействующих с окружающим миром:
1. Free monad
2. Tagless Final
Нашёл на гитхабе проект с лаконичным и понятным для начинающих определением этих паттернов и сравнением реализаций на них сервиса из «реальной жизни». Проект необычен тем, что выполнен в виде ASCII презентации в репле. И это выглядит очень стильно.
Из приведённых примеров понятно, почему практически всё Scala-сообщество последние пару лет тащится от паттерна Tagless Final. По сравнению с ним фри манатки кажутся дико переусложнённым подходом с кучей бойлерплейта.
1. Free monad
2. Tagless Final
Нашёл на гитхабе проект с лаконичным и понятным для начинающих определением этих паттернов и сравнением реализаций на них сервиса из «реальной жизни». Проект необычен тем, что выполнен в виде ASCII презентации в репле. И это выглядит очень стильно.
Из приведённых примеров понятно, почему практически всё Scala-сообщество последние пару лет тащится от паттерна Tagless Final. По сравнению с ним фри манатки кажутся дико переусложнённым подходом с кучей бойлерплейта.
Слайд из проекта. А вот библиотека, которая позволяет делать такие классные слайды.
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.Immutable Documentation
Статья описывает подход к ведению документации в компании Etsy.
Документация к ПО состоит из двух подмножеств:
1. why-doc — описание причин возникновения программы, стандартных юзкейсов и ключевых идей, заложенных в неё;
2. how-doc — инструкция по использованию, выдержки из кода, разбор частных случаев.
По ходу развития ПО устаревает в основном how-doc.
Для внутренних разработок можно пренебречь полнотой how-doc в пользу актуальности. Для этого в Etsy сделали бота в слаке, в которого программисты могут пушить свежие знания о системах напрямую из рабочих переписок. Таким образом документация превращается в лог сообщений. Чем свежее сообщение в логе, тем больше вероятность того, что информация в нём актуальна.
А why-doc по-прежнему пишется в вики/README.
На мой взгляд, самый большой плюс этого подхода в том, что формирование базы знаний идёт неразрывно от рабочих обсуждений. Устранён сам процесс ведения документации.
#ссылки
Статья описывает подход к ведению документации в компании Etsy.
Документация к ПО состоит из двух подмножеств:
1. why-doc — описание причин возникновения программы, стандартных юзкейсов и ключевых идей, заложенных в неё;
2. how-doc — инструкция по использованию, выдержки из кода, разбор частных случаев.
По ходу развития ПО устаревает в основном how-doc.
Для внутренних разработок можно пренебречь полнотой how-doc в пользу актуальности. Для этого в Etsy сделали бота в слаке, в которого программисты могут пушить свежие знания о системах напрямую из рабочих переписок. Таким образом документация превращается в лог сообщений. Чем свежее сообщение в логе, тем больше вероятность того, что информация в нём актуальна.
А why-doc по-прежнему пишется в вики/README.
На мой взгляд, самый большой плюс этого подхода в том, что формирование базы знаний идёт неразрывно от рабочих обсуждений. Устранён сам процесс ведения документации.
#ссылки