Геймдев на Lisp. Часть 1: метаязыковая абстракция
В этой серии руководств мы углубимся в создание простых 2D-игр на Common Lisp. Результатом первой части станет настройка среды разработки и базовая симуляция, отображающая 2D-сцену с большим количеством физических объектов. Предполагается, что читатель знаком с каким-либо языком программирования высокого уровня, имеет общее представление о том, как графика отображается на экране компьютера, и заинтересован в расширении своих горизонтов.
Common Lisp — это язык программирования с богатой историей предоставления эффективных инструментов для разработки сложных интерактивных приложений, таких как видеоигры. Эта серия руководств нацелена на демонстрацию ряда возможностей CL, которые органично вписываются в контекст разработки игр. Краткий обзор этих возможностей и уникальных особенностей Common Lisp приведён в статье Юкари Хафнер "Using a Highly Dynamic Language for Development".
Многие особенности, впервые представленные в Lisp, такие как конструкция условного оператора if/then/else, функции как объекты первого класса, сборка мусора и другие, давно вошли в мейнстрим языков программирования. Однако одной из уникальных особенностей, которую мы рассмотрим сегодня, является метаязыковая абстракция.
Метаязыковая абстракция
Чтобы по-настоящему понять этот концепт, обратимся к известному фундаментальному учебнику Structure and Interpretation of Computer Programs:
Однако, сталкиваясь с всё более сложными задачами, мы обнаружим, что Lisp или любой другой фиксированный язык программирования оказывается недостаточным для наших нужд. Нам постоянно приходится обращаться к новым языкам, чтобы выражать наши идеи более эффективно. Создание новых языков — мощная стратегия управления сложностью в инженерном проектировании; зачастую мы можем повысить свои способности справляться со сложными задачами, приняв новый язык, который позволяет описывать (а значит — и осмысливать) проблему по-новому, используя примитивы, средства комбинирования и абстракции, особенно подходящие для данной задачи.
Метаязыковая абстракция — создание новых языков — играет важную роль во всех областях инженерного проектирования.
Понять это — значит изменить своё представление о себе как о программисте. Мы начинаем воспринимать себя как дизайнеров языков, а не просто пользователей языков, созданных другими.
Таким образом, важнейшим механизмом, предоставляемым практически любым диалектом Lisp, включая, конечно, один из самых мощных — Common Lisp, является возможность создавать собственные языковые конструкции внутри самого языка. Эта концепция также известна как DSL (Domain Specific Languages, предметно-ориентированные языки), но только в диалектах Lisp она невероятно глубоко интегрирована в саму суть языка. Во многих из них механизм метаязыковой абстракции построен вокруг так называемых макросов — специальных функций, определяемых программистом, которые вызываются на этапе компиляции и возвращают фрагменты кода, подставляемые компилятором в местах вызова.
Отличительная особенность Lisp'ов в том, что код по своей сути является обычным вложенным списком, что делает генерацию и обработку фрагментов программного кода простой и эффективной.
Существует множество способов творчески использовать (и злоупотреблять) этой возможностью. Я хочу представить созданную мной макробиблиотеку cl-fast-ecs, которая предоставляет мини-язык для описания игровых объектов и правил их обработки с использованием паттерна Entity-Component-System, часто применяемого в разработке игр.
Перевод статьи: ссылка