Возможно ли метапрограммирование в Javascript? - PullRequest
15 голосов
/ 01 сентября 2009

Во время моей обычной работы я случайно написал цепочечную функцию 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;

есть ли способ добиться этого ??

Приветствия

Рамеш Вэл

Ответы [ 8 ]

18 голосов
/ 01 сентября 2009

Нет. JavaScript не поддерживает это.

Но это тоже выглядит неплохо:

var Result =  from(obj1)
             .as("x")
             .where("x.id=5")
             .groupby("x.status")
             .having(count("x.status") > 5)
             .select("x.status");
6 голосов
/ 26 февраля 2010

Большинство людей настаивают на попытке метапрограммирования из внутри их любимого языка. Это не работает, если язык не поддерживает метапрограммирование; другие ответы отметили, что JavaScript не.

Обойти это можно, выполнив метапрограммирование из вне языка, используя инструменты преобразования программ . Такие инструменты могут анализировать исходный код и выполнять произвольные преобразования над ним (в любом случае это делает метапрограммирование), а затем выплевывать пересмотренную программу.

Если у вас есть система преобразования программ общего назначения, которая может анализировать произвольные языки, вы можете затем выполнять метапрограммирование на / на любом языке, который вам нравится. Смотрите наш DMS Software Reengineering Toolkit для такого инструмента, который имеет надежные внешние интерфейсы для C, C ++, Java, C #, COBOL, PHP и ECMAScript и ряда других языков программирования, и использовался для метапрограммирование на все это.

В вашем случае вы хотите расширить грамматику JavaScript новым синтаксисом для запросов SQL, а затем преобразовать их в обычный JavaScript. (Это очень похоже на преднамеренное программирование) DMS легко позволит вам создать диалект JavaScript с дополнительными правилами, а затем вы сможете использовать его возможности преобразования программ для создания эквивалентного стандартного Javascript.

Сказав, что я не большой поклонник "пользовательского синтаксиса для каждого программиста на планете", к которому ИМХО ведет Интенциональное программирование.

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

5 голосов
/ 01 сентября 2009

хотя и не совсем то, что вы хотели, можно написать синтаксические анализаторы в javascript, просто проанализировать запрос (сохраненный в виде строк) и затем выполнить его. например, используя библиотеки типа http://jscc.jmksf.com/ (несомненно, есть и другие), это не должно быть слишком сложно для реализации.

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

3 голосов
/ 13 сентября 2016

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

Начиная с ECMAScript 6, метапрограммирование теперь поддерживается в некотором смысле через Символ , Отражение и Прокси объектов.

При поиске в Интернете я нашел серию очень интересных статей на эту тему, написанных Китом Киркелем:

Метапрограммирование в ES6: символы и почему они классные

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

Метапрограммирование в ES6: Часть 2 - Отражение

Короче говоря, Reflect фактически представляет собой совокупность всех тех «внутренних методов», которые были доступны исключительно через внутренние компоненты движка JavaScript, теперь представленные в одном удобном объекте. Его использование аналогично возможностям отражения в Java и C #. Они используются для обнаружения информации вашего кода на очень низком уровне (Отражение через самоанализ).

Метапрограммирование в ES6: Часть 3. Прокси

Короче говоря, Прокси - это объекты-обработчики, отвечающие за обертывание объектов и перехватывающие их поведение через ловушки (Отражение через заступничество).

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

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

3 голосов
/ 20 июля 2010

Ну, в вашем примере кода:

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 имеет замыкания и динамическую типизацию, так что вы можете сделать несколько действительно изящных и элегантных вещей. Просто сообщаю тебе.

2 голосов
/ 04 февраля 2015

В чистом JS нет, ты не можешь. Но с правильным препроцессором это возможно.

Вы можете сделать что-то похожее с sweet.js макросами или (простите меня) GPP .

1 голос
/ 01 сентября 2009

Ват вы хотите изменить парсер javascript на парсер SQL. Он не был создан для этого, синтаксис javascript не позволяет вам.

То, что у вас есть, на 90% похоже на SQL (он отображается прямо на него) и на 100% допустимый JavaScript, что является большим достижением. Мой ответ на вопрос в заголовке: ДА, метапрограммирование возможно, но НЕТ, это не даст вам анализатор SQL, поскольку он обязательно использует грамматику javascript.

0 голосов
/ 01 сентября 2009

Может быть, вы хотите что-то вроде JSONPath , если у вас есть данные JSON. Я нашел это в http://www.json.org/. Множество других инструментов, связанных с этим, если это не совсем то, что вам нужно.

(над этим также ведутся работы: http://docs.dojocampus.org/dojox/json/query)

...