1

let、letrec、let* の違いに苦労しています...スキームは私の主要なプログラミング言語ではないため、私の記憶は長い間存在していません..私はこの機能を持っています..今、私はここで letrec と非常に混乱しています..これも再帰です。理解できます...しかし、このコードでは十分に接続できません..(再帰についてまだ混乱しているかもしれません)誰かがここでletrecが必要な理由を説明できますか

(define myFunc
  (lambda (start end res func)
    (letrec ((func:rec_func
              (lambda (x i y)
                (if (>= i start)
                    (func:rec_func (cons i x) (- i res) (cons (func i) y))  ;; line6
                    (cons x (cons y '()))))))                               ;; line7
      (func:rec_func '() end '()))))

(編集済み)私が理解しているのは末尾再帰です

⇒【Q1】末尾再帰ですか?

⇒【Q2】では、末尾再帰は常にletrecを使うべきでしょうか?

この関数は、開始、終了の境界を持つ x、y のリストを返すため、インデックス i が境界内にあるかどうかをチェックし、そうであれば 6 行目を実行します。

→【Q3】では、line6は何をしているのですか?line6が届かない

4

3 に答える 3

7

letrec、let、および let* との違いは、プログラムで使用できる宣言をいつ行うかです。

(letrec ((X (you could use X here))
         (Y (you could use X here too))
         )
     (X also is available here)
)


(let   ((X (nope, X isn't declared yet))
         (Y (in fact, no declaration body will see X))
         )
     (But X is available here)
)


(let* ((X (X isn't available here))
         (Y (but you could use it here))
         )
     (X also is available here)
)

要点をまとめると:

  1. letrec で宣言された変数のスコープは、letrec の本体内のすべてです。コンパイラは、宣言が終了した後に参照が置き換えられるように、いくつかの魔法を行います。
  2. let* で宣言された変数のスコープは、変数宣言後の let* のスコープ内のすべての式です。
  3. また、let で宣言された変数のスコープは、let の本体であり、宣言部分ではありません。
于 2014-05-25T05:39:42.723 に答える
1

私の記憶が正しければ、この構成体は、の本体がそれ自体を参照するのではletrecなく、letまたはそのlet*ために必要です。ここでorfunc:rec_funcを使用した場合、ネストされたラムダ内のシンボルは、トップレベル フォームの外部に表示される任意の定義にバインドされるか、そのような定義がない場合は undefined になります。どちらも必要なものではありません。letlet*func:rec_func

于 2014-05-25T02:00:35.207 に答える
0

【Q1】末尾再帰ですか?

回答はい、末尾再帰を行います。

【Q2】では、末尾再帰は常にletrecを使うべきでしょうか?

回答あなたの質問を解釈するには 2 つの方法があります。

  1. 常にletrec末尾再帰を使用する必要がありますか? 私はあなたがこれを尋ねるつもりはなかったと思います。しかし ...

    答えはノーだ。トップレベルのラムダ関数も末尾再帰に使用できます。

  2. letrec常に末尾再帰を使用する必要がありますか?

    その答えは次のとおりです。再帰関数は末尾再帰である方がよいです。可能であれば、末尾再帰にする必要があります。

【Q3】ではline6って何?

6 行目のコードは、再帰呼び出しを実行します。

としましょう、startです、およびです。の最初の呼び出しでは、は空のリスト、is 、およびは空のリストです。0end5res1func:rec_funcx()i5y()

最初の再帰関数が 6 行目で呼び出されると、引数は(cons i x)(- i res)、およびであり、これらは、 、および(cons (func i) y)に評価されます。(5)4((func 5)

次の反復では、引数は(4 5)3、および((func 4) (func 5))です。

i未満になるまで続けstartます。その後、再帰は結果で停止します((0 1 2 3 4 5) ((func 0) (func 1) (func 2) (func 3) (func 4) (func 5)))

7 行目のコードは、再帰の終了基準が満たされたときに実行されます。これは、(>= i start)false の場合です。

于 2014-05-25T03:38:47.867 に答える