4 つのモジュール:
- ライブラリ関数を定義します
- ライブラリ関数を使用するライブラリ マクロを定義します。
- ライブラリ マクロを使用するアプリケーション関数を定義します
- 他の 3 つをロードします。
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 への移植。無理だと思い始めています。Gambit-C has##define-macro
および##namespace
which は関連する可能性がありますが、どこにも文書化されておらず、Google で検索できません。多くのスキーム間で移植可能な大きなライブラリである Meroon で私が見つけたものの 1 つは、Gambit-C を回避するためのこのコードです。
編集: Meroon の作者である Christian Queinnec は、この問題をうまく処理していたと思います。彼は、Scheme のモジュールについて私が知っている 23 のことを書きました。フランス語とスキームの両方を話せば、すべての答えが得られるような気がします。
編集 2 : 移植しようとしているシステムを実行するために構築された元のスキームを調べました。彼らはだますことがわかりました。から呼び出されるすべての「関数」にはdefine-macro
、マクロ グローバル名前空間に関連付けられた C のシャドウ実装があります。Gambit-C は非常に C 指向であるため、Gambit-C でコピーできるトリックかもしれませんが、その可能性はまだ調査中です。
define
構文ケースを使用してマクロから通常の d 関数を呼び出すことができるかどうかはわかりません。私はそれについて理解しやすいものを見つけることができません (ほとんどのドキュメンテーションは Phds によって、そして Phds のために書かれているようです) が、マクロとして任意の関数を実装できることを示す非常に興味深いチュートリアルがdefine-syntax
あります。syntax-case
マクロで基本的な Lisp を実装することさえできます。それは何かです。単なるエキセントリックのための JRM の構文規則入門
編集 3 : @GoZonerのように、少なくとも Racket ではfor-syntax
andを使用してこれを行うことができます。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 ...
魔法が起こる場所です。ラケットにはそれがあります。Gambit-C はそうではありません。