1

とりわけ、新しいグローバルシンボルを定義する関数が必要です。私がこのようにそれを使うことができるように:

(define (func-prototype symbol value comment)
  (define symbol value) ; this should somehow be reformulated
  (format "~a=~a   !~a\n" symbol value comment))

(define string-list (map func-prototype
                         '((s1 1 "first value")
                           (s2 20 "second value")
                           (s3 300 "third value))))

そして、次の結果を得ることができます:

> string-list
'("s1=1  !first value\n"
  "s2=20  !second value\n"
  "s3=300  !third value\n")
> s1
1
> s2
20
> s3
300

これは関数として実装できますか、それともマクロの助けを借りてのみ実装できますか?可能な実装を提案するか、少なくとも役立つかもしれないいくつかのヒント/リファレンスを教えてください。

4

3 に答える 3

3

一般的なアプローチを再考して、よりシンプルにします。私の提案:グローバルハッシュテーブルを定義し、関数内にバインディングを追加します。次に例を示します。

(define value-map (make-hash))

(define (func-prototype symbol value comment)
  (hash-set! value-map symbol value)
  (format "~a=~a   !~a\n" symbol value comment))

次のように使用します。

(define string-list
  (map (lambda (lst)
         (apply func-prototype lst))
       '((s1 1   "first  value")
         (s2 20  "second value")
         (s3 300 "third  value"))))

string-list
=> '("s1=1   !first  value\n"
     "s2=20   !second value\n"
     "s3=300   !third  value\n")

また、ハッシュテーブル内のシンボルの1つを参照する必要がある場合は、次のようにします。

(define (get key)
  (hash-ref value-map key))

(get 's1)
=> 1
(get 's2)
=> 20
(get 's3)
=> 300
于 2013-03-11T16:54:07.750 に答える
2

一般に、あなたが説明した方法であなたが達成しようとしていることを達成することは不可能です。あなたの唯一の望みは、ファイルに何かを書き、次にloadそのファイルをインタラクティブセッションに書き出すことです。しかし、それでも。

スキームでは、トップレベルを除いて、目的s1の、、、などのトップレベルの名前を導入することはできません。そのためには、マクロを次のように定義できます。s2s3

>(define-syntax define-foo
  (syntax-rules ()
    ((_ name value)
     (define name value))))

>(define-foo s1 1)
<undefined>
> s1
1

関数でそのマクロを使用しようとすると、関数の本体は式で終了する必要があり、上記のマクロが展開されるような定義形式はローカル変数になるため、サイコロではありません。あれは:

(define (func-prototype name value comment)
   (define-foo name value)
   name)

>(func-prototype 's1 1 "com")
1
> s1
<error>

文字列リストが定数である場合に機能するアプローチの1つは、次のようになります。

> (define-syntax declare-variables
    (syntax-rules ()
      ((_ (name value comment) ...)
       (begin
         (define name value)
         ...))))

> (declare-variables (s1 1 "com") (s2 20 "com") (s3 300 "com"))
> s1
1

これで完了しますが(「コメント」の使用は無視しました)、前述したように、コンパイル時の文字列リストが必要です。

うまくいくと思うかもしれないが、うまくいかない可能性の1つは、次のように使用することevalです。

   (eval '(define s1 1) (environment ...))

ただし、「eval」は式に対してのみ機能し、宣言に対しては機能しません。これにより、可能性として「ロード」に戻ることができます。

于 2013-03-11T18:48:56.343 に答える
2

まず、これを本当に実行したいかどうか、または別のソリューション(ハッシュテーブルなど)も機能するかどうかを検討します。

手順を使用して、リフレクションと動的評価でこれを行うことができます。eval

;; define-variable-with-value! : symbol any -> void
(define (define-variable-with-value! name value)
  (eval `(define ,name (quote ,value))))

これquoteは重要です。そうしないと、評価する式としてを再解釈するリスクがあります。違いを確認するには、例を検討してください

(define-variable-with-value! 'x (list 'error "kaboom"))
于 2013-03-11T20:41:51.007 に答える