Как стать автором
Обновить

Комментарии 23

Хм. Забавно. Бывало использовал такое для разнообразной валидации и/или фильтров и всегда сомневался, правильно ли я делаю, не сильно ли все абстрактно и т.д. Ну теперь я спокоен, спасибо
Великолепно! И даже источники есть… Спасибо!!!
Очень хочется разобраться с программной архитектурой управления «руками и ногами» в живых системах. Подозреваю, там тоже метаподвох, заключенный в самоподобии иерархии управления. В звёздочки))
Извиняюсь, но зачем вы пишите код в одну строчку?

for (var i=0; i<tasks.length; i++) setInterval(closureTask(tasks[i]), duration(tasks[i].interval));


Как такое читать коллегам?
Ооо… Это далеко не худший вариант. Даже грех на такое коллегам жаловаться )))
Да забейте, идея же понятна. У него там масса неточностей в коде, например, в первом примере надо выкинуть флаг и остановиться (return) на первом же получившимся false, остальные условия бесполезно выполняться будут. Или parseInt надо использовать с системой счисления, иначе какой-нибудь parseInt(«010») вернёт «8».
JavaScript у меня тут не оптимальный, согласен, но я использую его тут как псевдокод.
Откройте для себя 140bytes )
Ну вот тема крутая, вроде автор действительно шарит, разложено все по полочкам, примеры красивые и интересные, но читать невыносимо скучно, и мне, как неподготовленному читателю, ничего не понятно

1.
Почему первый пример — метапрограммирование? Ведь все функции и опции запрограммированы заранее, что именно меняется в ран тайме?
Становится ли это метапрограммированием от того, что мы вызываем функцию по ключу из хеша? (operations[key](s, conditions[key]);).

Тогда каждый раз когда мы используем конструкцию something[key] это — метапрограммирование?
А если бы мы захардкодили все те же функции в один гигантский switch, то это уже не метапрограммирование?

2.
Второй пример — понятно вроде, есть и вызов функции по ключу и замыкание. Получается, что любое замыкание — метапрограммирование, потому что персонализирует ф ункцию?
Наверное стоит заметить, что в последней части примера все вынесенные в хеш функции потеряют контекст, что не страшно для данного примера, но может доставить много удовольствия новоиспеченному мета программисту.

3.
Это метапрограммирование потому что используются регулярные выражения? И значения берутся из хеша? Если второе, то что, вообще любое использование хешей — метапрограммирование?

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

Диаграммы не помогают: есть три шага, стрелочки идут из коробочки с надписью logic в другую такую же коробочку, как иллюстрация соотносится с примером — для меня загадка.

5.

Dependency injection в angular по ходу метапрограммирование, потому что имена переменных берутся из декларации функции, например:

angular.module('hi', [])
      .value('someVar', 'hello')


inject( function( someVar ){
  console.log(someVar); // 'hello'
}

6.
Или матчеры в chai тоже должны подходить, потому что используют defineProperty.
expect(something).to.be.ok

7.

Плагины в jquery добавляются в runtime, AMD и любая система модулей, любые операции с json, операции с хешами, замыкания, модификация прототипа и свойств объекта — все метапрограммирование?
А что тогда не относится к мета программированию?
Метапрограммирование это, потому что вы как бы конфигурируете один раз написанный код. Вот надо вам в функции «duration» (см. примеры) миллисекунды добавить, ничего программировать (как в обычном программировании) не надо — достаточно добавить ещё одно свойство в объект.
Кто Вам сказал, что конфигурация кода — это метапрограммирование?
Я так понял автора статьи.
Так я же и говорю, что метапрограммирование повсеместно, это не что-то новое, а обобщение общепринятой практики изменения поведения кода при при помощи его конфигурирования метаданными в момент исполнения. Критерий разделения что называть метапрограммированием, а что не называть я тоже предлагаю — если в результате увеличивается абстрактность модели, и мы получаем более общую модель, т.е. метамодель, то это метапрограммирование.

В первом примере есть замыкание на каждый conditions, что позволяет просто вводить новые условия и рекурсивный вызов при модификаторе not, этого достаточно для получения более общей модели. Да, пример прост, но тема сложная и если бы я привел тут код как генерируются 5000 сложнейших форм по метамодели в 80 строк, то за сложностью реализации мы бы не увидели сути — того, как метамодель во время запуска подражает модели на базе разных метаданных.
Очень сильно не хватает пункта «Пользуюсь метапрограммированием давно, но то, что описано в статье — бред собачий».

Следим за руками.

Метаданные — это данные, описывающие данные
Метамодель — это модель, описывающая модели
Метаисследование — исследование, имеющее объектом другие исследования

Метапрограммирование — это парадигма программирования, построенная на программном изменении структуры и поведения программ.

Хм, «меня терзают какие то смутные сомнения» (с)

А почему бы не последовать за всем остальным миром и не пытаться переопределить существующие понятия (и метапонятия, хехе).
Метапрограммирование — это программы, которые генерируют программы. ВСЕ!

Скажем, старый добрый
#define MIN(a, b) ((a) < (b) ? (a) : (b))


Это метапрограммирование. Да, да, какой бы примитивной ни была сишная макросистема — она генерирует новый код в месте использования (который потом может быть а может и не быть «выброшен» оптимизатором) и поэтому является метапрограммированием.

template <typename T> T min(T lhs, T rhs) {return lhs < rhs ? lhs : rhs; }

Это тоже метапрограммирование. Для каждого типа порождается (инстанцируется) новая функция

И даже уродство вроде
$db->query("select * from users where name='" . $user . "'")

Это, очевидным образом, тоже метапрограммирование.

Логичнее всего метапрограммирование выражено в Scheme. Компиляция явным образом разделена на метауровни. Уровень meta-0 — это то, что, собственно, компилируется. Meta-1 — уровень который может генерировать код для meta-0 (собственно, макросы), meta-2 — уровень генерирующий код для meta-1 (макросы, генерирующие макросы). Количество метауровней стандартом не регламентируется.

Ну а то, что описано в статье — это именно, что «бред собачий» и попытка переопределить существующую терминологию
Полностью согласен насчёт попытки переопределить терминологию, но что касается «бред собачий» — у него есть своё собственное имя: data-driven programming. Как вариант, описанный в статье подход может развиться в Domain Specific Language и дальше в Language Oriented Programming, которое уже относят к метапрограммированию.
Да, я таки переборщил. Подход в статье сам по себе имеет право жизнь, более того, конфигурирование фреймворков (хоть чужих хоть самописных) — зачастую действительно гораздо более поддерживаемый подход, чем клепание всего под конкретную задачу. Спасибо, что поправили — я полностью с Вами согласен.
Ну я же не говорю, что метапрограммирование это только то, что я показал в примерах, генерация кода не перестает быть метапрограммированием, но нет принципиальной разницы, при помощи чего меняется поведение программы, при перегенерации кода или при интерпретации, при замыкании метаданных с более абстрактной моделью или при использовании примесей или фабрик. Не использование хешей и замыканий делает из программирования метапрограммирование, а переход от модели к метамодели и от данных к метаданным.
Блин, то что показано в статье — это банальное программирование! Выделяем сущность и делаем к ней такие мостики/интерфейсы, что бы использовать ее в конкретных местах, listener/hadler и так далее. А люди поверят, что это метопрограммирование. Серьезно, лучше чем пудрить людям мозги тк с «не большой натяжкой» и С и assembler объектно-ориентированные, функциональные языки, напишите в начале материала: это статья полная отсебятина, «так как видит автор», «задумка творческая», «воспринимайте все критически» и «прошу на обсуждения в комментарии». А то ж ваш кисель в мозгах уже попал в 6150 мозгов :-) Чувствуете ответственность?
Не использование хешей и замыканий делает из программирования метапрограммирование, а переход от модели к метамодели и от данных к метаданным.
Вот здесь и зарыта логическая ошибка в Ваших рассуждениях. Из перехода от приготовления еды для себя самого к приготовлению еды для всей семьи не следует что Вы из обычного человека стали профессиональным поваром.

Программирование с использованием метаданных/метамодели — это всё ещё программирование с использованием метаданных/метамодели, а не метапрограммирование. Более того, я сомневаюсь, что можно выявить метаданные и/или метамодель в классическом примере метапрограммирования с макросом #define MIN(a,b).
Это не ошибка, это терминологический казус, я использую терминологию непривычную для Вас, потому, что в этой сфере терминология не устоялась, и написанное в википедии — не догма.
Написанное в википедии — не догма, более того это зачастую даже не правда, но, как правило, это общепринятое мнение. Поэтому в вопросах определения терминов, мне кажется, ссылаться на википедию вполне корректно.
The classic definition for a metaprogram is “a computer program that writes new computer programs.” [...] Another common definition for metaprogramming is “a computer program that manipulates other programs at runtime.”

(Kevin Hazzard, Jason Bock, Metaprogramming in .NET)

Функциональные вещи (типа замыканий и каррирования), программирование на основе модели и табличные методы — это не метапрограммирование.

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

Этот тезис, кстати, ничем не подтвержден. Очень многие подходы к метапрограммированию, наоборот, усложняют поддержку — попробуй-ка найти все использования того или иного аспекта, или определить контракт, по которому он вбрасывается.
Ох, давно мне нигде не попадалась эта цитата, здесь, думаю, будет уместно:
Любая достаточно сложная программа на Си или Фортране содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории