
Scala *
Мультипарадигмальный язык программирования
Новости
Opaque Types в Scala: типобезопасность без runtime‑overhead

Строгая типизация не всегда спасает от глупых ошибок. Если userId, orderId и productId — это один и тот же Int или Long, компилятор не увидит разницы и спокойно пропустит неверный аргумент. В Scala 3 для таких случаев есть opaque types: они позволяют сделать доменные типы различимыми на этапе компиляции, но без лишних обёрток и накладных расходов в рантайме. Разберём, как это работает и чем этот подход лучше type alias, case class и AnyVal.
# 10 ошибок рефакторинга

Рефакторинг — это не уборка, это хирургия на живом коде. Большинство провалов здесь не технические: смешали рефакторинг с улучшениями, сделали один огромный коммит, затянули релиз — и три недели работы ушли в мусор. Собрал 10 ошибок из реальных проектов: с примерами кода, разбором механики и способами не наступить на те же грабли.
Хроники Agent Driven Development трансформации .1: улучшаем agent feedback loop

Как перевести продакшен-проект на рельсы agent-driven development - когда LLM-агенты становятся полноценными участниками разработки, а не просто подсказчиками в автокомплите ? Реальный опыт на реальном проекте !
Продолжаем улучшать Feedback Loop. В предыдущей статье я ускорил прогон тестов в 6 раз. Теперь — следующий шаг: LLM-агент генерирует тесты. Два подхода (sprint-driven и coverage-driven), шестиуровневый pipeline верификации, двух-агентная архитектура, оптимизация feedback loop — и 68 тестовых файлов на выходе с acceptance rate 86.8% при ревью живыми разработчиками.
В статье — конкретика: как анализировал покрытие и свежесть документации, как ускорял компиляцию для агента, на чём экономил токены, и что сказала команда на code review.
Категории типов. Часть 5½. Сопряжения из монады

В этот раз мы проанализируем различные способы факторизации монады на сопряжённые функторы. Прежде всего рассмотрим два полярных варианта, раскрывающих наиболее важные аспекты факторизации. Это даст более глубокое понимание самого понятия монады и послужит мотивацией для построения операции факторизации произвольного функтора.
Нити и волокна (Threads & Fibers)

Всем привет! Меня зовут Сергей и последнее время я занимаюсь backend-разработкой на Scala. Вообще, мой опыт асинхронного программирования на Scala и C# составляет более десяти лет, и за это время сложилось вполне достаточное понимание этой темы. Во всяком случае, тогда мне так казалось…
Но недавно в беседе с коллегами обнаружились большие проблемы в моём «понимании», что мотивировало детально разобраться в этом вопросе.
Хроники Agent Driven Development трансформации .0: Как ускорить тесты проекта в 6 раз: от 10 минут к 101 секунде

Почти 800 тестов, 10 минут на прогон, каждый пуш — ожидание на CI. Знакомо? Рассказываю, как довёл время до 101 секунды: снижение таймаутов, параллелизм ScalaTest, shared Testcontainers и защита от регрессий. Scala, SBT, PostgreSQL, GraalVM — конкретные шаги и подводные камни.
ZIO Mock не может — ScalaMock поможет

Если вы пишете тесты на ZIO, то с моками, скорее всего, уже сталкивались. И почти наверняка — с ZIO Mock. Формально он решает задачу, но на практике ломает Arrange‑Act‑Assert, «краснит» в IDEA и иногда падает так, что вы видите только InvalidCallException: null. В Яндекс Вертикалях мы довольно долго жили с этой библиотекой — пока количество таких тестов не перевалило за пару сотен и они не расползлись по десятку команд.
Меня зовут Женя Веретенников, я тимлид в Яндекс Вертикалях и последние годы занимаюсь инструментами для Scala‑разработчиков и инфраструктурой бэкенд‑монорепозитория. Когда стало ясно, что ZIO Mock больше мешает, чем помогает, мы решили отказаться от него полностью — и подружить ZIO Test с классическим ScalaMock. Он даёт более предсказуемый синтаксис и понятные ошибки, но из коробки с ZIO не работает.
В этой статье я расскажу не о том, как пользоваться новой библиотекой, а о том, как мы её делали: какие ограничения ZIO‑стека пришлось учитывать, где пришлось лезть под капот ScalaMock и ZIO Test и во что в итоге превратилась эта инженерная затея. Это история про построение собственного test tooling в большой Scala‑кодовой базе — с честными компромиссами и практическими выводами.
Сегодня я для себя открыл: Project Loom

"Loom" означает "ткацкий станок" - так назывался проект по добавлению асинхронности в джаву. Тяжёлые системные потоки заменили легковесными виртуальными потоками. Потоки и нити в английском называются одинаково - thread - отсюда название.
Проект успешно внедрили пару лет назад, и я, к сожалению, это полностью пропустил. Основная причина, конечно - что я в принципе не ожидал от джавы никаких прорывов (и оказался на 100% неправ!) Ну и, как бэкенд-разработчик на питоне, я не очень-то слежу за развитием JVM-языков.
Но исправляюсь: Project Loom - это блестящая идея. Учитывая, что его внедрили совместимым образом, и почти не было ломающих изменений. Я считаю, это оптимальная реализация асинхронности для высокоуровневого серверного языка.
Уже почти все использующие JVM языки переехали на новую версию JVM, и, таким образом, на проект Loom: деваться им некуда. Так что, есть надежда, что это изменение откроет новую главу для некоторых из них. Есть также предположение, как оно может повлиять на скриптовые языки, такие как питон. Гипотеза только.
Также, вы узнаете, почему Гвидо ван Россум не ошибся, когда добавлял async/await в питон, а Мацумото — создатель Ruby — тоже угадал, когда, наоборот, отказался от async/await.
Функциональные шаблоны: fold и unfold

Привет! Меня зовут Артём. Я Scala Tech Lead в компании “Криптонит” и автор Scalabook — русскоязычной базы знаний по Scala и функциональному программированию. В прошлой статье я разбирал можно ли программировать без циклов. Сегодня хотелось бы подлить масла в огонь и продолжить разбирать альтернативы императивным циклам в мире функционального программирования.
Данная статья посвящена свёрткам (folds) и развёрткам (unfolds). Это модели вычислений, работающие поверх рекурсивных типов данных, таких как связанные списки, деревья и т.д. Свёртки и развёртки образуют мощную пару абстракций: если свёртки предназначены для потребления рекурсивных структур данных, то развёртки ответственны за генерацию структур данных из некоторого начального состояния.
Допустим у нас есть связанный список:
Как мы мигрировали с Zeppelin и что из этого вышло. Часть 2. Формы

Это вторая (и заключительная) часть цикла статей о нашей миграции с Zeppelin. О причинах и первом опыте перехода с Zeppelin я рассказал здесь. В данной статье я хочу большее внимание уделить второму виду Zeppelin notebook, которые срочно нуждались в переносе.
Конечно, отчеты для клиентов не были настолько "забагованы" как рассылки: большая часть проблем с Zeppelin крылась именно в cron-е, который временами работал как хотел (или в интерпретаторах, мы так и не смогли разобраться, но ошибка интерпретатора возникала только когда запускали через cron). В отчетах этого звена не было, поэтому их перенос был плавным и основан скорее на особенностях UI/UX дизайна.
Данная статья может быть полезна аналитикам, которые не знают, какой инструмент использовать для своих задач и думают, что писать графический интерфейс крайне сложно (спойлер, нет), а также для команд, которые устали от Zeppelin как UI-инструмента (и от Zeppelin в целом)
Ближайшие события
Live Reload на JVM

В этой статье я хотел бы обобщить всё, что мы знаем про Hot/Live Reloading на JVM, и далее показать, как я пришел к реализации универсального Live Reloading решения для любых веб-приложений на JVM.
Вкратце, в этой статье мы:
🔹 Попробуем сформулировать, какие виды релоадинга бывают.
🔹 Подробно рассмотрим, какие реализации существуют на JVM.
🔹 И немножко обсудим детали реализации универсального решения, и что вообще к нему привело.
Создаём мини-фреймворк для MapReduce в Scala с конкретной реализацией

Статья демонстрирует построение минималистичного MapReduce-фреймворка на Scala для локальных экспериментов. Рассматриваются стадии Map, Shuffle и Reduce с ленивыми вычислениями через Iterator, а также абстракции ввода/вывода IO и локальные исполнители с виртуальными потоками.
Категории типов. Часть 5. Пределы и сопряжения функторов

Ранее мы выяснили, что монадные возможности присущи эндофункторам, основанных на определённых ковариантных обобщённых типах. Обобщённые же типы соответствуют алгебраическим выражениям, собранным из сумм, произведений и экспоненциалов типов.
В этой части обзора мы увидим, почему конструкторы типов связаны с алгебраическими операциями, и как сама эта связь порождает монады и комонады.
Санкционный while: стоит ли запретить циклы вслед за goto?

Привет, Хабр! Меня зовут Артём. Я руковожу группой Scala‑разработчиков в компании «Криптонит» и веду Scalabook — русскоязычную базу знаний по Scala и функциональному программированию. В ней можно найти другие мои статьи‑инструкции, а также примеры кода. В этой статье предлагаю обсудить циклы и связанные с ними спорные моменты.





