29

どこかでリッチ・ヒッキーが言ったのを読んだ:

「継続は理論的にはうまくいくかもしれないが、実際にはうまくいかないと思う」

私はクロージュアに慣れていません。
1. clojure には継続がありますか?
2. いいえの場合、継続は必要ありませんか? 私は特にこの男から多くの良い例を見てきました. 代替手段は何ですか?
3. はいの場合、ドキュメントはありますか?

4

7 に答える 7

27

継続について話すときは、2 つの異なる種類の継続を区別する必要があります。

  • ファーストクラスの継続 – 言語 (Scheme または Ruby) に深く統合された継続サポート。Clojure はファーストクラスの継続をサポートしていません。

  • Continuation-passing-style (CPS) – CPS は単なるコーディング スタイルであり、無名関数をサポートするすべての言語でこのスタイルが許可されます (Clojure にも適用されます)。

例:

-- Standard function
double :: Int -> Int
double x = 2 * x

-- CPS-function – We pass the continuation explicitly
doubleCPS :: Int -> (Int -> res) -> res
doubleCPS x cont = cont (2 * x)
; Call
print (double 2)

; Call CPS: Continue execution with specified anonymous function
double 2 (\res -> print res)

ウィキペディアで続きを読む。

良い言語に継続が必要だとは思いませんが、特に Haskell のような関数型言語におけるファーストクラスの継続と CPS は非常に役立ちます (インテリジェントなバックトラッキングの例)。

于 2009-07-23T17:14:39.707 に答える
23

CommonLispに継続を追加するcl-contのClojureポートを作成しました。

https://github.com/swannodette/delimc

于 2009-07-24T06:00:08.247 に答える
18

抽象的な継続

継続は、制御フローのセマンティクスを記述するために使用される抽象的な概念です。この意味で、数値が (抽象エンティティとして) 存在し、存在しないのと同じように、制御演算子を提供するすべての言語 (チューリング完全言語がそうであるように) には存在する場合と存在しない場合 (それらは抽象的であることを思い出してください) の両方があります。存在しない (有形の実体として)。

継続は、関数呼び出し/戻り、例外処理、さらには goto などの制御効果を記述します。よく確立された言語は、とりわけ、継続に基づいて構築された抽象化 (例: 例外) を使用して設計されます。(つまり、十分に確立された言語は、継続を念頭に置いて設計された制御演算子で構成されます。もちろん、言語が継続を唯一の制御抽象化として公開し、ユーザーが独自のものを構築できるようにすることは完全に合理的です。抽象化を上にします。)

ファーストクラス継続

継続の概念が言語で第一級のオブジェクトとして具体化されている場合、あらゆる種類の制御効果を構築できるツールが得られます。たとえば、言語にファーストクラスの継続があり、例外がない場合、継続の上に例外を構築できます。

一流の継続の問題

多くの場合、ファーストクラスの継続は強力で便利なツールですが、言語でそれらを公開することにはいくつかの欠点もあります。

  • 継続の上に構築されたさまざまな抽象化は、構成時に予期しない/非直感的な動作を引き起こす可能性があります。たとえばfinally、継続を使用して計算を中止すると、ブロックがスキップされる可能性があります。
  • 現在の継続がいつでも要求される可能性がある場合、言語ランタイムは、現在の継続のデータ構造表現をいつでも生成できるように構成する必要があります。これは、良くも悪くも「エキゾチック」と見なされることが多い機能のランタイムにある程度の負担をかけます。言語がホストされている場合 (Clojure が JVM でホストされているなど)、その表現は、ホスティング プラットフォームによって提供されるフレームワーク内に収まる必要があります。ソリューション空間を制限する、言語が維持したい他の機能 (C 相互運用機能など) がある場合もあります。このような問題は、「インピーダンスの不一致」の可能性を高め、高性能ソリューションの開発を非常に複雑にする可能性があります。

言語への第 1 級継続の追加

メタプログラミングによって、第一級継続のサポートを言語に追加することができます。通常、このアプローチでは、コードを継続渡しスタイル (CPS) に変換します。このスタイルでは、現在の継続が明示的な引数として各関数に渡されます。

たとえば、David Nolen のdelimcライブラリは、一連のマクロ変換を通じて、Clojure プログラムの部分の区切り付き継続を実装しています。同様に、コードを CPS に変換するマクロ コンパイラであるpulley.cpsと、より多くのコア Clojure 機能 (例外処理など) をサポートし、ネイティブ Clojure コードとの相互運用をサポートするランタイム ライブラリを作成しました。 .

このアプローチの問題点の 1 つは、ネイティブ (Clojure) コードと変換された (CPS) コードの間の境界をどのように処理するかということです。具体的には、ネイティブ コードの継続をキャプチャできないため、ベース言語との相互運用を禁止する (または何らかの方法で制限する) か、ユーザーが実際にキャプチャしたい継続をコンテキストが許可することを保証する負担をユーザーに課す必要があります。捕まる。

pulley.cps は後者の傾向にありますが、ユーザーがこれを管理できるようにする試みがいくつか行われています。たとえば、CPS コードがネイティブ コードを呼び出せないようにすることができます。さらに、既存のネイティブ関数の CPS バージョンを提供するメカニズムが提供されます。

十分に強力な型システムを持つ言語 (Haskell など) では、型システムを使用して、機能的に純粋なコードからの制御操作 (つまり、継続) を使用する計算をカプセル化することができます。

概要

これで、3 つの質問に直接答えるために必要な情報が得られました。

  1. Clojure は、実用的な考慮事項により、ファーストクラスの継続をサポートしていません。
  2. すべての言語は、理論的な意味での継続に基づいて構築されていますが、継続を第一級のオブジェクトとして公開している言語はほとんどありません。ただし、たとえば CPS への変換を介して、任意の言語に継続を追加することは可能です。
  3. delimcおよび/またはpulley.cpsのドキュメントを確認してください。
于 2016-05-19T23:00:56.973 に答える
13

継続は言語に必要な機能ですか?

いいえ、多くの言語には継続がありません。

いいえの場合、継続は必要ありませんか?特にこの男の良い例をたくさん見てきました。代替手段は何ですか?

呼び出しスタック

于 2009-07-23T17:06:25.373 に答える
7

継続の一般的な用途は、関数からの復帰、ループからの脱却、例外処理などの制御構造の実装です。ほとんどの言語 (Java、C++ など) は、コア言語の一部としてこれらの機能を提供します。一部の言語はそうではありません (例: スキーム)。代わりに、これらの言語は継続をファースト クラス オブジェクトとして公開し、プログラマが新しい制御構造を定義できるようにします。したがって、Scheme はそれ自体が完全な言語ではなく、プログラミング言語のツールキットと見なされるべきです。

Clojure では、ほとんどすべての制御構造が言語と VM の組み合わせによって提供されるため、継続を直接使用する必要はほとんどありません。それでも、一流の継続は、有能なプログラマーの手の中で強力なツールになる可能性があります。特にSchemeでは、継続は他の言語の同等の対応物よりも優れています(Cのsetjmp/longjmpのペアなど)。この記事には、これに関する詳細があります。

ところで、リッチ・ヒッキーが継続についての彼の意見をどのように正当化するかを知ることは興味深いでしょう. そのためのリンクはありますか?

于 2009-08-05T08:46:01.757 に答える
6

Clojure (またはむしろclojure.contrib.monads) には継続モナドがあります。その使用法と動機を説明する記事を次に示します

于 2009-12-04T04:24:50.260 に答える
-1

まあ... Clojureの->実装はあなたが求めているものです...しかし、代わりにマクロを使用します

于 2014-01-07T18:54:14.937 に答える