Возможно ли метапрограммирование в Javascript?
Во время моей обычной работы я случайно написал цепочку javascript, которая является чем-то вроде выражения LINQ, чтобы запросить результат JSON.
var Result = from(obj1).as("x").where("x.id=5").groupby("x.status").having(count("x.status") > 5).select("x.status");
Он отлично работает и дает ожидаемый результат.
Мне было интересно, что это выглядит потрясающе, если код написан так (более читаемым образом)
var Result = from obj1 as x where x.status
groupby x.status having count(x.status) > 5
select x.status;
есть ли способ достичь этого?
Приветствия
Рамеш Вель
Ответы
Ответ 1
Нет. JavaScript не поддерживает это.
Но это тоже выглядит неплохо:
var Result = from(obj1)
.as("x")
.where("x.id=5")
.groupby("x.status")
.having(count("x.status") > 5)
.select("x.status");
Ответ 2
Большинство людей настаивают на попытке метапрограмм изнутри своего любимого языка. Это не работает, если язык не поддерживает метапрограммирование; другие ответы заметили, что JavaScript не работает.
Для этого нужно выполнить метапрограммирование извне языка, используя
инструменты преобразования программы. Такие инструменты могут анализировать исходный код и выполнять произвольные преобразования на нем (что метапрограммирование в любом случае), а затем переплести пересмотренную программу.
Если у вас есть система преобразования общей цели, которая может анализировать произвольные языки, вы можете выполнить метапрограммирование на любом языке, который вам нравится. См. Наш DMS Software Reengineering Toolkit для такого инструмента, который имеет надежные интерфейсы для C, С++, Java, С#, COBOL, PHP и ECMAScript и ряд других языковых программ программирования, и он использовался для метапрограммирования на всех этих языках.
В вашем случае вы хотите расширить грамматику JavaScript с помощью нового синтаксиса для SQL-запросов, а затем преобразовать их в обычный JavaScript. (Это очень похоже на преднамеренное программирование)
DMS легко позволит вам построить диалект JavaScript с дополнительными правилами, а затем вы можете использовать его возможности преобразования программы для создания эквивалентного стандартного Javascript.
Сказав это, я не являюсь отличным поклонником "пользовательского синтаксиса для каждого программиста на планете", в котором Intentional Programming ведет IMHO.
Это хорошо, если есть большое сообщество пользователей, которое найдет это ценным. Эта идея может быть или не быть одной из них; часть проблемы заключается в том, что вы не можете узнать об этом без проведения эксперимента, и это может не получить достаточного социального тяготения к делу.
Ответ 3
хотя и не совсем то, что вы хотели, можно написать парсеры в javascript и просто проанализировать запрос (сохраненный как строки), а затем выполнить его. например, используя библиотеки, такие как http://jscc.jmksf.com/ (без сомнения, есть другие), это не должно быть слишком сложно реализовать.
но то, что у вас есть в вопросе, выглядит великолепно уже, я не знаю, почему вы хотите, чтобы он выглядел так, как вы предполагали.
Ответ 4
Хорошо, в вашем примере кода:
var Result = from(obj1)
.as("x")
.where("x.id=5")
.groupby("x.status")
.having(count("x.status") > 5)
.select("x.status");
Единственная проблема, которую я вижу (кроме select
, используемой как идентификатор), заключается в том, что вы вставляете предикат в качестве аргумента функции. Вы должны были бы сделать его функцией:
.having(function(x){ return x.status > 5; })
У JavaScript есть закрытие и динамическая типизация, поэтому вы можете сделать некоторые действительно изящные и элегантные вещи в нем. Просто дайте знать.
Ответ 5
В чистом JS нет, вы не можете. Но с правильным препроцессором это возможно.
Вы можете сделать что-то подобное с sweet.js макросами или (простите меня Бог) GPP.
Ответ 6
Ват, который вы хотите, - это изменить парсер javascript в парсер SQL. Он не был создан для этого, синтаксис javascript не позволяет вам.
То, что у вас есть, - это 90%, как SQL (оно прямо на нем), и 100% действительный javascript, что является большим достижением. Мой ответ на вопрос в заголовке: ДА, возможно метапрограммирование, но НЕТ это не даст вам синтаксический анализатор SQL, поскольку он связан с использованием грамматики javascript.
Ответ 7
Учитывая, что этот вопрос задан несколько лет назад, я постараюсь добавить к нему больше, основываясь на существующих технологиях.
Как и в ECMAScript 6, метапрограммирование теперь поддерживается в некотором смысле через Symbol, Reflect и Proxy.
Просматривая в Интернете, я нашел серию очень интересных статей по этой теме, написанных Китом Киркелем:
Метапрограммирование в ES6: Символы и почему они потрясающие
Короче говоря, символы - это новые примитивы, которые могут быть добавлены внутри объекта (без каких-либо свойств) и очень удобны для передачи ему свойств метапрограммирования. Символы касаются изменения поведения существующих классов путем их изменения (Reflection in implementation).
Метапрограммирование в ES6: Часть 2 - Отражение
Короче говоря, Reflect фактически представляет собой совокупность всех этих "внутренних методов", которые доступны исключительно через внутренние механизмы JavaScript, которые теперь отображаются в одном удобном для пользователя объекте. Его использование аналогично возможностям Reflection для Java и С#. Они используются для обнаружения очень низкого уровня информации о вашем коде (отражение через интроспекцию).
Метапрограммирование в ES6: Часть 3 - Прокси
Короче говоря, Proxies - это объекты-обработчики, ответственные за обертывание объектов и перехватывание их поведения через ловушки (отражение через ходатайство).
Конечно, эти объекты предоставляют определенные возможности метапрограммирования, гораздо более ограничительные по сравнению с языками метапрограммирования, но все же могут обеспечить удобные способы базового метапрограммирования, в основном, посредством практики отражения. Фактически.
В конце концов, стоит упомянуть, что существует некоторая заслуживающая внимания текущая исследовательская работа поэтапного метапрограммирования в JavaScript.
Ответ 8
Возможно, вы хотите что-то вроде JSONPath, если у вас есть данные JSON. Я нашел это на http://www.json.org/. Множество других инструментов, связанных с ним, если это не совсем то, что вам нужно.
(это тоже работает: http://docs.dojocampus.org/dojox/json/query)