2

: これは Gauche Scheme バージョン 0.9.3.3 のようです。
私はこれらの Lisp 言語に頭を悩ませているようには見えません :/.

Scheme で for ループ構文を定義しようとしています。これが再帰関数で実行可能かどうかはわかりませんが (可能だと思います)、この時点で本当にdefine-syntax作業を開始したいと考えています。

次のコードを使用して、ループを 1 回実行することができます (その後、ループが終了したように見えます)。

(define-syntax forloop
  (syntax-rules ()
    ((forloop start stop exps)
      (letrec ((aloop (lambda (astart astop aexps)
        (if (<= astart astop) (begin aexps (aloop (+ astart 1) astop aexps))))))
          (aloop start stop exps)))))

省略記号で定義することもできればいいのですが、これでは「テンプレートに一定の形式の繰り返しが含まれる」ことになります。R5RS 仕様のマクロ セクションを読みましたが、すぐにテンプレート セクションを読み直す予定です。

(define-syntax forloop
  (syntax-rules ()
    ((forloop start stop exps ...)
      (letrec ((aloop (lambda (astart astop aexps ...)
        (if (<= astart astop) (begin aexps ... (aloop (+ astart 1) astop aexps ...))))))
        (aloop start stop exps ...)))))

私はこれを最初に試しましたが、出力なしで失敗する前に約10秒間実行されます...私はcompileonline.comを使用しているので、何か関係があるかもしれません:

(define-syntax forloop
  (syntax-rules ()
    ((forloop start stop exps ...) 
      (if (<= start stop) 
        (begin exps ... (forloop (+ start 1) stop exps ...))))))

forloop を呼び出さなくても問題はありません (マクロを展開する必要がないためだと思います)。したがって、これらをテストするために使用したコードは次のとおりです。

(forloop 6 8 (display "g"))

私は何を間違っていますか?私はステートメントを正常に実装しましたwhen(私自身ですが、そこには何十もの例があり、私はすでにそれらの多くを見てきました)。私がやりたいことの再帰的な性質と省略記号が私を台無しにしていると思います。

4

1 に答える 1

2

マクロはコンパイル時に展開されるため、 の値(実行時に評価される)に関係なく、ようなものは何度(begin exps ... (forloop (+ start 1) stop exps ...))も展開されます。forloop(+ start 1)

おそらく、少なくとも で実行できる最善のsyntax-rules方法は、マクロを使用して実行する式のみをキャプチャし、マクロ以外のコードを使用してループに対処することです。

(define-syntax forloop
  (syntax-rules ()
    ((forloop start stop exps ...)
     (let ((j stop))
       (let loop ((i start))
         (when (<= i j)
           exps ...
           (loop (+ i 1))))))))

doループを使用することもできます:

(define-syntax forloop
  (syntax-rules ()
    ((forloop start stop exps ...)
     (let ((j stop))
       (do ((i start (+ i 1)))
           ((> i j))
         exps ...)))))
于 2013-12-28T04:11:58.660 に答える