Пространство имен define-macro в схеме Gambit-C
Четыре модуля:
- Определяет библиотечные функции
- Определяет макросы библиотеки, которые используют библиотечные функции
- Определяет функции приложения, которые используют макросы библиотеки
- Загружает остальные три
libfunc.scm:
(define (my-func ls) ...)
libmacro.scm:
(define-macro (my-macro ls) (define mfls (my-func ls)) `...
libapp.scm
(define app (begin (my-macro '(1 2 3 ...
libmain.scm
(load "libfunc.scm")
(load "libmacro.scm")
(load "libapp.scm")
(define (main . args) (app ...
Портирование из другой схемы, где это работает, в Gambit-C, где это не так. Я начинаю думать, что это невозможно. Гамбит-С имеет ##define-macro
а также ##namespace
что может быть актуально, но нигде не задокументировано и не подлежит поиску. Одна вещь, которую я нашел в Meroon, большой библиотеке, переносимой на многие Схемы, - это код для работы с Gambit-C.
Редактировать: Я думаю, что Кристиан Квиннек, автор Meroon, хорошо разбирался в вопросах. Он написал 23 вещи, которые я знаю о модулях для Схемы. Я чувствую, что если бы я говорил по-французски и на Scheme, это дало бы мне ответы на все вопросы.
Редактировать 2: Я посмотрел на оригинальную схему, которая была в значительной степени предназначена для запуска системы, которую я пытаюсь портировать. Оказывается, они обманывают. Каждая "функция", которая вызывается из define-macro
имеет теневую реализацию в C, которая присоединена к макроглобальному пространству имен. Это может быть уловка, которую я могу скопировать в Gambit-C, так как он очень ориентирован на C, но я все еще исследую эту возможность.
Я не знаю можно ли нормально звонить define
d функционирует из макроса с использованием синтаксиса case. Я не могу найти ничего простого для понимания (кажется, что большая часть документации написана для phds), но есть очень интересное руководство по define-syntax
а также syntax-case
который показывает, что вы можете реализовать любую функцию в качестве макроса. Он даже реализует базовый Лисп в макросах. Вот и все. Учебник по синтаксическим правилам JRM для просто эксцентричного
Редактировать 3: Как @GoZoner говорит, что это можно сделать с помощью for-syntax
а также define-syntax
по крайней мере в ракетке. Остается увидеть, сможет ли он работать в Gambit-C
#lang racket
(require srfi/1)
(require (for-syntax srfi/1))
(require (for-syntax syntax/stx))
(define-syntax (fnodup x)
(define mydat (delete-duplicates (syntax->datum x)))
(syntax-case mydat ()
[(fnodup f) #'(f) ]
[(fnodup f x0) #'(f x0) ]
[(fnodup f x0 ...) #'(f '(x0 ...)) ]
))
(fnodup print "hi" "der" "hi")
(require (for-syntax ...
Здесь происходит волшебство. Ракетка имеет это. Гамбит-С нет.
1 ответ
Когда "новичок в Схеме", придерживайтесь Схемы. Синтаксическая форма define-macro не является частью какого-либо стандарта Scheme и, согласно приведенному вами примеру, представляет собой крайне низкую систему макросов по сравнению с тем, что содержится в стандарте Scheme.
Посмотрите на R5RS, R6RS или R7RS, чтобы понять syntax-rules
как ваш шаг № 1. После этого syntax-case
в R6RS позволяет делать другие вещи.