В какой степени макросы «функционируют в обратном порядке»?

Я пишу код на Лиспе на Haskell(на GitHub ), чтобы больше узнать об обоих языках.

Новейшей функцией, которую я добавляю, являются макросы. Не гигиенические макросы или что-то необычное -, а простые преобразования ванильного кода. Моя первоначальная реализация имела отдельную макросреду, отличную от среды, в которой живут все остальные значения. Между функциями readи evalя вставил еще одну функцию, macroExpand,который обходил дерево кода и выполнял соответствующие преобразования каждый раз, когда находил ключевое слово в среде макроса, прежде чем окончательная форма была передана в evalдля оценки. Приятным преимуществом этого было то, что макросы имели то же внутреннее представление, что и другие функции, что уменьшало некоторое дублирование кода.

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

eval env (List (function : args)) = do
    func <- eval env function
    case func of 
        (Macro {}) -> apply func args >>= eval env
        _          -> mapM (eval env) args >>= apply func

Он работает следующим образом:

  1. Если вам передается список, содержащий начальное выражение и кучу другие выражения...
  2. Вычислить первое выражение
  3. Если это макрос, то применить его к аргументам и оценить результат
  4. Если это не макрос, то оценить аргументы и применить функцию к результату

Как будто макросы точно такие же, как функции, за исключением того, что порядок eval/apply изменен.

Это точное описание макросов? Я упускаю что-то важное, реализуя макросы таким образом? Если ответы «да» и «нет», то почему я никогда раньше не видел такого объяснения макросов?

20
задан Peter Mortensen 21 April 2012 в 11:23
поделиться