LINUX.ORG.RU

Tree как универсальный формат общения программ и людей

 , , , ,


0

2

Есть прикольный формат данных, который может использоваться для простого создания DSL-ей под различные нужды: от конфигов и межсерверной коммуникации, до программирования и логирования.

Он в 2 раза компактнее XML, в 20 раз проще YAML, в 2 раза быстрее JSON.

Он является бинарным, но человекопонятным, но не требует экранирования, но парсится как машиной так и человеком предельно однозначно.

Нативная модель данных у него похожа на XML, но без всех его сложностей и куда более гибкая. Он вообще сам себе AST.

Несколько интересных идей, как он может использоваться, в чём он особо хорош:

  • удобные расширяемые конфиги
  • структурированное логирование
  • коммуникация любых консольных утилит без парсинга текста регулярками

Подробно о нём тут: https://page.hyoo.ru/#!=8i7ao7_xfyxah

А вкратце тут: https://github.com/nin-jin/tree.d

Тут пример использования спец DSL для добавления подсветки синтаксиса для своего DSL за 3 минуты: https://www.youtube.com/watch?v=33k5ryVu0Uc

А тут пример пайплайна его обработки на js: https://page.hyoo.ru/#!=b6c11q_ocy5oh

Ну а здесь онлайн песочница с разными трансформациями: https://tree.hyoo.ru/

Что думаете об этом всём? Пока что есть реализациии лишь на D и TS, почти нет тулинга. Не хотели бы присоединиться к развитию?



Последнее исправление: nin-jin (всего исправлений: 2)

Если вы хотите чтоб ваша идея в каком-то виде взлетела - вам надо провести анализ потребностей.

И как мне кажется то, в каком виде оно изобретено сейчас - это что-то низкоуровневое. Сказать в 2023м «давайте сделаем DSL наших конфигов поверх tree, а не поверх байтов или yaml» - это как сказать в 2013м «давайте сделаем DSL-язык разработки, который будет компилироваться не в машинный код, не в java-исходник, а в webassembly».

Что я хочу сказать этим сравнением:

  1. для того чтоб идея взлетела, а не похоронилась - нужно попасть в нишу потребностей

  2. сейчас оно такое низкоуровневое, что ближе не к формату данных, а к инструменту разработки форматов. Больше похоже не на замену YAML, а на замену байтовых последовательностей.

Подход «сделаем крутую базу, пусть каждый доделывает её в DSL по своему вкусу» - это как C++ до 2011 или как jabber. Дикая путаница и отсутствие стандартизации. Пример: хороша ли гибкость, позволяющая добавить в разных DSL несколько разных вариантов записи комментариев? Нет, не хороша, это генератор путаницы.

И, как ни странно если речь идёт о человеко-читаемости - то над единственным спецсимволом \ тоже имхо стоит подумать. Сейчас он смотрится нелогично, это же не экранирование.

GPFault ★★
()
Последнее исправление: GPFault (всего исправлений: 1)
Ответ на: комментарий от Forum0888

Хотелось бы посмотреть спецификацию бинарного формата.

tree .is .optional .list_of line
line .is .sequence
	.optional indent
	.optional nodes
	new_line
nodes .is .sequence
	.optional .list_of struct
	.optional data
	.with_delimiter space
struct .is .list_of .byte
	.except special
data .is .sequence
	data_prefix
	.optional .list_of .byte
		.except new_line
special .is .any_of
	new_line
	data_prefix
	indent
	space
new_line .is .byte \0A
indent .is .list_of .byte \09
data_prefix .is .byte \5C
space .is .list_of .byte \20
X512 ★★★★★
()
Ответ на: комментарий от Forum0888

Нет. Они задают иерархию. Семантику отступов проблематично выразить в виде формальной контекстно-независимой грамматики.

Я так понимаю в этом языке грамматики ‘.list_of’ означает повтор один или более раза. Для повтора начиная с нуля раз надо писать .optional .list_of.

То есть .optional в .optional indent нужен чтобы разрешить нулевое количество табов.

https://github.com/nin-jin/tree.d/wiki/grammar.tree

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 2)
Ответ на: комментарий от X512

Эммм… минимализм конечно хорошо, но ТС болел за скорость. Загрузка комментариев (их же можно повыкидывать) на скорости сказывается плохо.

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

Спасибо!

AntonI ★★★★★
()
Ответ на: комментарий от GPFault

Так яндекс уже пытался навязать всем свой стандарт BEM с раССово-верными названиям КСС-селекторов дебилы долго это говно пиарили, в итоге начали требовать знания оного при устройстве формошлепом, а потом как-то само собой забыли про него. Агрессивный маркетинг тоже не всегда помогает.

uwuwuu
()
Ответ на: комментарий от X512

Исходя из спецификации, дескрипторы

new_line .is .byte \0A
indent .is .list_of .byte \09
data_prefix .is .byte \5C
space .is .list_of .byte \20
как раз и определяют структуру дерева.

И никаких правил, определяющих отступы нет.

Впрочем это спецификация для бинарного формата, а для текстового таковая имеется?

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 3)
Ответ на: комментарий от uwuwuu

Ну, мы автоматически генерируем BEM классы из view.tree описания компонента. Причём они у нас более продвинутые, поддерживающие иерархию на любую глубину, а не только на уровень. Плюс к этому ещё стат типизация прикручена, учитывающая как иерархию расположения, так и иерархию владения, и иерархию наследования. Тут есть доклад про это: https://page.hyoo.ru/#!=xwq9q5_f966fg

nin-jin
() автор топика
Ответ на: комментарий от Forum0888

Структура дерева определяется числом отступов. Это не формализовано, да. Tree - бинарный формат, который можно без проблем использовать и для текстовых языков.

nin-jin
() автор топика
Ответ на: комментарий от X512

Нет. Но обычно многострочный текст лежит в пустом узле данных:

multi-line-string \
	\first
	\second

Списки же обычно располагаются в структурных узлах:

list-of-single-line-strings
	\first
	\second

И, конечно, их можно комбинировать:

list-of-ulti-line-strings
	\
		\fist
		\text
	\
		\second
		\text
nin-jin
() автор топика

в жысоне пара ключ - значение записывается

"string" : value

это есть отображение произвольных строк на значения.

вопрос - как написать на tree жысоновское

"this is my key" : 1000
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от nin-jin

Попробуйте в JSON без костылей продублировать ключ объекта, написать комментарий, указать предикат отличный от «равно», или добавить список тегов к строке. Всё это вынуждает изобретать свои микроформаты поверх базового.

Что значит продублировать ключ объекта? У вас в статье где упорядоченные списки, есть пример дублирования ключей как массивов-кортежей например внутри массива. А прежде чем мне работать с каким-то форматом или АПИ, я всё равно читаю документацию и вижу что для извлечения данных из json надо обрабатывать массивы, также и по Tree я буду читать документацию чтобы понять как автор решил записать ключи, так

keys
    1
    2

или так

keys
    key \1
    key \2

, в этом плане Tree не лучше JSON или другого. Он также не интуитивен, не универсален и требует чтения и реализации своего парсера для конкретного Tree, просто в JSON доступ к любому полю можно получить через цепочку ['a']['b']['c'], а в Tree через, условно, \ta\tb\tc. И в чём тогда разница? Ну да, разница есть в синтаксическом сахаре вроде навязчивых кавычек в json или пробелов в yaml, которые tree убрал и поэтому места занимает меньше, на несколько процентов.

Попробуйте в JSON без костылей … написать комментарий

А в Tree где комментарии? Не увидел. И зачем в JSON комментарии когда это формат изначально не предназначаемый для внесения туда комментариев людьми, это формат обмена данными между клиентом и сервером, json формируется программой для программы, а программа не оставляет комментарии в отличие от людей.

добавить список тегов к строке

В Tree тоже нет единого способа добавить список тегов к строке. Можете возразить что в Tree единственнный способ наследования это Его Величество Отступ, и все что Отступно от родителя, является его [родительской ноды] ребенком-наследником-вложением, а в JSON и XML есть варианты, как уже сказали выше, типа путаницы с тем как определять атрибуты, через <a href="lor"></a> или <a><href>lor</href></a>, НО мякотка в том, что мне это не мешает даже зная что в tree есть только один способ задания наследника, мы опять возвращаемся к тому что мне даже в tree придётся лезть в доки и смотреть как же разработчик задал теги у строки, так

\строка
    тег1 тег2

или так

\строка
    теги
        тег1 тег2

или ещё как-то. Так и с JSON и XML я также лазаю и смотрю, поэтому у tree, в добавлении тегов к строке, преимуществ нет. JS ведь из коробки предоставляет операторы для получения value у key-я ноды, так что я просто чейню кишки объекта и получаю данные, как и в tree, и в чём разница?

Всё равно вы молодец, что упрощаете форматы, но тут тема гораздо глужбе и недостаточно просто пытаться выдать списки из маркдауна за новый формат сериализации данных. К чему я, тут недавно новость была про революционную объектный формат данных взамен plain text, советую почитать и причастится, может даже захотите сотрудничать с тем человеком, он тоже работает над форматами данных.

mydibyje ★★★★
()
Ответ на: комментарий от mydibyje

когда это формат изначально не предназначаемый для внесения туда комментариев людьми, это формат обмена данными между клиентом и сервером

Почему тогда не использовать чисто бинарный формат?

X512 ★★★★★
()

Он в 2 раза компактнее XML, в 20 раз проще YAML, в 2 раза быстрее JSON.

компактность понимаю, простоту понимаю, скорость не понимаю

по ссылке очевидно сравнивается не столько формат, сколько парсер для него, потому что из tree можно и будет нужно парсить много чего, включая мапы

Lordwind ★★★★★
()
Ответ на: комментарий от alysnix

Чувствую, на tree это будет такое вот:

\this is my key
    1000

или

this-is-my-key \1000

потому что такая

this is my key \1000

запись будет означать список из 4 структур this is my key и данные 1000, что нам очевидно не хотелось бы.

@nin-jin Я кстати так и не понял, может ли tree в виде родителя хранить key-value и при этом иметь дочерние узлы, ну типа такого

Человек \Владимир
    программист
    \любитель кактусов перед монитором
mydibyje ★★★★
()
Последнее исправление: mydibyje (всего исправлений: 1)
Ответ на: комментарий от mydibyje

Чувствую, на tree это будет такое вот:

если ТС столько лет полоскает жысон и не врубился зачем там в ключе кавычки - то становится страшно за этот мир. если б там ключом был просто идентификатор, кавычки там никто не стал бы внедрять.

а в tree «безковычечная» запись, и потому его мега универсальный tree не покрывает json.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от X512

Типы структур не могут содержать не только переводы строк, но и пробелы с табами. К тому же процессинг ориентируется именно на типы структур, так что узлы данных гарантированно не будут интерпретированы некорректно.

nin-jin
() автор топика
Ответ на: комментарий от nin-jin

генерируем BEM классы … Причём они у нас более продвинутые, поддерживающие иерархию на любую глубину, а не только на уровень

Так ведь смысл БЭМа как раз в том, чтобы ограничить глубину вложенности стилей, чтобы они не превращались через месяц совместной работы нескольких человек в глубины ужоса, наполненные лапшой страдания и раздираемые войнами специфичности, в которые никто по доброй воле заныривать не хочет. Не? %)

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 3)
Ответ на: комментарий от nin-jin

«песочница» (я правда не понял, что оно такое) - не про то.

запишите нормальную жысоновую пару

" this is my key " : 1000

в своем виде, и выложите сюда. тут ключ - строка, да еще с пробелами, причем пробелов может быть сколь угодно между двумя словами, также пробелы могут быть и в начале и в конце строки. как вы будете задавать эту пару, да еще читабельно и компактно.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 2)
Ответ на: комментарий от nin-jin

Структура дерева определяется числом отступов. Это не формализовано, да.

Проще говоря, адекватной спецификации формата нет.

Вы упростили немного синтаксис JSON и считаете, что это большое преимущество?

Ныне в большинстве сайтов с страницей, содержащей двадцать строк полезной информации прилетает по 5MB разного мусора.
А ведь кто-то должен этот мусор разгрести.
Мало того, что трафик засоряется, так еще и немало ресурсов тратится на разгребание «авгиевых конюшен».

Вот это действительно проблема!

Все всё понимают, но никто не разрабатывает эффективные технологии и протоколы.

Мир в целом ныне сильно лукав.
Да еще и сознательно отвергает Бога.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 3)
Ответ на: комментарий от mydibyje

Tree не избавляет вас от необходимости знать язык. Он упрощает обработку этого языка.

Разработчик всё же задаст теги как-то так:

\строка
    тег1
    тег2

https://github.com/nin-jin/tree.d/wiki/span.tree - пример мета языка, который берёт дерево на любом языке, и добавляет к каждому узлу сорсмап. Это позволяет не терять информацию о сорсмапах при сериализации. В песочнице можете поиграться с прямой и обратной трансформацией.

https://page.hyoo.ru/#!=gf3a0a_5koj1m - а тут можете сравнить разные форматы на одной и той же прикладной задаче и ужаснуться с кода на JSON.

nin-jin
() автор топика
Ответ на: комментарий от Nervous

У нас не составные селекторы, а составные классы. Это даёт одинаковую специфичность всех селекторов. А сборщик упорядочивает все стили в правильном порядке, чтобы переопределения корректно работали.

nin-jin
() автор топика
Ответ на: комментарий от Forum0888

Ну, вообще-то мы как раз и разрабатываем эффективные технологии. Вот, для примера, самое больше приложение: портал mol.hyoo.ru Весит всего 300кб, которые кешируется в сервис воркере, а при последующих запусках достаётся сразу из кеша, и обновлятся в фоне, если есть интернет. Статьи в энциклопедии, сообщения в чате, бенчмарки синхронизируются дельтами в реальном времени. Сервер синхронизаци у нас, кстати, поддерживает эффективный REST протокол для обмена подграфами: https://page.hyoo.ru/#!=uhgyst_zfa8t3

nin-jin
() автор топика

Пока что есть реализациии лишь на D и TS

Для того чтобы это было кому-то интересно нужны реализации для каких-нибудь ЯП, а не букв алфавита. В смысле я имею ввиду настоящие ЯП, а не хипстату. А когда это будет реализвано хотя бы для Js, PHP, Python, Java, C[рандомныеСимволы], нужно будет убедить пару корпораций что им это надо.

Suntechnic ★★★★★
()
Последнее исправление: Suntechnic (всего исправлений: 1)
Ответ на: комментарий от nin-jin

Речь не о вас шла.

Вэб использует теговые форматы данных, но они текстовые и они пригодны лишь для некой ниши задач.

Но большинство разработчиков просто не понимают этого и разрабатывают задачи с использованием теговых форматов.

Корпорации никогда ничего толкового не разработают.

Почему?

Потому, что для них создание новых технологий в области IT вовсе не приоритетная задача.

Поэтому вэб в ближайшее время будет доминировать.

Радует то, что создано много хороших алгоритмов.

Ну, вообще-то мы как раз и разрабатываем эффективные технологии.

См. сказанное выше.

Forum0888
()

Tree это точная копия логической организации файловой системы, где директории - это структурные ноды, а файлы - ноды данных. То есть вообще не видно ни предмета изобретения, ни какой-то ранее несуществующей мощи такого представления.

имя структурной ноды в tree должно быть строковой константой иначе не записать имена нод вида «это моя нода!», как это можно в json.

alysnix ★★★
()
Ответ на: комментарий от alysnix

В JSON все структурные ноды безымянные. У них есть лишь тип, и то лишь в 2 вариантах: объект и массив. Tree же не ограничивает в числе возможных типов узлов.

А то, о чём вы говорите, - это ключи словарей. Оные в любом формате записываются строками. И Tree тут не исключение. С той лишь разницей, что в Tree вместо строк произвольные бинарники.

nin-jin
() автор топика
Ответ на: комментарий от nin-jin

В JSON все структурные ноды безымянные.

в жысоне пары - «произвольная строка» -> значение. это математическое отображение (map) множества строк на множество значений (Value), где Value есть или скалярный тип, или строка, или структура или массив.

кстати для большей общности жысона можно было бы дать возможность отображать Value->Value, а не String->Value. тогда можно было бы например числа отображать на произвольные Value, массивы на массивы и так далее.

например

 5: "this is five"
 [1,2,3,4] : ["one", "two", "three", "four"]
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от nin-jin

то, что вы изобрели, в функциональном виде есть набор (c)

Struct* add_struct(Struct* fparent, const char* fname);
DataNode* add_data(Struct* fparent, const char* fdata);

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

в чем предмет новизны?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от X512

Я бы немного упросил этот формат:

name \Legacy SATA
controller \busses/ata/legacy_sata/driver_v1
channel \busses/ata/legacy_sata/channel/v1
bus pci vendor
	1106/VIA device
		3149/VIA6420
		3249/VIA6421
		0591/VIA8237A
	10B9/ALI device
		5289/ALI5289
		5287/ALI5287
		5281/ALI5281

nin-jin
() автор топика
Ответ на: комментарий от nin-jin

Или так, если важно минимизировать размер:

name \Legacy SATA
controller \busses/ata/legacy_sata/driver_v1
channel \busses/ata/legacy_sata/channel/v1
bus pci vendor
	1106 device
		3149
		3249
		0591
	10B9 device
		5289
		5287
		5281

Это даёт по 7 байт на каждый device/id.

nin-jin
() автор топика
Ответ на: комментарий от nin-jin

Там суть в матчинге атрибутов. То есть что-то вроде:

void GetDrivers(std::vector<std::string> &modules, const AttrMap &attrs)
{
	const char *module = nullptr;
	module = "busses/ata/legacy_sata/driver_v1";
	if (attrs["device/bus"] == "pci") {
		if (attrs["device/vendor"] == 0x1106) {
			if (
				attrs["device/id"] == 0x3149 ||
				attrs["device/id"] == 0x3249 ||
				attrs["device/id"] == 0x0591
			) {
				modules.push_back(module);
			}
		} else if (attrs["device/vendor"] == 0x10b9) {
			if (
				attrs["device/id"] == 0x5289 ||
				attrs["device/id"] == 0x5287 ||
				attrs["device/id"] == 0x5281
			) {
				modules.push_back(module);
			}
		} else if (attrs["device/vendor"] == 0x10de) {
			if (
				attrs["device/id"] == 0x008e ||
				attrs["device/id"] == 0x00e3
				/* ... */
			) {
				modules.push_back(module);
			}
		}
	}
}

X512 ★★★★★
()
Ответ на: комментарий от X512

Так и в моём примере структура не жёсткая, а идёт матчинг на указанные атрибуты, только они имеют более короткие имена.

Вот более сложный пример:

name \Legacy SATA
controller \busses/ata/legacy_sata/driver_v1
channel \busses/ata/legacy_sata/channel/v1
bus pci vendor
	1106/VIA device
		3149/VIA6420
		3249/VIA6421
		0591/VIA8237A
vendor 00B9/IBM bus
	com
	pci
device EFF9/DC
nin-jin
() автор топика