Pull to refresh

Comments 67

Комментарии. Jsonnet принимает комментарии в стиле С ( /* … */ ) и С++ ( // )


Собственно, за отсутсвие комментариев в JSON можно сказать спасибо крокфорду с его шизофреническими идеями.
Только этого мне не хватает в JSON. А все остальное из jsonnet на мой взгляд лишнее, т.к. это стандарт передачи данных, с которыми при необходимости может работать человек.
UFO just landed and posted this here
comment: «This is your comment»;

Чем не устраивает?
1. Корректен только в объектах/мапах.
2. Является частью данных, при преобразовании будет полностью загружен в память (что нужно дополнительно обходить, если это проблема).
Если ваши комментарии настолько забивают память, то я думаю, что проблема не в JSON…
Суть в самом подходе, если вы ещё этого не поняли. В любом языке и синтаксисе (если он подразумевает работу с переменными) тогда можно таскать просто строковую переменную, к которой «присваивать комментарий». Можно в окна (вместо дверей) входить, а микроскопами гвозди забивать — да
JSON это неструктурированные данные. Комментарий — часть данных. В чём проблема?
Допустим вы делаете конфиг для программы. И у вас есть два варианта: либо конфиг будет без комментариев, либо программа должна будет загружать комментарии в рантайме в память. Это не нужно и это оверхед, т.к. программа держит в памяти то что ей не нужно.
И сколько там она загрузит этих комментариев? Если вы пишите хардкорный embedded на asm, тогда, наверное, вам json в принципе не подходит, не то что комментарии в нём. А если вы пишите на каком-нибудь js, ruby или python то переживать из-за пары байт в комментарии явно не стоит.
суть в том, что заранее неизвестно какой объем текста будет в комментариях. вы не можете утверждать, что его всегда будет «пару байт».
Размер JSON вы тоже никогда не угадаете принципиально, так как у него нет схемы. Если вы используете JSON для данных, где можно определить схему, то you are doing it wrong.
У любого JSON есть неявная схема — это те представления о возможной структуре данных, которые писали программу, его генерирующую либо использующую.

Иногда эта схема даже описывается в документации.
UFO just landed and posted this here
По большому счету есть две проблемы с таким подходом:
1) Комментарии являющиеся частью JSON тратят ресурсы. Да, они бы тратили ресурсы в любом случае, но всетаки если бы они вырезались на уровне парсера тратили бы меньше чем если делать это на более высоком уровне. Да, это копейки, но мы сейчас говорим о концептуальной проблеме стандарта.
2) Нет единого синтаксиса или соглашения для комментариев. Можно договориться, например, добавлять комментарий в виде поля "_comment" в объекте, примерно так:
{
   _comment: "This is my program config file. Param 1 is for option1, param2 for option2",
  param1: "value1",
  param2: "value2"
}

Такой синтаксис, во первых не позволяет написать отдельные комментарии к param1 и param2, например так:
{
  // This is my program config file.
  param1: "value1", // Option 1.
  param2: "value2"  // Option 2.
}

Во вторых нет поддержки «вырезания» таких комментариев на разных платформах, и если вы допустим пишете приложение с сервером на c# и клиентами на js, Java и Swift то вам придется написать четыре пусть и простых но прослойки которые будут вырезать _comment ноды из распарсеного дерева, или делать это на уровне тесктого препроцессора.
В третьих это не является стандартом и возможно в будущем вы столкнетесь с какой-то библиотекой или сторонним API которое использует поле _comment для каких-то своих целей, тогда вам придется как-то изворачиваться чтобы один JSON пропускать через вот этот парсер, а другой через другой.

Я не говорю что все эти проблемы нерешаемы или очень сложны, что нельзя прикрутить два парсера или что написать препроцессор очень сложно, но всем было бы удобнее, если бы комменатрии поддерживались в стандарте.
UFO just landed and posted this here
Чем не устраивает?

Ну меня в вашем предложении больше всего не устраивает, что если нужно будет итерироваться по потомкам, то постоянно нужно будет проверять, не является ли у нас элемент комментарием. Причем насколько я знаю, с одним именем может быть только один элемент хеш-таблицы, коей является JSON, соответственно при желании добавить несколько комментариев в разных местах нужно будет проверять каждый элемент, не начинается ли он на comment, формировать культуру «комментарии начинайте со слова comment, например comment1, commentValue, ...», при малейшей опечатке превращается в camment, coment и т.п., в предметной области, ну например, объект — фильм на афише или блог, может быть поле comments, который придется отдельно обрабатывать, потому что его может порезать проверка на то, что слово начинается на это слово…

Можно продолжать сколько угодно. Причем это это не единственные недостатки вашего подхода, а только в добавление к вышесказанному.
А можно ссылку на эту тему? Гугл не силён в запросах «Шизофренические идеи Крокфорда» и «Крокфорд против комментариев», а почитать интересно)
Че мелочиться? Давайте сразу компилятор прикрутим к парсеру-JSON.

UFO just landed and posted this here
Господи, не надо трогать JSON, пусть останется хотя бы один простой и понятный текстовый формат, который железобетонно все поддерживают!

image
Единственно, комментарии можно было бы добавить.
Пусть добавят тип дата/время, и довольно. Можно ещё значение Infinity.
не надо дату/время — нигде нет нормального стандарта. Используйте таймстамп лучше
При всём наличии этих хороших стандартов всегда можно вспомнить о том, что Twitter (как явствует из примера, официально приведённого вон там) не стесняется возвращать время и дату в адском формате «Wed May 23 06:01:13 +0000 2007» (день недели, месяц, день, время, часовой пояс, год).
Странно, что такое название выбрали, так как есть созвучная и популярная библиотека под .NET: Json.NET.
Странно, что это в хабах ASP и .Net.
Да и гугл по запросу jsonnet первые несколько результатов выдает про Json.NET.
Ух ты, в кои-то веки буханка в плюсах!
Хабр уже не торт. Теперь он — хлеб.
> заменяет стандартный JSON и добавляет новые возможности без нарушения обратной совместимости. Среди таких возможностей: комментарии ...


Для поддержки комментариев делал проект github.com/spmbt/jsonComm — формат с комментариями (одно- и многострочными) и возможность смены ключей и значений в парах «ключ-значение» без удаления комментариев. Хабр

Он сейчас работает и расширен (код скоро будет добавлен в репо после тестирования) до возможности работы с фрагментами jsonComm в JS-файлах. Фрагменты выделяются специальными комментированными скобками с достаточно вольным синтаксисом.
Ну, и кто (и когда) должен вычислять «1 + 1»?
Генерирующая сторона в момент отправки?
Читающая сторона в момент приема?
А если json сохраняется в файл, нужно вычислять во время записи, или во время чтения?
Это формат для конфигов. Разумеется, вычислять должна программа при чтении — просто потому что человек пишет.
JSON — это не формат для конфигов. Это формат обмена данными, и его применение конфигами не ограничивается.
Зато применение Jsonnet ими ограничивается.
Гугл открыла исходный код своего проекта Jsonnet, языка для конфигурации, который заменяет стандартный JSON и добавляет новые возможности без нарушения обратной совместимости.
JSON — настолько же формат для конфигов, насколько AVI — формат для гей-порно.

За все годы я только один раз использовал JSON для хранения конфигов, и этот JSON как писался машиной, так ей же и читался, человек (я) лишь один раз задал его формат в коде. Зато без использования JSON для передачи данных между какими-то сторонами не обходится нынче почти ни один проект, поскольку альтернатив, в общем-то, и нет (XML и основанные на нём стандарты в разы дороже по оверхеду).
UFO just landed and posted this here
Могу в ответ лишь предложить им уволиться и сменить род деятельности, поскольку никакой разницы для разработчика, делать SOAP-сервис или JSON-сервис, в .NET нет, а использовать «все возможности фреймворка», скидывая на пользователей все неудобства, связанные с повышенным оверхедом, они могут в своё свободное время, делая личные проекты.
UFO just landed and posted this here
JSON — формат обмена данными, у которого есть множество реализаций для самых разных языков программирования. Он как раз примечателен тем, что он не исполняем, а потому относительно безвреден, а вычислительные ресурсы по его преобразованию обычно близки к О(strlen(message)).

Если нужно обрабатывать данные перед преобразованием в JSON — как раз существующие реализации покрывают эти нужды. Ведь если есть JSON, то где-то рядом работает и преобразователь между JSON и нативными типами (как правило). Добавлять ещё один язык в технологический стек нерационально или даже опасно.

Я вижу только один адекватный способ применения: преобразование структуры JSON-документов — когда у нас есть только исходный документ и приёмник, в который надо послать документ с этими же данными, но в другой структуре. Больше я не вижу ситуаций, когда не используется реализация JSON на другом языке и потому есть свобода выбора. Но лично я даже в этой ситуации выбрал бы Ruby, Python (основы которого изучал бы на ходу, поскольку его не знаю) или JS/производные.
UFO just landed and posted this here
Тот, кто говорит, что в YAML 1+1 — это строка «1+1» явно ничего не понимает в YAML. Нужно преобразовывать 1+1 в 2 — напишите свой resolver или constructor (второе обязательно, первое нет). Гораздо проще взять готовый YAML парсер и приделать к нему constructor, чем писать новый формат.

Если что: resolver определяет, какой тёг соответствует данному синтаксическому дереву в случае, когда тёг не указан (здесь тёг — это тип). Обычно используется только для скаляров, именно благодаря resolver'ам в формате есть числа и true/false/null.

Constructor определяет, как из синтаксического дерева получить объект (строку/число/словарь/...). Определение тёга определяет constructor.

В стандарте описаны «стандартные» resolver'ы для трёх схем (безопасная, JSON-совместимая, основная (failsafe, json, core)), но нигде не написано, что они обязаны быть единственными.
UFO just landed and posted this here
JSON это декларативный формат по свой сути. Зачем туда пихать императивные директивы вообще не понятно.
XML-bomb сделать не проблема.
Теперь видимо можно будет и JSON-bomb сделать :-)
Вот да, сразу возникают вопросы с безопасностью. Принимать JSON из недоверенного источника в принципе можно. Дыры в JSON-парсерах случаются очень редко. А тут сам формат подразумевает, что результат может вычисляться долго и захавает всю память.
В json не хватает четырех вещей — схемы, дат, комментариев и NaN. А так — идеальный формат.
Из всего вышеперечисленного для эффективной передачи данных не пригодится ничего (кроме, возможно, NaN). Схему передавать по сети (особенно мобильной) очень дорого, тем более, что предполагается, что общающиеся стороны знают про протокол обмена, и не крашатся от допустимых изменений (отсутствующее поле, значение null в любом из полей, новое поле). Если разработчик накосячил с типом, в который он хочет приводить поле — это не проблема формата передачи данных.

Самый простой способ избежать проблемы с кривыми руками и неверными типами — использовать схожие языки для обеих сторон (например, Java-фронтенд и C#-бекенд), и после фиксации протокола тупо копировать все структуры данных из сериализующего проекта в десериализующий, по пути исправляя синтаксис.

Даты и сейчас прелестно передаются в формате таймштампа. В случае, когда надо передать ещё и таймзону, её всё равно нельзя передавать цифрой +ЧЧММ после даты, а надо заводить отдельное строковое поле.
Схему передавать и не надо — это просто стандратный способ проверить целостность данных, то есть вместо громоздкого текстового описания моего API и тучи реализаций на разных языках, я могу просто предоставить одну схему. Отсутствие схемы — это не минус самого формата, это минус его инфраструктуры, и хорошо, что json schema уже, как минимум, internet draft.

Для дат есть замечательный ISO 8601, самый распротраненный формат данных после строк и чисел. Иметь его в стандрате передачи данных было бы очень приятно.
<нудная мутотень>

ISO 8601 прекрасен для случаев, когда надо передать отсылку на конкретную точку во времени, т.е. по сути, тот же таймштамп. Это прекрасно работает для дат в прошлом. Если же вы оперируете датами из будущего, это может быть неприемлемо. Например, пользователь сказал приложению «напомни мне захватить мир 5 января 2020 года в 11:00», после чего вы сохранили это таймштампом (или в ISO 8601, разницы нет). Через два года прилетает новая tzdata, таймзона пользователя меняет часовой пояс или параметры DST, и представление «5 января 2020 года в 11:00» теперь указывает на другую точку во времени. Но вы об этом не узнаете, и напоминание откроете не в 11:00, а в другое время. Ошибочка вышла…

</нудная мутотень>

Как передавать и хранить дату, надо решать в каждом случае отдельно, в первую очередь отталкиваясь именно от того, что нам нужно зафиксировать — точку во времени (таймштамп), или пользовательское представление о будущей дате (ISO 8601 + название таймзоны). В любом случае, как вы договоритесь делать в протоколе передачи, так можно и передавать, все существующие форматы дат, включая ISO 8601, отлично вписываются в строки.
Да таких проектов уже тьма… есть например HOCON… Но новый язык это как-то слишком имхо для задачи «json на выходе».
Уу, в этом месяце еще никто не изобретал JSON с комментами!
Мы изобретём новый json с блекджеком комментариями и арифметическими операторами © Google
Любой синтаксис файлов конфигурации со временем превращается в полноценный язык программирования.
ini и properties пока ещё держатся
Sign up to leave a comment.