本でローカル定義について読んでいて、この例に出くわしました-
(local ((define (f x) (+ x 5))
(define (g alon)
(cond
[(empty? alon) empty]
[else (cons (f (first alon)) (g (rest alon)))])))
(g (list 1 2 3)))
ここで正確に何をlocal
しますか?
local
HtDP 言語の一部としてここに、またはモジュールの一部としてここに文書化されています。local
それぞれ順番に見ていきましょう。最初にHtDPのもの:
(local [definition ...] expression)
式で使用する関連定義をグループ化します。各定義は、define または define-struct のいずれかです。local を評価する場合、各定義が順番に評価され、最後に body 式が評価されます。ローカル内の式 (定義および式の右側を含む) のみが、定義によって定義された名前を参照できます。ローカルで定義された名前がトップレベルのバインディングと同じである場合、内側のものは外側のものを「覆い隠し」ます。つまり、ローカル内では、その名前への参照は内部のものを参照します。
次に、local
モジュール内のもの:
(local [definition ...] body ...+)
letrec-syntaxes+values と同様ですが、バインドがトップレベルまたはモジュール本体と同じ方法で表現される点が異なります: define、define-values、define-syntax、struct などを使用します。定義フォームを部分的に展開することによる定義 (部分展開を参照)。トップレベルまたはモジュール本体と同様に、begin-wrapped シーケンスが一連の定義にスプライスされます。
したがって、使用している言語/モジュールに応じてlocal
、どれが見つかったかがわかります。そして明らかに、これは標準の特殊な形式ではありません。
Local は、特定の関数のスコープでいくつかのヘルパー関数を定義するために使用されます。たとえば、指定された list のすべての要素に 5 を追加する関数を作成しています。
(define (add-5-to-list list)
(local
( ;; definition area start
(define (f x) (+ x 5))
(define (g alon)
(cond
[(empty? alon) empty]
[else (cons (f (first alon))
(g (rest alon)))]))
) ;; definition area end
(g list)
) ;; local end
) ;; define end
ローカルで好きなだけ関数を定義できます。ただし、メイン関数のスコープ内でのみ使用できます (ここでのメイン関数は add-5-to-list です)。