Пространство имен define-macro в схеме Gambit-C

Четыре модуля:

  1. Определяет библиотечные функции
  2. Определяет макросы библиотеки, которые используют библиотечные функции
  3. Определяет функции приложения, которые используют макросы библиотеки
  4. Загружает остальные три

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, но я все еще исследую эту возможность.

Я не знаю можно ли нормально звонить defined функционирует из макроса с использованием синтаксиса 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 позволяет делать другие вещи.

Другие вопросы по тегам