-
16-09-2020 - |
質問
スキームの参照により変数をどのように渡すことができますか?
私が欲しい機能の例:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
.
また、参照ごとに戻る方法はありますか?
他のヒント
Jariのように言った、通常は副作用を乱用していることを示唆しているように、通常はスキームの参照による通過を避けたい。
あなたがしたい場合は、cons
ボックスで参照したいものを囲むことができます。
(cons 5 (void))
.
5を含むボックスを生成します.5から6を変更する手順にこのボックスを渡すと、オリジナルのボックスには6が含まれます。もちろん、必要に応じてcons
とcar
を忘れないでください。
CHEZ方式(およびおそらく他の実装)には、このボックス/アンボックス化ナンセンスのために具体的にはbox
(およびその仲間box?
およびunbox
)と呼ばれる手続きがあります。 http://www.scheme.com/csug8/Objects.html#./Objects:s43
マクロを使用できます。
scheme@(guile-user)> (define-macro (foo var)`(set! ,var 5))
scheme@(guile-user)> (define y 2)
scheme@(guile-user)> (foo y)
scheme@(guile-user)> (display y)(newline)
5
. ラムダ!
(define (foo getx setx)
(setx (+ (getx) 5)))
(define y 2)
(display y)(newline)
(foo
(lambda () y)
(lambda (val) (set! y val)))
(display y)(newline)
. Jariは正しいですが、少なくとも変数では、参考に渡していくのはやや疑わしいです。しかし、あなたが望む行動は使われ、多くの場合、クロージャを使ってやることによって、より多くのスキームではずっと推奨されます。ページ181およびページ181182 (Google Books)で、季節のスキームでより良い仕事をすることができます。
これは、Cのようなシンタックスを「渡し」にすることを可能にするマクロを与えるための基準です。Olegs Siteは興味深い読み取りのための金鉱ですので、まだ持っていない場合は必ずマークを付けてください。
その外部コンテキストで定義されている関数内からの外部コンテキストに影響を与えることができ、これは参照変数によるパスの影響、すなわち副作用を持つ関数を与えます。
(define (outer-function)
(define referenced-var 0)
(define (fun-affects-outer-context) (set! referenced-var 12) (void))
;...
(fun-affects-outer-context)
(display referenced-var)
)
(outer-function) ; displays 12
.
この解決策は副作用の範囲を制限します。
ERIによるサブコメントに記載されているように(X(ボックス5))、(ボックスX)など、
の短所と同じです。あなたはおそらくC、PHP、または何でも使い過ぎました。 スキームでは、パスバイ*のようなものをしたくありません。 最初にどのようなスコープを意味するか、そして異なる実装がどのように振る舞うか(特にLispとSchemeの間の違いは何を把握しようとしています)。
本質によって純粋に機能的なプログラミング言語は副作用を持っていません。その結果、通過順序は機能的な概念ではないことを意味します。