JSON, YAML, TOML, HCL - за последние годы человечество успело изобрести десяток языков для конфигурации.
Каждый обещал быть "простым", "удобным" и "читаемым человеком".
Но по факту - все они страдают от одних и тех же проблем: шумный синтаксис, хрупкие отступы, бесконечные кавычки и отсутствие элементарных возможностей вроде модульности и слияния конфигов.
Пора перестать с этим мириться и сделать конфигурации наконец человеческими.
? Перестаньте
утомлять глаза, пытаясь разобраться в тонне бесполезных кавычек
утомлять глаза, пытаясь распознать в каком месте есть проблема с отступом
писать велосипед, когда в очередной раз нужно мержить конфиги для разных окружений
писать велосипед, когда нужно парсить env переменные в структуру конфига
забивать мозг, пытаясь разобраться в огромной конфигурации из-за отсутствия модульности
⁉️ Как перестать?
Использовать адекватный язык для конфигурации ATMC
ATMC - минималистичный, но мощный язык конфигурации, созданный для удобного описания системных настроек.
Он сочетает простоту синтаксиса, поддержку импортов, переопределений, гибкого слияния конфигов и переменные окружения.
? Почему ATMC?
-
топовый синтаксис
супер минималистичный
интуитивно понятный и простой
не перегружен конструкциями
не зависит от отступов, переносов, кавычек, запятых и прочей чепухи
очень простой и в то же время достаточно мощный
-
модульность
можно импортировать разные кусочки (модули) конфига
очень минималистичный синтаксис импорта
можно обращаться к вложенным полям импортированного конфига
-
слияние конфигов (киллер фича)
супер легко мерджить несколько конфигов (например, common + stg или prod)
есть возможность переопределять поля
умное слияние - рекурсивное - не перетирает поле полностью
-
встраивание
можно встраивать объекты и массивы с помощью spread (...) оператора
с помощью него же и происходит слияние
-
доступ к env переменным
$YOUR_ENV_VARIABLE
-
поддержка всех необходимых типов
int
float
string
bool
object
array
компиляция в структуру и мапу из коробки
поддержка комментариев
-
расширяемость:
можно получить итоговый AST со всеми резовленными значениями
можно сделать на этой основе компилятор во что угодно
в перспективе можно поддержать LSP
? Примеры использования
Простой пример
?File: config.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
}
Пример с импортом
?File: config.atmc
db ./database.atmc // Супер минималистичный импорт
{
logging: {
level: ["warn", "error"]
}
database: db // Тут появится объект из импортированного файла
}
?File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример с spread + env
?File: config.atmc
db ./database.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME // Будет подставленно значение из env
password: $POSTGRES_PASSWORD
}
db... // Сюда встроится импортированный конфиг
}
}
?File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример с доступом к вложенному полю
?File: config.atmc
db ./database.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME // Будет подставленно значение из env
password: $POSTGRES_PASSWORD
}
clickhouse: db.clickhouse // Сюда будет встроен вложенный в db объект
}
}
?File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример со слиянием
?File: common.atmc
{
logging: {
level: ["error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME
password: $POSTGRES_PASSWORD
host: "localhost"
port: 5432
}
}
}
?File: prod.atmc - конфиг для prod окружения
common ./common.atmc
{
common... // Встраивается общий конфиг
// Далее добавляются новые параметры и переопределяются параметры из общего конфига
logging: {
level: ["warn", "error"] // Переопределяется
enable_tracing: true // Добавляется новое поле
}
database: {
postgres: {
port: 6432 // Переопределяется только порт, остальные поля не будут затронуты
}
}
}
?File: stage.atmc - конфиг для stage окружения
common ./common.atmc
{
common... // Встраивается общий конфиг
// Далее добавляются новые параметры и переопределяются параметры из общего конфига
logging: {
// Переопределяется - можно без запятых
level: [
"info"
"warn"
"error"
]
}
}
⚙️ Что под капотом?
Язык конфигурации работает благодаря множеству компонентов:
-
lexer
преобразует код в токены
-
parser
преобразует токены в AST
-
analyzer
проверяет семантику в рамках одного AST
проверяет наличие неиспользованных переменных
проверяет использование неопределенных переменных
-
linker
резолвит значения переменных из всех связанных AST
резолвит значения переменных среды
выдает один итоговый AST
-
processor
получает на вход путь до файла с конфигом
запускает все необходимые компоненты для обработки всех связанных файлов
отдает полученный итого��ый AST после линковки
-
compiler
компилирует итоговый AST
компиляторы могут быть разными (в map, в struct и т.д.)
? Поддержка и интеграция
Язык написан пока только на Go, соответственно работает только для этого языка программирования.
В дальнейшем планируется поддержка других платформ
? В планах
-
компиляция в самого себя
будет удобно смотреть итоговый конфиг
можно будет выводить итоговый конфиг, как это делает, например,
nginx -T
-
кодогенерация структур на базе конфига
тогда описывать конфиг придется только в одном месте - в atmc файле
-
автоматическая загрузка env переменных из .env файла
сейчас такого нет - нужно будет самим загружать, чтобы они стали доступны в os.Getenv
но будет удобно, если добавить
подсветка синтаксиса
-
имплементация LSP
умная подсветка синтаксиса
подсказки
поиск определений и помощь в импортах
P.S. Знаю, что уже есть похожие языки, но у всех есть свои недостатки. Где-то приятный синтаксис, но нет модульности; где-то есть модульность, но нет слияния; а где-то есть всё, но язык излишне усложнён. В ATMC есть всё нужное - и ничего лишнего.
Моя цель - сделать конфигурации такими же простыми, как Go-код: предсказуемыми, читаемыми и расширяемыми.
? Репозиторий и примеры: https://github.com/atmxlab/atmc
Комментарии (43)

Autochthon
10.11.2025 14:30Лучше S-выражений еще ничто человечество не придумало.

nin-jin
10.11.2025 14:30Придумало: https://page.hyoo.ru/#!=8i7ao7_xfyxah

Autochthon
10.11.2025 14:30Нет ничего более нелепого чем форматы в которых отступы определяют вложенность. В таких форматах даже копи паста нормально не работает, а все гладко и удобно только в голове у авторов.

inkelyad
10.11.2025 14:30копи паста нормально не работает,
Если редактор не тупо захватывает пробелы в начале и их вставляет, а понимает, что блок копирует и делает (де)индент по месту вставки - работает. Ну или умеет по TAB/Shift-TAB отступ выделения менять - тогда немного ручной работы есть.
Но да, в nano редактировать неудобно.

pilot114
10.11.2025 14:30Модульность и слияние нужно реализовать не как фичу самих конфигов, а в том месте где они подключаются, после декодирования - и при этом вообще не зависеть от формата - вот куда усилия приложить надо, а не в изобретение json диалекта

supermetrolog Автор
10.11.2025 14:30Такое реализовать на самом деле не сложно - можно любой формат переложить в мапу, сделать это несколько раз для нескольких файлов и сделать мердж
Так и делают чаще всего
Но что не нравится в таком подходе:
- список файлов определяется в приложении - то есть без просмотра кода конфигурацию не прочесть
- без просмотра кода не понять, по каким правилам строится конфигурация - кто кого переопределяет и все такое
Ну и моя версия включает в себя некоторые другие фичи, которые таким образом не реализовать или можно реализовать, но с помощью костылей

kez
10.11.2025 14:30Основная проблема всех "статичных" языков не в синтаксисе (хотя насчёт ямла можно поспорить), а в том, что в этих языках нет синтаксических конструкций для избежания копипасты.
HCL пытается с этим что-то делать, вводя модули, но не забывая вводить магические переменные для описания циклов — что, по мне, отвратительно, и начинает напоминать Ansible с его декларативными конструкциями, которые на практике оказываются просто нетипизируемым ямлом. Ямл тоже пытается избежать копипасты со своими anchors, и
<<, но, опять же, на практике это превращается в просто месиво.Итого, потребность в хорошем языке для конфигов действительно есть.
В статье отсутствует какое-либо сравнение с существующими языками, включая плюсы и минусы каждого из них. Понятно, что ATMC яыляется более "выразительным", и более абстрактным, нежели JSON, YAML etc. Поэтому также стоит сравнить с Pkl, dhall, CUE, jsonnet и другими.
По статье, не доконца понял
можно ли отрендерить/экспоритировать .atmc конфиг в другие форматы?
как сделать ключ с пробелом?
можно ли сделать циклы?
пофейлится ли конфиг с одинаковыми ключами или есть какое-то правило?
при рекурсивном мерже, мержатся ли списки или просто перезаписываются?
Ещё много вопросов можно задать, но думать лень

user-book
10.11.2025 14:30YAML как раз позволяет "копипастить" причем довольно гибко, можно указывать шаблон, а потом докидывать и перезаписывать конкретные параметры, это не Ansible-приколы а часть стандарта
вообще из опыта конфиг нужно строить универсальным:
хочешь пихай json
хочешь yml или что то вообще странное
хочешь запускай без конфига вообще
хочешь укажи всего пару через cli параметры
решать за клиента как ему лучше самая порочная практика. Автор статьи вообще создал уже существующее неоднократно, есть куча похожих json-подобных языков конфигурации

inkelyad
10.11.2025 14:30Итого, потребность в хорошем языке для конфигов действительно есть.
Есть необходимость различать язык конфигов и язык программирования. Как только потребовалось что-то вроде циклов - нужно брать полноценный существующий и им и пользоваться, урезав возможности для того чтобы убрать всякие уязвимости.
Еще препроцессором можно начать пользоваться и генерировать полный конфиг из кусочков. Но опять же не забывать, что превращать конфиг в полноценный скрипт - вредно для понимаемости.

kez
10.11.2025 14:30урезав возможности для того чтобы убрать всякие уязвимости.
или просто использовать уже готовый язык, с урезанными возможностями, хорошим тулингом и имплементацией с минимальным количеством зависимостей (чтобы уменьшить риск уязвимостей)
но в целом это субъектившина

supermetrolog Автор
10.11.2025 14:30но не забывая вводить магические переменные для описания циклов — что, по мне, отвратительно
Согласен - поэтому такого у меня не будет - это все-таки язык конфигурации, а не язык программирования
> можно ли отрендерить/экспоритировать .atmc конфиг в другие форматы?
Сейчас можно только в JSON - причем это ненастоящая компиляция в json - применен такой хак: компилим в мапу, а из мапы в json с помощью стандартного пакета - в будущем можно сделать нормальную компиляция, но пока и так сойдет - можем себе позволить так как скорость компиляции не имеет значения:)
Больше ни во что нельзя
В планах компилировать в самого себя - то есть выдать один конфиг с отрезолвленными значениями - думаю будет удобно дебажить, как это позволяет делатьnginx -T
> как сделать ключ с пробелом?
Никак. А надо?
> можно ли сделать циклы?
Если это про циклические зависимости, то нет - детектится и выдается ошибка
> пофейлится ли конфиг с одинаковыми ключами или есть какое-то правило?
Нет, не пофейлится - можно переопределить значения - это не то чтобы фича - просто так работает - возможно стоит запретить, а то потом такую проблему фиг отыщешь
> при рекурсивном мерже, мержатся ли списки или просто перезаписываются?
Массивы перезаписываются - мердж не позволит переопределить значения в нем, так как ключей там нет, как в объектах
kez
10.11.2025 14:30все-таки язык конфигурации, а не язык программирования
Встаём на тонкий лёд споров об определениях. Является ли ваш
х...и ямловый<<: *aтем же самым, что и питоновскоеa | { ... }? Если да, то почему одно является язком программирования, а другое нет?Язык программирования не обязательно должен быть развесистым как питон, даже простенький DSL может являтся ЯПом. Также, к счастью, перечисленные мной конкуренты (CUE, jsonnet, Pkl, dhall) не являются generic-purpose язками, и некоторые даже не являются turing complete.
Было бы интересно увидеть подробное сравнение вашего языка и перечисленных.
как сделать ключ с пробелом?
Никак. А надо?
Получается, что язык даже не является суперсетом JSON. Но если серьёзо отвечать на вопрос, то да, конечно надо.
можно ли сделать циклы?
Если это про циклические зависимости, то нет - детектится и выдается ошибка
Нет, речь про циклы, конечно, а-ля
for item in ...или подобные способы избежать копипасты кода. Особенно полезно при модификации списков, учитывая что рекурсивный мерж просто обновит значение (что в целом логично, и правильно)В целом свой язык конфигов прикольно, хорошее занятие.
От себя могу добавить (и там в треде выше уже упомянули), что при работе с огромным количеством конфигов действительно хочется иметь простой не-тьюринг полный язык для избежания дедупликации всего по нескольку раз, и для этого нужны абстракции в виде циклов, условий, и т.п. Но это субъективно конечно. Моё мнение в основном совпадает с этой статьёй https://ruudvanasseldonk.com/2025/abstraction-not-syntax.

supermetrolog Автор
10.11.2025 14:30Если да, то почему одно является язком программирования, а другое нет?
Ну смотря, что считать языком программирования - я считаю языком программирования тюринг полный язык - соответсвенно мой язык под эту категорию не подходит
> Было бы интересно увидеть подробное сравнение вашего языка и перечисленных.
Ага, как-нибудь распишу
> даже не является суперсетом JSON.
Почему это плохо?
> Но если серьёзо отвечать на вопрос, то да, конечно надо.
Кому и зачем это надо? Никогда не видел, чтобы пробелы в конфигурации использовались
Если действительно надо, хотелось бы пример какой-нибудь, где без этого не обойтись
А если для галочки, чтобы стать суперсетом JSON, то думаю можно обойтись без этого
> Нет, речь про циклы, конечно, а-ляfor item in ...или подобные способы избежать копипасты кода. Особенно полезно при модификации списков, учитывая что рекурсивный мерж просто обновит значение (что в целом логично, и правильно)
Что-то мне, кажется, что это дикий оверхед, который нужен 1% разрабов/проектов
Такая сложная логика должна быть на уровне приложения, а не на уровне конфигурации
Не очень понимаю, какая конфигурация с массивом должна быть, чтобы аж циклы понадобились
Возможно мы в очень разных сферах работаем, поэтому мне эта тема не близка и я ее не понимаюВ целом идея сделать максимально простой язык, который закрывает 99% потребностей
А вот этот 1%, где циклы нужны или еще какая-то экзотика уж лучше не покрывать
А из статьи с примером копипасты и замены его на цикл, я предпочту копипасту - намного читабельнее и не позволит разрабам городить дичь, используя такие сложные конструкции
Ну и в довесок в ATMC можно обращаться к полям импортированного конфига
То есть значения, которые дублируются можно вынести отдельно и обращаться к ним, а не копировать - по итогу можно будет изменить значение в одном месте и поменяется везде
Ну в общем не понимаю я циклы эти в конфигах - они меня пугают
---
Перечитал свой ответ и вижу, что ни с чем особо не согласился по итогу - но хочу сказать, что в любом случае спасибо за фидбек - это очень полезно для меня - много нового узнал:)
kez
10.11.2025 14:30Без проблем. Опять же, у меня свой юзкейс для кучи деплойментов на десятки серверов, с кучей зависимых друг от друга частей, у вас — свой.
Могу сказать что в проде у нас для конфигов используется смесь ямла и питона (ворклоады либо определены прямо в питоне, либо питон парсит ямл и выплёвывает объект ворклоада). Так можно валидировать всё и вся. Например, можно статически на этапе сборки и проверки конфигов построить файл-мап всех портов которые должны быть открыты публично или только во внутренней подсети. Питон в целом нормально, но немного геморно, в основном потому, что нужно слишком много дата процессинга писать чтобы сконверить один ворклоад в нужный формат. (У питона есть и другие проблемы, но мы их опустим)
Было бы неплохо для этого использовать какой-нибудь простенький язык, но мы решили остаться на питоне, потому что остальные куски инфры уже были на нём. Но в целом я думаю какой-нибудь CUE бы нам подошёл.
Удачи вам с вашим языком конфигов, посмотрим как будет развиваться

SWATOPLUS
10.11.2025 14:30Почему не писать конфиги на Typescript? Тут и импорты и экспрорты и типы для валидации, а потом это все компилировать в json? А если эти конфиги редактирует 3rd party, то напишите им компилятор в json или же https://github.com/laverdet/isolated-vm

NeoCode
10.11.2025 14:30https://json5.org , это не оно?

supermetrolog Автор
10.11.2025 14:30Неа, не оно
Насколько вижу, там нет фич, которые есть в ATMC (импорты, мерджи)
Но синтаксис похож, да - ну это не удивительно, ведь я ориентировался на js-ные объекты

Ru6aKa
10.11.2025 14:30Как только встает вопрос про валидацию сложного конфига, то оказывается что кроме JSON c JSON Schema больше ничего и нету.
Да и у этого решения тоже есть проблема, object или array никак не прокинешь из переменных окружения.

supermetrolog Автор
10.11.2025 14:30Да и у этого решения тоже есть проблема, object или array никак не прокинешь из переменных окружения.
Интересная идея
Мне такое не пригождалось никогда, поэтому даже не задумывался о таком
Может есть примеры, где такой функционал хотелось бы иметь?
Ru6aKa
10.11.2025 14:30array - список реплик для чтения, список endpoint-ов для каких-то запросов, список доступных языков, список доступных валют. Обычно приходиться колхозить что-то типа
DATABASE_REPLICA_1,DATABASE_REPLICA_2и тд. и ваш конфиг типа такого{ database: { replicas: $DATABASE_REPLICA_* } } что развернеться в { database: { replicas: [$DATABASE_REPLICA_1, $DATABASE_REPLICA_2] } }
object - тут чуть сложнее с примерами, они более редкие, это может быть например конфигурация oauth провайдеров, и будет что-то типаOAUTH_GOOGLE_ID,OAAUTH_GOOGLE_SECRET,OAUTH_APPLE_ID,OAUTH_APPLE_SECRETи тд. и ваш конфиг типа такого{ oauth: $OAAUTH_$ } что развернеться в { oauth: { google: { id: $OAUTH_GOOGLE_ID, secret: $OAAUTH_GOOGLE_SECRET }, apple: { id: $OAUTH_APPLE_ID, secret: $OAUTH_APPLE_SECRET } } }

kez
10.11.2025 14:30оказывается что кроме JSON c JSON Schema больше ничего и нету.
это, конечно, не так, есть как минимум CUE и несколько других вариантов

unicorn_style
10.11.2025 14:30Лично для меня yaml куда более читабелен чем пример который в статье. Опыт подсказывает что конфиг хорош такой, который можно править руками через nano «в особых случаях». YAML хоть я его и не люблю это делать позволяет без проблем, как и обычный config
А на тему “больших» конфигов где еще и модульность нужна - история уже про GUI , либо централизованная раздача конфигов через сеть. В каком они там формате уже будут - параллельно
Итого, без обид, но проблема высосана из пальца.

supermetrolog Автор
10.11.2025 14:30Опыт подсказывает что конфиг хорош такой, который можно править руками через nano «в особых случаях». YAML хоть я его и не люблю это делать позволяет без проблем, как и обычный config
Почему вы считаете, что ATMC нельзя так же править руками?
На мой взгляд его править даже удобнее, чем тот же yml, потому что в nano не видно ни пробелов ни табов и ошибиться с отступом в большом конфиге будет очень просто
Даже в IDE часто можно затупить с отступом. В прочем со скобкой тоже можно затупить:)
unicorn_style
10.11.2025 14:30Почему вы считаете, что ATMC нельзя так же править руками?
Просто для меня скобки фигурные которые показывают вложенность – не humanlike формат, вот и все
На мой взгляд его править даже удобнее, чем тот же yml, потому что в nano не видно ни пробелов ни табов и ошибиться с отступом в большом конфиге будет очень просто
При аварийной правке есть гениально простые решения:
В корне лежит всегда default.yaml/conf как пример
При редактировании конфигурация копируется с приставкой backup
Это позволяет полностью забыть о спецсиволах даже когда накосячил с ними, все восстанавливается или просто копируется из существующих
Ну а если прям задача найти проблема: "cat -A файл" отобразит скрытое
Странно что я это объясняю, будто бы вы не понимаете как реально строится программное обеспечениеДаже в IDE часто можно затупить с отступом. В прочем со скобкой тоже можно затупить:)
Возможно "Даже" возникнет в вашем IDE, и тут только совет его поменять. А к примеру в VSCode затупить с yaml конфигурацией - это что-то нереальное. На тему скобок, тут тоже вопросы. На тему скобок тоже не понимаю, не помню вообще когда последний раз скобки ставил клавишей. Конкретный IDE на Golang по первым буквам func/switch+Enter сразу рисует необходимый блок автоматически со всеми скобками и ставит указатель на имя, потом +tab и можно заполнить аргументы...и тд

supermetrolog Автор
10.11.2025 14:30Лично для меня yaml куда более читабелен чем пример который в статье.
Да, для меня тоже
Тут проблема примеров просто - в реальности конфиги в 100 раз больше - там то и начинаются проблемы
unicorn_style
10.11.2025 14:30Я рад что есть разработчики которые делают простыни конфигураций, к примеру такие можно найти на mysql и прочий софт. Но там хорошо, настроил один раз и забыл на большой период времени (в большинстве случаев)
Но если конфиги такие что еще надо постоянно что-то там менят, подкручивать или объединять и это сотнями строк в yaml/conf/ATMC файлах и все это без GUI – то думаю для таких программистов в аду есть отдельный котел
К слову, мы для своих систем писали раздачу конфигурации с сервера, т.е в приложение вшито или в конфиге адрес API точки доступа куда приложение обращается при запуске и тянет с сервера ту конфигурацию которая актуальна и можно даже пушить настройки + GUI где можно поменять настройки полностью для любого приложения. Когда мы создавали пакеты, ничего подобного и дельного не нашли. Вот таких систем не хватает...PS: Хотя может плохо искали
supermetrolog Автор
10.11.2025 14:30Мне вот интересно, что вы предпримете в таких условиях:
- вы начинаете новый проект
- понимаете, что конфигурация для prod и stg будут отличаться
- например, на prod нужно 10 воркеров для аутбокса, а на stg всего 5, чтобы не ушатать слабые машины на stg
Как вы поступите тут? Как будете конфигурировать приложение?
unicorn_style
10.11.2025 14:30Этот вопрос почти в вакууме, но у меня есть пример монолитного приложения и которое на prod жрет как не в себя. После деплоя в папке лежит test.yaml / prod.yaml.
Для проверки на prod после deploy мы запускаем с test.yaml где зажаты все гайки в том числе количество потоков и ограничения (просто для проверки что приложение запускается и корректно переваривает данные), далее уже запускаем as service, но с prod.yaml.
Поэтому задачу stg/prod я решал бы абсолютно так же, просто в конфиге прописывались все ограничения или даже вводим бы вшитый механизм а-ля ключ запуска: stg/prod, в том числе можно вшить механизм оценки того сколько конкретная "машина" может держать потоков на базе информации о системе.
Другое вопрос если у вас в конфиге например ограничения описываются более чем 2-3 переменными (как в моем примере, т.к у нас все ограничения потоков описаны двумя строчками конфигурации).Я понимаю что можно сделать монолит поставив к примеру 100500 endpoint точек API и на каждую повесить воркер с ограничением и потом успешно это в конфигурацию вынести отдельно, но опять же такие истории предполагают уж изменения конфигурации налету. При deploy нового подобного приложения собирается аналитика или при атаке на endpoint вносятся PUSH ограничения и тут мы опять приходим к централизации и GUI

supermetrolog Автор
10.11.2025 14:30раздачу конфигурации с сервера
А на сервере, как оно конфигурировалось? Через UI и в базе лежало?

unicorn_style
10.11.2025 14:30У нас сейчас все хранится в mysql базе, GUI и сервер раздачи написал chatgpt. Нам надо было срочно решение с GUI.
Пакет тоже написал chatgpt для стыковки. Сейчас стараемся во весь софт сделать это обновление.
При старте приложения просто ./app --config=имя_приложения
Он по имени обращается на API вшитый в код и ему отдается JSON готовый из базы. Сделано на коленке, увы пока так и времени доделать нет. Но работает уже год и все довольны. Осталось весь софт перевести на эту историюВообще считаю что mysql это была ошибка, потенциальная точка отказа. Лучше в файлах...
Вот кстати ваш формат можно было к этому приспособить...т.к вы сами предположили что конфиги могут быть большими...Ну пускай в одном файле будет сразу много конфигураций и при запросе нужный кусок отдается по HTTP
Основная беда в том что mysql очень плохо переживает сбои если не настроена репликация (пс у нас она не настроена), т.е если что у нас будут веселые ночи. Если бы конфигурация была упакована в единый файл к примеру с вашим форматом...то вопрос бекапа – вопрос простого копирования. И если что-то случилось можно быстро перекинуть бек и загрузить новый экземпляр раздачи.

andrey_27
10.11.2025 14:30Забавно. Упрекать шум, а потом использовать фигурные скобки и кавычки, что и есть самый неприятный шум в конфигах.
YAML навсегда!

supermetrolog Автор
10.11.2025 14:30Кавычки только для строк
Скобки позволяют хоть в одну строку писать конфиг
Причем скобки для массивов в yml тоже есть - можно и без них, если на новой строке писать - ну вот уже несколько способов сделать одно и тоже - не очень нравится
Ну и плюс скобки более четко визуально группируют данные - ну это ИМХО, конечно

kez
10.11.2025 14:30В ямле
noэто строка "no" или false? (И там ещё много примеров, можно погуглить по "yaml from hell")Уж лучше явные строки чем гадать на кофейной гуще, и вычленять различия версий 1.0, 1.1, 1.2 (речь про ямл спек, конечно же)

Hackitect7
10.11.2025 14:30Ваша статья получилась очень близкой к тому, о чём многие регулярно вздыхают: усталость от бесконечных отступов и кавычек в YAML/JSON и желание наконец-то просто описывать настройки. Идея вынести импорт, слияние и подстановку переменных в отдельный, простой DSL - звучит заманчиво. Примеры синтаксиса понятно читаются, особенно нравятся лаконичные импорты и
spread‑оператор.
Есть, правда, пара вопросов, которые было бы интересно обсудить. Например, как ATMC ведёт себя при конфликте типов при слиянии двух конфигов или что происходит, если ключ встречается в нескольких местах? Планируется ли типовая проверка, чтобы ловить подобные ошибки заранее? Как вы видите дальнейшее развитие проекта: будет ли поддержка других языков помимо Go и есть ли планы на интеграцию с редакторами (подсветка, автодополнение)? Сейчас конфигурационных DSL уже довольно много (HOCON, Dhall, CUE), любопытно было бы увидеть сравнение ATMC с ними.
В целом же направление классное: хочется, чтобы конфиги были такими же предсказуемыми и приятными, как код.
Удачи в развитии!
supermetrolog Автор
10.11.2025 14:30как ATMC ведёт себя при конфликте типов при слиянии двух конфигов или что происходит, если ключ встречается в нескольких местах?
В любом случае по итогу ключ будет всегда один на выходе - каждый будет переопределять предыдущий - тип ключа будет таким, какой он был у последнего ключа, который переопределил предыдуший
Планируется ли типовая проверка, чтобы ловить подобные ошибки заранее?
Даже не задумывался, пока не спросили. Вообще думаю хорошо бы завести такую проверку - поможет быстро находить ошибки в конфигурации
> Как вы видите дальнейшее развитие проекта: будет ли поддержка других языков помимо Go
Если язык заимеет хоть какой-нибудь успех на языке Go, то да
Иначе, кажется, это пустая трата времении есть ли планы на интеграцию с редакторами (подсветка, автодополнение)
Есть. Использую язык для своих проектов - чувствую, как без хотя бы подсветки жить тяжело (но все равно лучше, чем с json или yml :))
> любопытно было бы увидеть сравнение ATMC с ними
Выше тоже это подмечали. А я просто не хотел раздувать статью
Может быть распишу сравнение позже

SergeyProkhorenko
10.11.2025 14:30Подкину для обсуждения свеженький (но уже 12.7k stars) формат TOON (https://github.com/toon-format/toon), созданный для экономной передачи в LLM огромного количества данных, вплоть до содержимого целой базы данных. Это сильно модифицированный гибрид YAML и CSV. Сам по себе он мне понравился для моих целей (а это вовсе не общение с LLM, а передача данных в 6NF). Он практически идеален: почти нет визуального мусора, многократно меньше строк, чем в JSON. Одним щелчком вставляется в Excel в правильные столбцы (я в качестве разделителей выбрал табы). Но спецификация огромная и при этом отрывочная и неудобная. Пока не сконвертировал вручную JSON в TOON (см. мой пример), на что ушло много времни, ничего не было понятно. Поэтому есть сомнения, что все конверторы будут работать одинаково, хотя их уже много понаделали. Конверсия из JSON в TOON, к сожалению, односторонняя, если я правильно понял. Возможно, что это поправят. Три часа назад вышла версия 1.0.0.
Статьи о нем:
Is JSON Dead? Meet TOON – The Token-Efficient Alternative for LLM Prompts
JSON vs TOON – Token-efficient data format for LLMs
Landgraph
Шутка про n-стандартов…
ИМХО, когда конфиг становится сложнее, чем можно описать в ini файле - что-то пошло не так. И этот конфиг уже перестает быть человекочитаемым и лучше уже иметь какой-то гуй.
paramtamtam
В дополнение, крайние несколько лет являюсь адептом секты "config-less", когда все что нужно сконфигурировать - должно иметь cli/env ручки для этого, и знаете - этот подход более чем жизнеспособен! И строгие правила, и валидация, и генерация документации из этого кода - прям хорошо. Да что уж говорить - великий и могучий Traefik и тот умеет себя конфигурировать флагами без сильной боли ниже поясницы (если понимаешь что делаешь), а он тот еще комбаин.
supermetrolog Автор
На моем опыте в бизнесовых приложениях не удается обойтись простецким конфигом, который можно было бы удобно описать в ini
Во всех проектах всегда были фреймворки, которые из коробки давали модульность + слияние конфигов - и это прям надо реально. И даже для go приложений такое надо, потому как на нем мы тоже бизнесовый код пишем - сейчас мы мерджим yml
Понимаю проблему сложных конфигов, поэтому пытался найти баланс - добавил ключевые фичи, без которых нереально жить в бизнесовых приложениях ИМХО
Постарался в общем не усложнять синтаксис и читабельность конфига