3

さて、私は本当にばかでなければなりません。関数を指定して独自のサブモジュールにラップし、それをrequires するマクロ (より大きな事業の一部) を作成しようとしています。これにより、このように定義された関数が周囲の用語をいじることはできませんが、ホストの残りの部分はモジュールはそれらを通常どおり使用できます。おそらくこれは良い考えではありませんが、冗談を言ってください。なぜそれが不可能なのかわかりません。

次の最小限のコード例を 2 つのファイルにまとめました。

tinylang.rkt:

(provide (all-defined-out))

(define-syntax (modularise stx)
  (syntax-case stx ()
[(_ func)
 (with-syntax ([mod (datum->syntax stx 'testmodule)]
               [nm  (datum->syntax stx 'working)]
               )
   #`(begin

       (print (list "Defining module " 'mod))(newline)

       (module mod racket
         (provide nm)
         (define  nm func)
       )

       (require (for-syntax (submod "." mod))) ;; at least kills a syntax error
       (require (for-template (submod "." mod))) ;; doesn't help
    ))]))

tinyimp.rkt:

#lang racket
(require "tinylang.rkt")
(modularise (lambda () (display "this works!")))
; the following line would make everything work!
;(require (submod "." testmodule))
(working)

ドキュメントで解決するのは些細なことだと思う質問をこのサイトにスパム送信することに罪悪感を覚えますが、どの段階で何が起こるかはまだ明確ではありません. 誰かが良いリソース (本、講義、論文) を知っていれば、それについて聞いて本当にうれしいです. Racket のドキュメントは非常に広範囲に渡っていますが、そこにある説明の重要な詳細を見逃してしまうことがよくあります。

4

1 に答える 1

3

はい、マクロで生成されたrequireとprovideは扱いにくいです。それらのキーは、require-spec (つまり(submod "." testmodule)) のレキシカル スコープです。

ドキュメントから:

require ... では、require-spec のジェネレーターがバインディングのスコープを決定します。

つまり、require-spec と必要な識別子の使用には、同じスコープが必要です。

動作する tinylang.rkt のバージョンは次のとおりです。

#lang racket

(provide (all-defined-out))

(define-syntax (modularise stx)
  (syntax-case stx ()
    [(_ func)
     (with-syntax ([require-spec (datum->syntax stx '(submod "." testmodule))])
       #`(begin
           (module testmodule racket
             (provide working)
             (define working func))
           (require require-spec)))]))
于 2013-09-17T20:48:33.600 に答える