2016-08-20 8 views
1

ラケットで「override」のdefineモジュールがあるとします。この「オーバーライド」は、手続き本体に関する情報を収集し、それをマップに格納します(コンパイルフェーズ中)。今度は、ランタイムフェーズで収集した情報を使用する必要があります。単純な方法では動作しません。フェーズ0でフェーズ1の計算結果を確認

#lang racket 

(require (for-syntax racket)) 

(define-for-syntax map-that-should-be-used-in-phase-0 (make-hash)) 
(define-for-syntax (fill-in-useful-information n) (hash-set! map-that-should-be-used-in-phase-0 n n)) 

; Suppose that some useful information is collected here and stored into a map 
(define-syntax (fill-in-map stx) 
    (begin 
    (fill-in-useful-information 1) 
    (fill-in-useful-information 2) 
    (syntax/loc stx (displayln "OK, the map is filled, but I cannot see it here")))) 

(define-syntax (print-that-map stx) 
    (syntax/loc stx (displayln map-that-should-be-used-in-phase-0))) ; <-- This can not be compiled 

(fill-in-map) 
(print-that-map) 

私はRacketで実行できますか?はいの場合はどうですか?どんなヒントもありがとうございます!

+2

私はこの質問がなぜ棄却されたのか完全に迷っています。私には素晴らしい質問のようです。 –

+0

@AlexisKingコメントをいただき、ありがとうございました。私は彼らに彗星の理由を説明することを期待した。 – dvvrd

答えて

2

変数を参照する識別子はコンパイルできませんが、それが参照できる値は、ラケットが提供するビルトインデータ構造の1つで、不変であれば可能です。

quasisyntaxunsyntaxを使用して、ハッシュテーブル値を構文オブジェクトにスティックすることができます。

> (quasisyntax (foo #,(hash 'a 4 'b 16))) 
#<syntax:5:15 (foo #hash((a . 4) (b . 16)))> 

あなたは、時間を実行するために、コンパイル時から一方通行を通信するために同じことを行うことができます。

(define-for-syntax (hash->immutable-hash hsh) 
    (make-immutable-hash (hash->list hsh))) 

(define-syntax (print-that-map stx) 
    (quasisyntax/loc stx (displayln #,(hash->immutable-hash map-that-should-be-used-in-phase-0)))) 
+0

ありがとう!このアイデアは私の問題を解決するようだ! – dvvrd

関連する問題