Пересел недавно с джавы на котлин и начал осваивать новые сахарные возможности. На проекте у нас во многих местах используются дсл. Я люблю подобные штуки и решил освоить, как и из чего это состоит.  Дано. - На вход программе приходят текстовые команды и идентификатор пользователя. - Пользователь может находиться в разных состояниях. - В зависимости от состояния есть разные наборы команд которые возможно обработать.- Если команда не соответствует ни одной из возможных, выполняется команда по умолчанию. Для начала нужно написать саму систему, которая будет выполнять требуемые действия. Она довольно простая. У нас есть Processor, который достает состояние пользователя и передает StateProviderService команду и состояние. В ответ он получает набор возможных команд в новом состоянии. StateProviderService и ActionProviderService устроены очень похоже. В зависимости от состояния StateProviderService вызывает обработку пришедшей команды у определенного обработчика. Аналогично ActionProviderService с командами. Следующая задача - заполнить все обработчики. Если бы это был спринг, я бы написал свою аннотацию и помечал бы ей классы обработчики и с помощью бпп заполнял мапы. На этот раз я хочу решить эту проблему с помощью дсл. В котлине можно вызывать функцию apply(). Она дает доступ к содержимому объекта и с помощью нее можно удобно изменять его состояние. Проблема в том, что у такого объекта прийдется открыть все поля и сделать пустой конструктор. В случае Processor-а это выглядело бы так: Я не хочу изменять таким образом системные сервисы. Напишем билдер, который можно будет таким образом настраивать. В билдере, помимо функции получения объекта сервиса, добавим вспомогательные функции для его настройки. В некоторые функции мы передаем билдер и странно выглядящую лямбду. Такая лямбда как например ActionProviderBuilder.() -> Unit позволяет получить доступ к объекту ActionProviderBuilder, как если бы она передавалась в функцию apply. Таким образом вызвав функцию state мы получаем доступ к функциям toService, action, default у объекта класса ActionProviderBuilder внутри лямбды. Еще одна приятная особенность - в котлине если лямбда - последний аргумент, ее можно вынести за скобки. В итоге вызов функции state выглядит так: В целом результат меня уже устроил, но мне хотелось попробовать infix функции. Это такие функции, которые могут использоваться как операторы. Например я могу сделать функцию, чтобы писать "print" doing {...}. И на самом деле, для этого всего лишь надо дописать рядом с функцией action следующее: И под конец у меня появилась идея. Допустим есть одинаковые переходы из нескольких  состояний в другое. Повторять несколько раз одно и то же не хотелось бы, так что допишу еще вот такой вариант:  listOf(TestState.A, TestState.B) withAction "action" doing  {...}. Здесь я хочу для каждого из перечисленных состояний добавить выполнение некоторой логики по команде "action". Kotlin dsl великолепная вещь! После джавы я получаю огромное удовольствие от таких новых возможностей. Я не коснулся переопределения операторов в этой статье, но такое тоже возможно. Пы Сы Это переписанная версия, извиняюсь перед всеми, кто видел предыдущую. Очень хотелось быстрее написать, и видимо делать это в ночь - не самая удачная затея. Вот репозитрийВот телеграмм (я там пропал надолго, но уже вроде как вернулся)  Бэкэнд разработчик