Программирование → Метапрограммирование
Целью этой статьи есть привлечение внимания широкой ИТ-шной общественности к метапрограммированию и всем его многочисленным формам и техникам. Я постарался собрать классификацию всего, что знаю по этой теме, и показать ее применимость не только в умозрительных задачах, но и в разработке рядовых приложений. Но это скорее план для дальнейшего изучения и, я надеюсь, толчек для более активного обсуждения.Итак, попробую дать альтернативное определение: метапрограммирование — это парадигма построения кода информационной системы с динамическим изменением поведения или структуры в зависимости от данных, действий пользователя или взаимодействия с другими системами. Задачи метапрограммирования: повышение абстракции кода и его гибкости, повторное использование, ускорение разработки, упрощение межсистемной интеграции. На самом деле, все мы в той или иной мере используем метапрограммирование, я даже сейчас могу вспомнить, как использовал его 15 лет назад, даже не подозревая как оно называется, тогда я еще не мог провести какой-либо классификации.
Программирование → Язык D2 и метапрограммирование: всё страньше и страньше
Не так давно Monnoroch опубликовал несколько прекрасных вступительных статей по языку D2, и это было хорошо. Но, прочитав последнюю статью, посвящённую метапрограммированию, захотелось сделать ещё лучше и раскрыть тему немножко подробнее. Дьявол, как известно, в деталях — и именно внимание к мелочам делает реализацию meta-парадигмы в D2 столь удобной. Если вы не читали статью Monnoroch, рекомендую вначале ознакомиться с ней, т.к. в рамках этой не хотелось бы тратить время на базовые вещи.
Итак, если вам уже знакомы некоторые возможности шаблонов в D2, я хотел бы подробнее рассказать о том, что сопутствует им — инструментах статической интроспекции, нюансах CTFE и даже такой запретной, но притягательной вещице, как mixin.
Цель — больше наглядных примеров кода с комментариями и меньше слов.
Итак, если вам уже знакомы некоторые возможности шаблонов в D2, я хотел бы подробнее рассказать о том, что сопутствует им — инструментах статической интроспекции, нюансах CTFE и даже такой запретной, но притягательной вещице, как mixin.
Цель — больше наглядных примеров кода с комментариями и меньше слов.
Программирование → Язык программирования D — продолжение
Доброго всем времени суток!
Итак, я решил продолжить рассказ о замечательном языке программирования D.
Моя прошлая статья была о мультипарадигменности языка, о том, что он естественным и гармоничным образом поддерживает большинство современных популярных стилей программирования.
В этот раз я задумал осветить другую сторону языка — менее общую и фундаментальную, но не менее полезную. А именно возможности метапрограммирования и compile-time computations.
Итак, я решил продолжить рассказ о замечательном языке программирования D.
Моя прошлая статья была о мультипарадигменности языка, о том, что он естественным и гармоничным образом поддерживает большинство современных популярных стилей программирования.
В этот раз я задумал осветить другую сторону языка — менее общую и фундаментальную, но не менее полезную. А именно возможности метапрограммирования и compile-time computations.
Ненормальное программирование → Вычисление простых чисел на шаблонах C++
В этом посте я расскажу как сделать совершенно бесполезную вещь — вычислять простые числа при помощи шаблонов C++.
Алгоритмы проиллюстрированы кодом на Scheme, поэтому осторожно: скобочки!
Алгоритмы проиллюстрированы кодом на Scheme, поэтому осторожно: скобочки!
C++ → Шаблонная магия, метафункция IsValidExpression
Доброго времени суток, уважаемое Хабрасообщество.
Сегодня я хочу поделиться одним интересным приемом, который позволяет определять компилируемость любого конкретного выражения.
Пример:
Как Вы уже, наверное, догадались мы будем думать как написать макрос DECLARE_IS_VALID_EXPRESSION.
Сегодня я хочу поделиться одним интересным приемом, который позволяет определять компилируемость любого конкретного выражения.
Пример:
/* Определяем метафункцию HasF, которая позволяет определить наличие функции f() у любого класса. */
DECLARE_IS_VALID_EXPRESSION(
HasF,
( ( U * ) NULL )->f() /* Это выражение компилируемо только если присутствует U::f() */ );
struct Foo{ void f(); };
struct Bar{};
BOOST_STATIC_ASSERT( HasF< A >::value ); /* Тут константа HasF< A >::value будет true */
BOOST_STATIC_ASSERT( !HasF< B >::value ); /* Тут константа HasF< A >::value будет false */
Как Вы уже, наверное, догадались мы будем думать как написать макрос DECLARE_IS_VALID_EXPRESSION.
C++ → Шаблонная магия, паттерн CallWithType
Доброго времени суток, уважаемые Xабровчане!
В этой статье я хочу рассказать о том, как в С++ можно делать преобразование данных времени компиляции (типов) в данные времени выполнения (целые значения) и обратно.
Пример:
Весь этот топик направлен на то, чтобы понять, что же надо написать вместо «magically resolve type hidden by nType here».
В этой статье я хочу рассказать о том, как в С++ можно делать преобразование данных времени компиляции (типов) в данные времени выполнения (целые значения) и обратно.
Пример:
int nType = ...;
if( boost::is_base_of< ISettable, /* ... magically resolve type hidden by nType here ... */ >::value )
{
// Do something
}
else
{
// Do something else
}
Весь этот топик направлен на то, чтобы понять, что же надо написать вместо «magically resolve type hidden by nType here».
Ruby → Изменение поведения метода в зависимости от контекста
По сути задачка для гиков:
Есть класс А, у него метод save, принимающий один параметр, у
параметра есть значение по умолчанию (допустим, true). Экземпляр
класса А, принимающий метод save без параметров, автоматически
принимает true и работает в соответствии с этим флагом.
Есть класс В, у которого есть поле типа А. При вызове метода save для
этого поля изнутри контекста класса В без параметров управление должно
передаваться другой реализации метода, которая принимает по умолчанию
значение параметра false. Примерно как работает override, но не
глобально, а внутри только одного класса.
Есть класс А, у него метод save, принимающий один параметр, у
параметра есть значение по умолчанию (допустим, true). Экземпляр
класса А, принимающий метод save без параметров, автоматически
принимает true и работает в соответствии с этим флагом.
Есть класс В, у которого есть поле типа А. При вызове метода save для
этого поля изнутри контекста класса В без параметров управление должно
передаваться другой реализации метода, которая принимает по умолчанию
значение параметра false. Примерно как работает override, но не
глобально, а внутри только одного класса.
.NET → Expressions в C# — impress yourself!
.NET 4.0 уже не за горами и принесет кучу всего нового, нужного и не очень, крутого и суперкрутого. Однако и в старом добром .NET 3.5 есть много разных интересных фич, которые не используются в повседенвной работе, но иногда здорово облегчают жизнь разработчикам. Одна из таких замечательных штук — это Expressions.
C++ → Spirit. Спиритические сеансы
Каждый программист в глубине души желает написать свой калькуляторязык программирования, но, вспоминая, как противно было в институте писать полотна в полторы тысячи строк и отлаживать их, прячет глубины своей души подальше от клавиатуры.
Недавно вышел Boost 1.41, а с ним и Spirit 2, синтаксический анализатор, почти равный по возможностям оригинальным регулярным выражениям Perl. Я просто обязан о нём написать.
Сегодня мы попытаемся запрограммировать простой интерпретируемый язык.
Недавно вышел Boost 1.41, а с ним и Spirit 2, синтаксический анализатор, почти равный по возможностям оригинальным регулярным выражениям Perl. Я просто обязан о нём написать.
Сегодня мы попытаемся запрограммировать простой интерпретируемый язык.
Ненормальное программирование → Katahdin: метапрограммирование на грани фантастики
Katahdin — это интерпретируемый язык программирования, в котором синтаксис и семантика могут изменяться во время исполнения. Чтобы идея стала ясна, сразу приведу пример с официального сайта. В примере определяется операция получения остатка от деления ("%" в C, «mod» в Pascal).
class ModExpression : Expression {
pattern {
option leftRecursive;
a:Expression "%" b:Expression
}
method Get() {
a = this.a.Get...();
b = this.a.Get...();
return a - (b * (a / b));
}
}