| パラダイム | マルチパラダイム:機能的、命令的、メタ |
|---|---|
| 家族 | リスプ |
| デザイン: | ガイ・L・スティール ジェラルド・ジェイ・サスマン |
| 初登場 | 1975年 |
| 安定リリース | R7RS / 2013 |
| タイピングの規律 | ダイナミック、潜在的、強力 |
| 範囲 | 語彙 |
| ファイル名拡張子 | .scm、.ss |
| Webサイト | 詳しくはこちら |
| 主な実装 | |
| 多数 (Scheme実装を参照) | |
| 影響を受けた | |
| ALGOL、Lisp、MDL | |
| 影響を受けた | |
| Clojure、Common Lisp、Dylan、EuLisp、Haskell、Hop、JavaScript、Julia、Lua、MultiLisp、Python、R、Racket、Ruby、Rust、[1] S、Scala、T | |
SchemeはLisp系プログラミング言語の方言である。Schemeは1970年代にMITコンピュータサイエンスおよび人工知能研究所(MIT CSAIL)で開発され、開発者のGuy L. SteeleとGerald Jay Sussmanによって、現在Lambda Papersとして知られる一連のメモとして公開された。Schemeは、語彙スコープを選択した最初のLisp方言であり、実装に末尾呼び出し最適化の実行を要求した最初のLisp方言であり、関数型プログラミングと再帰アルゴリズムなどの関連技術をより強力にサポートしている。また、第一級継続をサポートした最初のプログラミング言語の1つでもある。Common Lispの開発につながった取り組みに大きな影響を与えた。[2]
Scheme言語は、電気電子技術者協会(IEEE)の公式標準[3]と、アルゴリズム言語Schemeの改訂版報告書(R n RS)と呼ばれる事実上の標準で標準化されています。広く実装されている標準はR5RS(1998)です。[4] Schemeの最も最近承認された標準は「R7RS-small」(2013)です。[5]より拡張的でモジュール化されたR6RSは2007年に承認されました。[6]どちらもR5RSから派生しており、以下のタイムラインは承認の時系列を反映しています。
歴史
起源
Schemeは1970年代にCarl HewittのActorモデルを理解する試みとして始まり、その目的でSteeleとSussmanはMaclispを使用して「小さなLispインタープリタ」を書き、次に「アクターを作成してメッセージを送信するためのメカニズムを追加しました。」[7] Schemeは元々、 PlannerやConniverなどの他のLisp派生言語 の伝統に倣い、「Schemer」と呼ばれていました。現在の名前は、作者がファイル名を最大6文字の2つのコンポーネントに制限するITSオペレーティングシステムを使用したことに由来しています。現在、「Schemer」はSchemeプログラマーを指すのに一般的に使用されています。
R6RS
2003 年の Scheme ワークショップで新しい言語標準化プロセスが開始され、2006 年に R6RS 標準を作成することが目標となりました。このプロセスは、以前の全会一致の R n RS アプローチを破りました。
R6RSは標準モジュールシステムを備えており、コア言語とライブラリを分割することができます。R6RS仕様のドラフトがいくつかリリースされ、最終バージョンはR5.97RSです。投票の結果、新しい標準が承認され、2007年8月28日に発表されました。[6]
現在、さまざまなScheme実装の最新リリース[8]はR6RS標準をサポートしています。R6RS用に提案された暗黙的に段階的に分割されたライブラリの移植可能な参照実装であるpsyntaxがあり、これはさまざまな古いScheme実装で適切にロードおよびブートストラップされます。[9]
R6RS の特徴の 1 つは、レコード型記述子 (RTD) です。RTD を作成して使用すると、レコード型表現によってメモリ レイアウトを表示できます。また、オブジェクト フィールドのビット マスクと変更可能な Scheme オブジェクト フィールドのビット マスクを計算し、ガベージ コレクタが RTD に保存されているフィールド リスト全体を走査することなく、フィールドの処理方法を知るのに役立ちました。RTD を使用すると、ユーザーは基本的な RTD を拡張して新しいレコード システムを作成できます。[10]
R6RS では、言語に数多くの重要な変更が導入されています。[11] ソース コードはUnicodeで指定されるようになり、Unicode 文字の大部分のサブセットが Scheme のシンボルと識別子に表示できるようになりました。また、語彙規則にその他の小さな変更が加えられています。文字データも Unicode で指定されるようになりました。多くの標準手続きが新しい標準ライブラリに移動されました。新しい標準ライブラリ自体が標準の大幅な拡張を構成し、以前は標準の一部ではなかった手続きと構文形式が含まれています。新しいモジュール システムが導入され、例外処理のシステムが標準化されました。syntax-rules は、マクロ展開時に Scheme 全体を使用できる、より表現力の高い構文抽象化機能 (syntax-case) に置き換えられました。準拠した実装では、 Scheme の完全な数値タワーをサポートすることが要求され、数値の意味論が拡張されました。これは主に、浮動小数点数値表現の IEEE 754標準をサポートする方向です。
R7RS
R6RS標準は、ミニマリストの哲学からの逸脱と見る人もいるため、論争を巻き起こした。[12] [13] 2009年8月、標準化プロセスを監督するScheme運営委員会は、Schemeを2つの言語に分割することを推奨する意向を発表した。1つはプログラマー向けの大規模で現代的なプログラミング言語、もう1つは教育者や一般の実装者から賞賛されているミニマリズムを維持した大規模バージョンのサブセットである小規模バージョンである。 [14] Schemeのこの2つの新しいバージョンに取り組むために、2つのワーキンググループが設立された。Scheme Reports Processサイトには、ワーキンググループの憲章、公開ディスカッション、問題追跡システムへのリンクがある。
R7RS(小さな言語)の第9草案は、2013年4月15日に公開されました。[15]この草案を批准する投票は2013年5月20日に締め切られ、[16]最終報告書は2013年8月6日から公開されており、「その取り組みの「小さな」言語:したがって、R6RSの後継として単独で考えることはできない」と説明されています。[5]
特徴的な機能
Scheme は主に関数型プログラミング言語です。Lisp プログラミング言語ファミリーの他のメンバーと多くの特徴を共有しています。Scheme の非常に単純な構文は、 S 式 (プレフィックス演算子の後に引数が続く括弧で囲まれたリスト) に基づいています。したがって、Scheme プログラムはネストされたリストのシーケンスで構成されます。リストは Scheme の主要なデータ構造でもあり、ソース コードとデータ形式がほぼ同等です (同図法性)。Scheme プログラムは、Scheme コードの一部を動的に簡単に作成および評価できます。
データ構造としてのリストへの依存は、すべての Lisp 方言に共通しています。Scheme は、Lisp の祖先から、、などの豊富なリスト処理プリミティブを継承しています。Scheme は、厳密かつ動的に型付けされた変数を使用し、ファーストクラスプロシージャをサポートしています。したがって、プロシージャは変数に値として割り当てたり、プロシージャに引数として渡したりできます。
conscarcdr
このセクションでは、Scheme を他の Lisp と区別する機能を含む、言語の革新的な機能を中心に説明します。特に明記しない限り、機能の説明は R5RS 標準に関連しています。このセクションの例では、直前の行の式を評価した結果を示すために、「===> 結果」という表記が使用されています。これは、R5RS で使用されているのと同じ規則です。
ミニマリズム
Scheme は非常にシンプルな言語で、同等の表現力を持つ他の多くの言語よりも実装がはるかに簡単です。[17]この容易さは、ラムダ計算 を使用して、言語の構文の多くをより基本的な形式から導出することによるものです。たとえば、R5RS Scheme 標準で定義されている 23 の s 式ベースの構文構造のうち、14 は派生形式またはライブラリ形式に分類され、主にラムダなどのより基本的な形式を含むマクロとして記述できます。R5RS (§3.1) には次のように書かれています。「変数バインディング構造の中で最も基本的なのはラムダ式です。他のすべての変数バインディング構造はラムダ式で説明できるためです。」[4]
- 基本形式: define、lambda、quote、if、define-syntax、let-syntax、letrec-syntax、syntax-rules、set!
- 派生形式: do、let、let*、letrec、cond、case、and、or、begin、named let、delay、unquote、unquote-splicing、quasiquote
例:変数バインディングを実行するために
let使用する式として実装するマクロ。lambda
(構文定義let (構文規則() (( let (( var expr ) ... )本体... ) (( lambda ( var ... )本体... )式... ))))
したがって、let上記の定義に従って を使用すると、Scheme 実装では " (let ((a 1)(b 2)) (+ b a))" が " ((lambda (a b) (+ b a)) 1 2)" に書き換えられ、実装のタスクがプロシージャのインスタンス化をコーディングするタスクにまで軽減されます。
1998 年、サスマン氏とスティール氏は、Scheme のミニマリズムは意識的な設計目標ではなく、設計プロセスの意図しない結果であると述べました。「私たちは実際に複雑なものを作ろうとしていましたが、偶然にも、すべての目標を満たしながらも、意図していたよりもはるかに単純なものを設計してしまったことに気付きました...ラムダ計算 (小さくて単純な形式) が、強力で表現力豊かなプログラミング言語の核として機能できることに気付きました。」[7]
語彙範囲
ほとんどの現代のプログラミング言語と同様に、またMaclispなどの初期の Lisp とは異なり、Scheme はレキシカル スコープです。つまり、プログラム ユニットのテキストを読み取ることで、プログラム ユニットが呼び出されるコンテキストを考慮せずに、プログラム ユニット内のすべての可能な変数バインディングを分析できます。これは、当時のコンパイラとインタープリタでレキシカル スコープ アルゴリズムを実装するために使用された原始的なテキスト置換方法に関連する処理コストが原因で、初期の Lisp 方言の特徴であった動的スコープとは対照的です。それらの Lisp では、呼び出しのコンテキストに応じて、プロシージャ内の自由変数への参照がプロシージャ外部のまったく異なるバインディングを参照することが完全に可能でした。
1970年代初頭には珍しいスコープモデルであったレキシカルスコープを新しいバージョンのLispに組み込むきっかけとなったのは、サスマンのALGOLの研究だった。彼は、ALGOLのようなレキシカルスコープのメカニズムが、ヒューイットのアクターモデルをLispに実装するという当初の目標を実現するのに役立つだろうと示唆した。[7]
Lisp方言に語彙スコープを導入する方法に関する重要な洞察は、サスマン氏とスティール氏の1975年のラムダ論文「Scheme: 拡張ラムダ計算のためのインタープリタ」[18]で広く知られるようになりました。この論文では、 1970年にジョエル・モーゼス氏がAIメモで説明し、ピーター・J・ランディン氏のアイデアであるとした語彙閉包の概念(21ページ)を採用しました。[19]
ラムダ計算
アロンゾ・チャーチの数学表記法であるラムダ計算は、Lisp で手続きを導入するためのキーワードとして「ラムダ」を使用するきっかけとなったほか、 Lisp で高階関数を使用する関数型プログラミング技術の発展にも影響を与えた。しかし、初期の Lisp は自由変数の扱い方からラムダ計算の適切な表現ではなかった。[7]
形式的なラムダシステムには公理と完全な計算規則があり、数学的論理とツールを使用した分析に役立ちます。このシステムでは、計算は方向性のある演繹として見ることができます。ラムダ計算の構文は、x、y、z、...、括弧、スペース、ピリオド、記号λからの再帰式に従います。[20]ラムダ計算の機能は次のとおりです。まず、強力な数学的論理の出発点として機能します。次に、機械評価を模倣するために使用できるため、プログラマが実装の詳細を考慮する必要性を減らすことができます。最後に、ラムダ計算は実質的なメタ理論を作成しました。[21]
レキシカルスコープの導入により、ラムダ記法のいくつかの形式と、実用的なプログラミング言語での実際の表現とが同等になり、問題が解決されました。サスマンとスティールは、ラムダ式を単純な手続きのインスタンス化としてではなく「制御構造と環境修飾子」として使用することで、新しい言語を使用して、ALGOLやFortranなどの他のプログラミング言語のすべての命令型および宣言型セマンティクス、および他のLispの動的スコープをエレガントに導出できることを示しました。 [22]彼らは、最初のLambda PapersでSchemeの最初の説明とともに継続渡しスタイルを導入し、その後の論文で、ラムダ計算のこの実際の使用の真の力を実証しました。
ブロック構造
Scheme は、以前のブロック構造言語、特にALGOLからブロック構造を継承しています。Scheme では、ブロックは 、およびの 3 つのバインディング構成要素によって実装されます。たとえば、次の構成要素はlet、というシンボルが数値 10 にバインドされる
ブロックを作成します。let*letrecvar
( define var "goose" ) ;; ここでの var への参照はすべて "goose" にバインドされます( let (( var 10 )) ;; ステートメントはここに記述します。ここでの var への参照はすべて 10 にバインドされます。) ;; ここでの var への参照はすべて "goose" にバインドされます
ブロックをネストして、プログラマーのニーズに応じて任意の複雑なブロック構造を作成できます。ブロック構造を使用してローカル バインディングを作成すると、発生する可能性のある名前空間の衝突のリスクが軽減されます。
の 1 つの変形である ではlet、let*バインディングが同じ構造内で以前に定義された変数を参照することを許可します。
( let* (( var1 10 ) ( var2 ( + var1 12 ))) ;; しかし、var1の定義はvar2を参照できませんでした)
もう 1 つのバリアントは、相互に再帰的な手順を相互にバインド
letrecできるように設計されています。
;; ホフスタッターの男性と女性の配列をペアのリストとして計算する
( define ( hofstadter-male-female n ) ( letrec ((女性( lambda ( n ) ( if ( = n 0 ) 1 ( - n (男性(女性( - n 1 ))))))) (男性( lambda ( n ) ( if ( = n 0 ) 0 ( - n (女性(男性( - n 1 ))))))) ( let loop (( i 0 )) ( if ( > i n ) ' () ( cons ( cons (女性i ) (男性i )) ( loop ( + i 1 )))))))
(ホフスタッター-男性-女性8 )
===> (( 1 . 0 ) ( 1 . 0 ) ( 2 . 1 ) ( 2 . 2 ) ( 3 . 2 ) ( 3 . 3 ) ( 4 . 4 ) ( 5 . 4 ) ( 5 . 5 ) )
(この例で使用されている定義については、 Hofstadter の男性と女性のシーケンスを参照してください。)
1 つの にバインドされたすべてのプロシージャは、letrec名前によって相互に参照したり、同じ 内で以前に定義された変数の値を参照したりできますが、同じ 内で後で定義された値letrecを参照することはできません。
letrec
の変形であるlet「名前付き let」形式には、キーワードの後に識別子がありますlet。これは、let 変数を、名前が指定された識別子で本体が let 形式の本体であるプロシージャの引数にバインドします。プロシージャを呼び出すことによって、本体を必要に応じて繰り返すことができます。名前付き let は、反復処理を実装するために広く使用されています。
例: シンプルなカウンター
( let loop (( n 1 )) ( if ( > n 10 ) ' () ( cons n ( loop ( + n 1 )))))
===> ( 1 2 3 4 5 6 7 8 9 10 )
Scheme のあらゆるプロシージャと同様に、名前付き let で作成されたプロシージャはファーストクラス オブジェクトです。
適切な末尾再帰
Scheme には反復構造 がありますdoが、反復 を表現するには末尾再帰を使用する方が Scheme ではより慣用的です。標準に準拠した Scheme 実装では、末尾呼び出しを最適化して、アクティブな末尾呼び出しの無制限の数をサポートすることが求められます (R5RS セクション 3.5) [4] —Scheme レポートでは適切な末尾再帰として説明されている特性— これによって Scheme プログラマは、より直感的になることもある再帰構造を使用して反復アルゴリズムを安全に記述できるようになります。末尾再帰プロシージャと名前付きフォームは、末尾再帰を使用した反復のサポートを提供します。
let
;; 0 から 9 までの正方形のリストを作成します:
;; 注: loop は、ラベルとして使用される任意のシンボルです。任意のシンボルを使用できます。
( define ( list-of-squares n ) ( let loop (( i n ) ( res ' ())) ( if ( < i 0 ) res ( loop ( - i 1 ) ( cons ( * i i ) res )))))
(正方形のリスト9 ) ===> ( 0 1 4 9 16 25 36 49 64 81 )
ファーストクラスの継続
Schemeにおける継続は第一級オブジェクトである。Schemeは、プログラマーが提供する手続き内の正式な引数にバインドされたエスケープ手続きとしてパックすることにより、現在の継続を捕捉する手続きcall-with-current-continuation(とも呼ばれる)を提供する。(R5RS 6.4節) [4]第一級継続により、プログラマーは反復子、コルーチン、バックトラックなどの非局所的な制御構造を作成できる。
call/cc
継続は、命令型プログラミング言語のreturn ステートメントの動作をエミュレートするために使用できます。次の関数はfind-first、関数funcとリストが指定されると、が true を返すようなのlst最初の要素を返します。
xlst(func x)
( define ( find-first func lst ) ( call-with-current-continuation ( lambda ( return-immediately ) ( for-each ( lambda ( x ) ( if ( func x ) ( return-immediately x ))) lst ) #f )))
(最初に整数を検索しますか? ' ( 1/2 3/4 5.6 7 8/9 10 11 )) ===> 7 (最初にゼロを検索しますか? ' ( 1 2 3 4 )) ===> #f
次の例は、従来のプログラマーのパズルですが、Scheme が継続をファーストクラス オブジェクトとして処理し、それを変数にバインドして、プロシージャに引数として渡すことができることを示しています。
( let* (( yin (( lambda ( cc ) ( display "@" ) cc ) ( call-with-current-continuation ( lambda ( c ) c )))) ( yang (( lambda ( cc ) ( display "*" ) cc ) ( call-with-current-continuation ( lambda ( c ) c ))))) ( yin yang ))
このコードを実行すると、カウントシーケンスが表示されます。@*@**@***@****@*****@******@*******@********...
プロシージャと変数の共有名前空間
Common Lispとは対照的に、Schemeではすべてのデータと手続きが共通の名前空間を共有しますが、Common Lispでは関数とデータが別々の名前空間を持つため、関数と変数に同じ名前を持つことができ、関数を値として参照するための特別な表記が必要になります。これは、Schemeの統一された名前空間とCommon Lispの別々の名前空間を指して、「Lisp-1対Lisp-2」の区別として知られていることもあります。[23]
Scheme では、データの操作とバインドに使用される同じプリミティブを使用して、プロシージャをバインドできます。Common Lisp のdefunおよび#'プリミティブに相当するものはありません。
;; 数値にバインドされた変数:
( define f 10 ) f ===> 10 ;; ミューテーション (バインドされた値の変更) ( set! f ( + f f 6 )) f ===> 26 ;; 同じ変数にプロシージャを割り当てる: ( set! f ( lambda ( n ) ( + n 12 ))) ( f 6 ) ===> 18 ;; 式の結果を同じ変数に割り当てる: ( set! f ( f 1 )) f ===> 13 ;; 関数型プログラミング: ( apply + ' ( 1 2 3 4 5 6 )) ===> 21 ( set! f ( lambda ( n ) ( + n 100 ))) ( map f ' ( 1 2 3 )) ===> ( 101 102 103 )
実装基準
このサブセクションでは、長年にわたって行われてきた設計上の決定について説明します。これらの決定は Scheme に特別な特徴を与えてきましたが、元の設計の直接的な結果ではありません。
数字の塔
Schemeは、複素数型や有理数型を含む比較的完全な数値データ型のセットを規定しており、これはSchemeでは数値タワーとして知られています(R5RS sec. 6.2 [4])。標準ではこれらを抽象化として扱い、実装者に特定の内部表現を強制しません。
数値には正確さという性質があります。正確な数値は、他の正確な数値を含む一連の正確な演算によってのみ生成できます。つまり、不正確さは伝染します。標準では、正確な数値を生成するすべての演算に対して、任意の 2 つの実装が同等の結果を生成する必要があることが規定されています。
R5RS 標準では、数値の正確さを変更するために使用できる手順exact->inexactとが指定されています。 は、「引数に数値的に最も近い正確な数値」を生成します。は、「引数に数値的に最も近い不正確な数値」を生成します。 R6RS 標準では、これらの手順をメイン レポートから省略していますが、標準ライブラリ (rnrs r5rs (6)) で R5RS 互換手順として指定しています。
inexact->exactinexact->exactexact->inexact
R5RS 標準では、Scheme 実装は数値タワー全体を実装する必要はありませんが、「実装の目的と Scheme 言語の精神の両方に一致する一貫したサブセット」を実装する必要があります (R5RS セクション 6.2.3)。[4] 新しい R6RS 標準では、タワー全体の実装と、「実質的に無制限のサイズと精度の正確な整数オブジェクトと正確な有理数オブジェクト、および特定の手順の実装が要求されます...正確な引数が与えられたときに常に正確な結果を返すようにするため」です (R6RS セクション 3.4、セクション 11.7.1)。[6]
例 1: 正確な有理複素数をサポートする実装における正確な算術演算。
;; 3 つの有理数実数と 2 つの有理数複素数の合計
( define x ( + 1/3 1/4 -1/5 -1/3i 405/50+2/3i )) x ===> 509/60+1/3i ;; 正確性をチェックします。( exact? x ) ===> #t
例 2: 正確な有理数も複素数もサポートしていないが、有理数表記の実数を受け入れる実装での同じ演算。
;; 4 つの有理実数の合計
( xr ( + 1/3 1/4 -1/5 405/50 )を定義) ;; 2 つの有理実数の合計( xi ( + -1/3 2/3 )を定義) xr ===> 8.48333333333333 xi ===> 0.333333333333333 ;; 正確性をチェックします。( exact? xr ) ===> #f ( exact? xi ) ===> #f
どちらの実装も R5RS 標準に準拠していますが、2 番目の実装は完全な数値タワーを実装していないため、R6RS に準拠していません。
遅延評価
delayScheme は、フォームと手順を通じて遅延評価をサポートしますforce。
( define a 10 ) ( define eval-aplus2 ( delay ( + a 2 ))) ( set! a 20 ) ( force eval-aplus2 ) ===> 22 ( define eval-aplus50 ( delay ( + a 50 ))) ( let (( a 8 )) ( force eval-aplus50 )) ===> 70 ( set! a 100 ) ( force eval-aplus2 ) ===> 22
プロミスの元の定義の語彙コンテキストは保持され、その値も の最初の使用後に保持されますforce。プロミスは 1 回だけ評価されます。
これらのプリミティブは、プロミスと呼ばれる値を生成または処理し、ストリームなどの高度な遅延評価構造を実装するために使用できます。[24]
R6RS標準では、これらはもはやプリミティブではなく、代わりにR5RS互換性ライブラリ(rnrs r5rs(6))の一部として提供されます。
delayR5RSでは、との推奨実装が与えられており、引数のない手続き(サンクforce)としてプロミスを実装し、が呼び出される回数に関係なく、メモ化を使用して1回だけ評価されることを保証します(R5RS sec. 6.4)。[4]force
SRFI 41は、有限数列と無限数列の両方を非常に経済的に表現することを可能にする。例えば、これはSRFI 41で定義された関数を使ったフィボナッチ数列の定義である: [24]
;; フィボナッチ数列を定義します:
( define fibs ( stream-cons 0 ( stream-cons 1 ( stream-map + fibs ( stream-cdr fibs ))))) ;; 数列の 100 番目の数を計算します: ( stream-ref fibs 99 ) ===> 218922995834555169026
手続き引数の評価順序
ほとんどの Lisp では、プロシージャ引数の評価順序が指定されています。Scheme では指定されていません。評価順序 (演算子位置の式の評価順序を含む) は、呼び出しごとに実装によって選択できます。唯一の制約は、「演算子とオペランド式の同時評価の結果は、評価の順序と一致するように制約される」ことです (R5RS セクション 4.1.3) [4]
( let (( ev ( lambda ( n ) ( display "評価中 " ) ( display ( if ( procedure? n ) "手続き" n )) (改行) n ))) (( ev + ) ( ev 1 ) ( ev 2 ))) ===> 3
評価1
評価2
評価手順
ev は、渡された引数を記述し、その引数の値を返すプロシージャです。他の Lisp とは対照的に、Scheme 式の演算子位置 (最初の項目) に式を出現させることは、演算子位置の式の結果がプロシージャである限り、まったく問題ありません。
1 と 2 を加算する手順 " + " を呼び出す場合、式(ev +)、(ev 1)、(ev 2)は、並列に評価されたかのようにならない限り、任意の順序で評価できます。したがって、上記のサンプル コードを実行すると、標準 Scheme によって次の 3 行が任意の順序で表示されますが、1 行のテキストを別の行と交互に配置することはできません。これは、順次評価の制約に違反するためです。
衛生的なマクロ
R5RS 標準およびその後のレポートでは、マクロ システムを使用して Scheme の構文を簡単に拡張できます。R5RS 標準では、強力な hygienic マクロ システムが導入され、プログラマーは単純なパターン マッチングサブ言語を使用して言語に新しい構文構造を追加できるようになりました (R5RS セクション 4.3)。[4] これ以前は、hygienic マクロ システムは R4RS 標準の付録に格下げされ、"高レベル" システムと "低レベル" マクロ システムの両方が Scheme の拡張機能として扱われ、言語の必須部分ではありませんでした。[25]
とも呼ばれる衛生的なマクロ システムの実装では、syntax-rules言語の残りの部分の語彙スコープを尊重する必要があります。これは、マクロ拡張の特別な命名規則とスコープ規則によって保証され、他のプログラミング言語のマクロ システムで発生する可能性のある一般的なプログラミング エラーを回避します。R6RS は、より洗練された変換システム を指定します。syntax-caseこれは、以前から R5RS Scheme の言語拡張として利用可能でした。
;; 複数の式を持つ
true ブランチと false ブランチのない "if" のバリアントを実装するマクロを定義します。
( define-syntax when ( syntax-rules () (( when pred exp exps ... ) ( if pred ( begin exp exps ... )))))
マクロとプロシージャの呼び出しはよく似ていますが (どちらも S 式です)、扱いが異なります。コンパイラは、プログラム内で S 式を検出すると、まず、現在のレキシカル スコープ内でシンボルが構文キーワードとして定義されているかどうかを確認します。定義されている場合は、マクロの展開を試行し、S 式の末尾にある項目を引数として扱います (評価するコードはコンパイルしません)。このプロセスは、マクロ呼び出しがなくなるまで再帰的に繰り返されます。構文キーワードでない場合は、コンパイラは S 式の末尾にある引数を評価するコードをコンパイルし、次に S 式の先頭にあるシンボルで表される変数を評価して、評価された末尾の式を引数として渡してプロシージャとして呼び出します。
ほとんどの Scheme 実装では、追加のマクロ システムも提供されています。人気のあるものには、構文クロージャ、明示的な名前変更マクロ、およびCommon Lispで提供されるシステムdefine-macroに類似した非衛生的なマクロ システムがあります。
defmacro
マクロが衛生的であるかどうかを指定できないことは、マクロシステムの欠点の1つです。スコープセットなどの拡張の代替モデルは潜在的な解決策を提供します。[26]
環境と評価
R5RS 以前は、Scheme にはeval他の Lisp で広く使用されている 手続きに相当する標準的なものはなかったが、最初の Lambda 論文では がevaluate「LISP 関数 EVAL に似ている」と説明されており[18]、1978 年の最初の改訂レポートではこれencloseが 2 つの引数を取る に置き換えられた。2 回目、3 回目、4 回目の改訂レポートでは に相当するものはすべて削除されたeval。
この混乱の原因は、Schemeのレキシカルスコープでは、式の評価結果がどこで評価されるかによって異なることです。たとえば、次の式を評価した結果が5になるのか6になるのかは明らかではありません。[27]
( let (( name '+ )) ( let (( + * )) (評価(リストname 2 3 ))))
が定義されている外部環境で評価された場合name、結果はオペランドの合計になります。シンボル「+」がプロシージャ「*」の値にバインドされている内部環境で評価された場合、結果は 2 つのオペランドの積になります。
evalR5RS は、環境を返す 3 つの手続きを指定し、 S 式と環境を受け取り、提供された環境で式を評価する手続きを提供することで、この混乱を解決します。 (R5RS セクション 6.5) [4] R6RS は、プログラマが評価環境にインポートするオブジェクトを正確に指定できる手続きを提供することでこれを拡張しますenvironment。
evaluate最新のスキーム (通常は R5RS と互換性があります) を使用してこの式を評価するには、次のような
関数を定義する必要があります。
(定義(式を評価する) (式を評価する(相互作用環境)))
interaction-environment通訳者のグローバル環境です。
ブール式における非ブール値の扱い
Common Lispを含むほとんどのLisp方言では、慣例により、NILブール式では の値はfalseと評価されます。Schemeでは、1991年のIEEE標準以来、[3] を除くすべての値(Schemeで と表記される の同等値#fを含む)は、ブール式ではtrueと評価されます。(R5RS 6.3.1節)[4]NIL'()
ほとんどの Lisp ではtrue のブール値を表す定数は ですがT、Scheme では です#t。
プリミティブデータ型の非重複性
Schemeでは、プリミティブデータ型は互いに独立している。Schemeオブジェクトに対して真となり得る述語はboolean?、pair?、symbol?、number?、char?、string?、vector?、port?、 のうち1つだけであるprocedure?。(R5RS sec 3.2) [4]
対照的に、数値データ型では、数値は重複する。例えば、整数値はinteger?、、、、および述語rational?のすべてを同時に満たす。(R5RS sec 6.2)[4]real?complex?number?
同値述語
Scheme には、3 つの異なる同値述語、等価性をテストするための関係演算子eq?、、eqv?およびによって表される、任意のオブジェクト間の 3 つの異なる同値タイプがありますequal?。
eq?#fパラメータがメモリ内の同じデータ オブジェクトを表していない限り、評価されます。eqv?は、一般的に と同じですがeq?、プリミティブ オブジェクト (文字や数字など) を特別に扱うため、同じ値を表す数字は、eqv?同じオブジェクトを参照していなくても同じになります。equal?リスト、ベクトル、文字列などのデータ構造を比較し、それらの構造とeqv?内容が一致するかどうかを判断します。(R5RS sec. 6.1) [4]
Schemeには型依存の等価演算も存在する。2つの文字列を比較string=?しstring-ci=?(後者は大文字と小文字を区別しない比較を行う)、char=?文字char-ci=?を比較し、=数値を比較する。[4]
コメント
R5RS 標準まで、Scheme の標準コメントはセミコロンであり、これにより行の残りの部分は Scheme から見えなくなります。多数の実装では、コメントを 1 行以上に拡張できる代替規則がサポートされており、R6RS 標準ではそのうちの 2 つが許可されています。S 式全体をコメント (または「コメント アウト」) にするには、その前に を置きます#;(SRFI 62 [28]#|で導入)。また、テキストを と で囲むと、複数行コメントまたは「ブロック コメント」を作成できます|#。
入力/出力
Scheme の入力と出力はportデータ型に基づいています。(R5RS セクション 6.6) [4] R5RS は、手続きcurrent-input-portとでアクセスできる 2 つのデフォルト ポートを定義しています。これらは、Unix の標準入力 と標準出力current-output-portの概念に対応しています。ほとんどの実装では も提供されています。入力と標準出力のリダイレクトは、やなどの標準手続きによって標準でサポートされています。ほとんどの実装では、同様のリダイレクト機能を備えた文字列ポートが提供されており、SRFI 6 で説明されている手続きを使用して、多くの通常の入出力操作をファイルではなく文字列バッファに対して実行できます。[29] R6RS 標準では、より洗練され、より高機能なポート手続きと、多くの新しいタイプのポートが指定されています。
current-error-portwith-input-from-filewith-output-to-file
以下の例は厳密な R5RS Scheme で記述されています。
例 1: 出力を (現在の出力ポート) にデフォルト設定する場合:
( let (( hello0 ( lambda () ( "Hello world"を表示) (改行)))) ( hello0 ))
例2: 例1と同様だが、出力手順にオプションのポート引数を使用する
( let (( hello1 ( lambda ( p ) ( "Hello world"を表示p ) (改行p )))) ( hello1 (現在の出力ポート)))
例3: 例1と同じですが、出力は新しく作成されたファイルにリダイレクトされます
;; 注意: with-output-to-file は R5RS ではオプションの手続きです
( let (( hello0 ( lambda () ( display "Hello world" ) ( newline )))) ( with-output-to-file "helloworldoutputfile" hello0 ))
例4: 例2と同様ですが、明示的にファイルを開き、ポートを閉じて出力をファイルに送信する
( let (( hello1 ( lambda ( p ) ( "Hello world" pを表示) (改行p ))) (出力ポート( "helloworldoutputfile"出力ファイルを開く))) ( hello1出力ポート) (出力ポートを閉じる出力ポート))
例 5: 例 2 と同じですが、call-with-output-file を使用して出力をファイルに送信します。
( let (( hello1 ( lambda ( p ) ( "Hello world" pを表示) (改行p )))) (出力ファイル"helloworldoutputfile" hello1で呼び出します))
入力にも同様の手続きが用意されています。R5RS Scheme では述語input-port?と が用意されています。output-port?文字の入力と出力には、、、write-charおよびread-charがpeek-char用意char-ready?されています。Scheme 式の書き込みと読み取りには、Scheme ではreadと が用意されwriteています。読み取り操作では、入力ポートがファイルの末尾に到達した場合、返される結果はファイル末尾オブジェクトであり、これは述語 を使用してテストできますeof-object?。
SRFI 28では、標準規格とともに、Common Lispのformat関数に似た基本的なフォーマット手順も定義されており、その関数の名前の由来となっている。[30]
標準手順の再定義
Scheme では、手続きは変数にバインドされます。R5RS では、言語標準により、プログラムが組み込み手続きの変数バインディングを変更し、実質的にそれらを再定義できることが正式に義務付けられました。(R5RS「言語の変更」) [4] たとえば、は、+再定義することで、数値だけでなく文字列も受け入れるように拡張できます。
( set! + ( let (( original+ + )) ( lambda args ( apply ( if ( or ( null? args ) ( string? ( car args ))) string-append original+ ) args )))) ( + 1 2 3 ) ===> 6 ( + "1" "2" "3" ) ===> "123"
R6RSでは、標準のバインディングも含め、すべてのバインディングは何らかのライブラリに属しており、エクスポートされたバインディングはすべて不変です。(R6RS 7.1節) [6] このため、標準のプロシージャをミューテーションで再定義することは禁止されています。代わりに、標準のプロシージャの名前で別のプロシージャをインポートすることは可能であり、これは実質的に再定義に似ています。
命名法と命名規則
標準 Scheme では、あるデータ型から別のデータ型に変換するプロシージャの名前には文字列「->」が含まれ、述語は「?」で終わり、すでに割り当てられているデータの値を変更するプロシージャは「!」で終わります。これらの規則は、Scheme プログラマーによってよく使用されます。
Scheme 標準などの正式なコンテキストでは、ラムダ式またはプリミティブ プロシージャを指す場合、「関数」ではなく「プロシージャ」という単語が使用されます。通常の使用では、「プロシージャ」と「関数」という単語は同じ意味で使用されます。プロシージャの適用は、正式には組み合わせと呼ばれることもあります。
他の Lisp と同様に、Scheme では「thunk」という用語は引数のないプロシージャを指すために使用されます。「適切な末尾再帰」という用語は、すべての Scheme 実装の特性を指し、末尾呼び出しの最適化を実行して、不特定多数のアクティブな末尾呼び出しをサポートします。
R3RS以降の標準文書のタイトルの形式「アルゴリズム言語スキームに関する改訂レポート」は、ALGOL 60標準文書のタイトル「アルゴリズム言語Algol 60に関する改訂レポート」を参照したものです。R3RSの概要ページは、ALGOL 60レポートの概要ページを忠実にモデル化しています。[31] [32]
標準フォームと手順の見直し
この言語は、標準R5RS(1998)[4]およびR6RS(2007)[6]で正式に定義されています。 これらの標準では、言語の制御構造を提供するキーワードとそれに付随する構文、および一般的なタスクを実行する標準手順などの標準的な「形式」が記述されています。
標準フォーム
この表は、Scheme の標準フォームについて説明しています。一部のフォームは、言語内で単一の関数に簡単に分類できないため、複数の行に表示されます。
この表で「L」とマークされているフォームは、標準では派生した「ライブラリ」フォームとして分類されており、実際にはより基本的なフォームを使用してマクロとして実装されることが多く、他の言語よりも実装のタスクがはるかに簡単になります。
beginR5RS ではライブラリ構文として定義されています
が、スプライシング機能を実現するには、展開側がこれを認識している必要があります。R6RS では、これはライブラリ構文ではなくなりました。
標準手順
次の 2 つの表は、R5RS スキームの標準手順を説明しています。R6RS ははるかに広範囲にわたるため、このタイプの概要は実用的ではありません。
一部の手順は、言語内で単一の関数に簡単に分類できないため、複数の行に表示されます。
名前に「-ci」が含まれる文字列および文字プロシージャは、引数間で大文字と小文字を区別しない比較を実行します。つまり、同じ文字の大文字と小文字は等しいとみなされます。
2 つ以上の引数を取る - および / の実装は定義されていますが、R5RS ではオプションのままになっています。
制度実施要請
Scheme はミニマリズムであるため、多くの共通手順と構文形式は標準では定義されていません。コア言語を小さく保ちながら拡張機能の標準化を促進するために、Scheme コミュニティには「Scheme Request for Implementation」(SRFI) プロセスがあり、このプロセスでは拡張機能の提案を慎重に議論して拡張ライブラリが定義されます。これにより、コードの移植性が促進されます。多くの SRFI は、すべてまたはほとんどの Scheme 実装でサポートされています。
さまざまな実装でかなり広くサポートされているSRFIには次のものがある: [33]
- 0: 特徴ベースの条件付き拡張構造
- 1: ライブラリの一覧
- 4: 同種の数値ベクトルデータ型
- 6: 基本的な文字列ポート
- 8: 受信、複数の値へのバインド
- 9: レコードタイプの定義
- 13: 文字列ライブラリ
- 14: 文字セットライブラリ
- 16: 可変引数の手続きの構文
- 17: 一般化されたセット!
- 18: マルチスレッドのサポート
- 19: 時間データ型と手順
- 25: 多次元配列プリミティブ
- 26:カリー化せずにパラメータを特殊化するための表記法
- 27: ランダムビットのソース
- 28: 基本的な書式文字列
- 29:ローカリゼーション
- 30: ネストされた複数行コメント
- 31: 再帰評価のための特別な形式
- 37: args-fold: プログラム引数プロセッサ
- 39: パラメータオブジェクト
- 41:ストリーム
- 42:熱心な理解
- 43: ベクターライブラリ
- 45: 反復遅延アルゴリズムを表現するためのプリミティブ
- 60: 整数をビットとして
- 61: より一般的なcond節
- 66: オクテットベクトル
- 67: 手順を比較する
実装
Scheme は、その洗練されたミニマリストな設計により、言語設計者、愛好家、教育者の間で人気があり、また、典型的なインタープリタと同じくらい小さいサイズであることから、組み込みシステムやスクリプトでも人気のある選択肢となっています。このため、数多くの実装が生まれましたが、[34]そのほとんどが互いに大きく異なっているため、ある実装から別の実装にプログラムを移植することは非常に困難です。また、標準言語のサイズが小さいため、標準的で移植性の高い Scheme で非常に複雑な有用なプログラムを書くことはほぼ不可能です。[14] R6RS 標準では、プログラマーへのアピールを広げるために、はるかに幅広い言語が指定されています。
ほぼすべての実装では、開発とデバッグのために、従来の Lisp スタイルの読み取り、評価、印刷のループが提供されています。また、多くの実装では、Scheme プログラムを実行可能なバイナリにコンパイルしています。他の言語で記述されたプログラムに Scheme コードを埋め込むサポートも一般的です。これは、Scheme 実装が比較的単純なため、Cなどの言語で開発された大規模なシステムにスクリプト機能を追加する場合によく使用されるためです。Gambit 、Chicken、Biglooの Scheme インタープリタは、Scheme を C にコンパイルするため、埋め込みがはるかに簡単になります。さらに、 Biglooのコンパイラは、 Java 仮想マシン(JVM)用のバイトコードを生成するように構成でき、 .NET用の実験的なバイトコード ジェネレーターがあります。
一部の実装では、追加機能がサポートされています。たとえば、KawaとJScheme はJavaクラスとの統合を提供し、Scheme から C へのコンパイラでは、C で記述された外部ライブラリの使用が容易になり、Scheme ソース コードに C コードを埋め込むことまで可能になります。もう 1 つの例は Pvts で、Scheme の学習をサポートするビジュアル ツール セットを提供します。
使用法
Scheme は多くの[35]学校で広く使用されており、特に、いくつかの入門コンピュータサイエンスのコースでは、教科書Structure and Interpretation of Computer Programs (SICP) と併せて Scheme を使用しています。[36]過去 12 年間、PLT はProgramByDesign (旧 TeachScheme!) プロジェクトを運営し、600 人近くの高校教師と何千人もの高校生に初歩的な Scheme プログラミングを教えてきました。MITの古い入門プログラミング クラス 6.001 は Scheme で教えられていました。[37] 6.001 はより現代的なコースに置き換えられましたが、SICP は引き続き MIT で教えられています。[38]同様に、カリフォルニア大学バークレー校の入門クラスCS 61A は、動的スコープを示すためにLogoに少し変更した以外は、2011 年まで完全に Scheme で教えられていました。現在、MITと同様に、バークレー校もシラバスをより現代的なバージョンに置き換え、主にPython 3で教えていますが、現在のシラバスは依然として古いカリキュラムに基づいており、授業の一部は依然としてSchemeで教えられています。[39]
現在ノースイースタン大学で使用されているマティアス・フェライセンの教科書『How to Design Programs』は、いくつかの高等教育機関のコンピュータサイエンス入門コースで使用されています。ノースイースタン大学とウースター工科大学は、それぞれ入門コースのコンピュータサイエンスの基礎 (CS2500) とプログラム設計入門 (CS1101) で Scheme のみを使用しています。[ 40] [41] ローズハルマンは、より高度なプログラミング言語の概念コースで Scheme を使用しています。[42] ブランダイス大学のコアコースであるコンピュータプログラムの構造と解釈 (COSI121b) も、理論計算機科学者のハリー・メアソンによって Scheme のみで教えられています。 [43] インディアナ大学の入門クラス C211 は、完全に Scheme で教えられています。[44]イェール大学とグリネル大学のコンピュータサイエンス入門コースもSchemeで教えられています。[45]ノースイースタン大学のコンピュータサイエンス大学院生の必修コースであるプログラミング設計パラダイム[46]もSchemeを多用しています。ミネソタ大学ツインシティ校の以前のコンピュータサイエンス入門コースであるCSCI 1901でもSchemeを主要言語として使用し、その後にJava言語を紹介するコースが続きました。[47]しかし、MITの例に倣って、学部は1901をPythonベースのCSCI 1133に置き換えました。[48]一方、関数型プログラミングは3学期のコースCSCI 2041で詳細に取り上げられています。[49]
このスキームは、次の目的にも使用されます。
- SGMLスタイルシートを指定する方法を提供する文書スタイルセマンティクスおよび仕様言語(DSSSL)は、Schemeのサブセットを使用しています。[50]
- よく知られているオープンソースの ラスターグラフィックエディタ GIMPは、スクリプト言語としてTinySchemeを使用しています。[51]
- GuileはGNUプロジェクトによって公式スクリプト言語として採用されており、Schemeの実装はGNU LilyPondやGnuCashなどのアプリケーションに拡張機能のスクリプト言語として組み込まれています。同様に、Guileはかつてデスクトップ環境 GNOMEのスクリプト言語でした。[52]また、GNOMEには今でもライブラリスタックにGuileバインディングを提供するプロジェクトがあります。[53] GNUの主力プログラムであるGNU EmacsにGuileを組み込み、現在のEmacs Lispインタープリタを置き換えるプロジェクトがあります。[要出典]
- Elk Schemeは、SynopsysのテクノロジーCAD(TCAD)ツールのスクリプト言語として使用されています。[54]
- 映画『ファイナルファンタジーXIV 黄金の風』のシニアプログラマーである河合史朗は、リアルタイムレンダリングエンジンを管理するためのスクリプト言語としてSchemeを使用しました。[55]
- Google App Inventor for AndroidはSchemeを使用しており、KawaはSchemeコードをAndroidデバイス上で動作するJava仮想マシンのバイトコードにコンパイルするために使用されます。[56]
参照
- プログラミング言語の基礎、Scheme を基礎として使った教科書
参考文献
- ^ 「影響 - The Rust Reference」。The Rust Reference 。 2023年4月18日閲覧。
- ^ Common LISP: The Language、第 2 版、Guy L. Steele Jr. Digital Press、1981 年。ISBN 978-1-55558-041-4。「Common Lisp は Lisp の新しい方言であり、MacLisp の後継であり、ZetaLisp の影響を強く受け、ある程度は Scheme と InterLisp の影響も受けています。」
- ^ ab 1178-1990 (Reaff 2008) Scheme プログラミング言語の IEEE 標準。IEEE 部品番号 STDPD14209、2008 年 3 月 26 日の IEEE-SA 標準委員会標準レビュー委員会 (RevCom) の会議で満場一致で再確認 (議事録の項目 6.3)、再確認議事録は 2009 年 10 月にアクセス。このドキュメントは IEEE からのみ購入可能で、執筆時点 (2009 年) ではオンラインでは入手できません。
- ^ abcdefghijklmnopqr Richard Kelsey、William Clinger、Jonathan Rees、他 (1998 年 8 月)。「アルゴリズム言語スキームに関する改訂レポート」。 高階および記号計算。11 (1): 7–105。doi : 10.1023 /A:1010051815785。S2CID 14069423。2012年 8 月 9 日に閲覧。
- ^ ab "R7RS final が利用可能" (PDF) . 2013-07-06.
- ^ abcde Sperber, Michael; Dybvig, R. Kent; Flatt, Matthew; Van Straaten, Anton; et al. (2007 年 8 月). 「Revised6 Report on the Algorithmic Language Scheme (R6RS)」. Scheme Steering Committee . 2011 年 9 月 13 日閲覧。
- ^ abcd Sussman, Gerald Jay; Steele, Guy L. (1998 年 12 月 1 日). 「Scheme に関する最初のレポートの再検討」.高階および記号計算. 11 (4): 399–404. doi :10.1023/A:1010079421970. S2CID 7704398.
- ^ 「R6RS 実装」. r6rs.org . 2017 年 11 月 24 日閲覧。
- ^ Abdulaziz Ghuloum (2007-10-27). 「R6RS ライブラリと構文ケース システム (psyntax)」 Ikarus Scheme . 2009-10-20閲覧。
- ^ Keep, Andrew W.; Dybvig, R. Kent (2014 年 11 月). 「Scheme レコード型の実行時表現」. Journal of Functional Programming . 24 (6): 675–716. doi : 10.1017/S0956796814000203 . S2CID 40001845.
- ^ 「アルゴリズム言語スキームに関する改訂版^6レポート、付録E: 言語の変更」。スキーム運営委員会。2007年9月26日。 2009年10月20日閲覧。
- ^ 「R6RS Electorate」。Scheme Steering Committee。2007年。 2012年8月9日閲覧。
- ^ Marc Feeley (編集) (2007-10-26). 「R6RS に関する実装者の意図」 Scheme 運営委員会、r6rs-discuss メーリング リスト。2012-08-09に取得。
- ^ ab Will Clinger、Marc Feeley、Chris Hanson、Jonathan Rees、Olin Shivers (2009-08-20)。「Position Statement (draft)」。Scheme Steering Committee。2012-08-09に閲覧。
{{cite web}}: CS1 maint: 複数の名前: 著者リスト (リンク) - ^ 「R7RS 9th draft available」(PDF) . 2013-04-15.
- ^ Will Clinger (2013-05-10). 「投票期間の延長」。Scheme Language Steering Committee、scheme-reports メーリング リスト。2013-07-21 時点のオリジナルからアーカイブ。2013-07-07に取得。
- ^ Scheme 48実装は、インタープリタが Richard Kelsey と Jonathan Rees によって 48 時間 (1986 年 8 月 6 日 - 7 日) で作成されたため、このように呼ばれています。Richard Kelsey、Jonathan Rees、Mike Sperber (2008-01-10) を参照してください。「リリース 1.8 の不完全な Scheme 48 リファレンス マニュアル」。Jonathan Rees、s48.org。2012-08-09に取得。
- ^ ab Gerald Jay Sussman & Guy Lewis Steele Jr. (1975年12月). 「Scheme: 拡張ラムダ計算のインタープリター」(PDF) . AI Memos . AIM-349. MIT AI Lab . hdl :1721.1/5794 . 2021年12月23日閲覧。
- ^ Joel Moses (1970 年 6 月)、LISP における FUNCTION の機能、または FUNARG 問題を環境問題と呼ぶべき理由、hdl :1721.1/5854、AI Memo 199、
LISP における FUNCTION と QUOTE の違いを表す便利な比喩は、QUOTE を関数の多孔質または開いた覆いと考えることです。これは、自由変数が現在の環境に逃げ込むためです。FUNCTION は、閉じた、または非多孔質の覆いとして機能します (Landin が「閉包」という用語を使用したのはそのためです)。したがって、私たちは「開いた」ラムダ式 (LISP の関数は通常ラムダ式です) と「閉じた」ラムダ式について話します。[...] 環境問題に対する私の関心は、この問題を深く理解していた Landin が 1966 年から 1967 年にかけて MIT を訪問したときに始まりました。その後、
LISP
の「閉じた」ラムダ式の評価結果である FUNARG リスト
と
ISWIM
のラムダ クロージャ間の対応に気付きました。
- ^ van Tonder, André (2004 年 1 月 1 日). 「量子計算のためのラムダ計算」. SIAM Journal on Computing . 33 (5): 1109–1135. arXiv : quant-ph/0307150 . doi :10.1137/S0097539703432165. S2CID 613571.
- ^ Niehren, J.; Schwinghammer, J.; Smolka, G. (2006 年 11 月). 「Futures を備えた並行ラムダ計算」(PDF) .理論計算機科学. 364 (3): 338–356. doi :10.1016/j.tcs.2006.08.016.
- ^ Gerald Jay Sussman & Guy Lewis Steele Jr. (1976 年 3 月)。「Lambda: The Ultimate Imperative」。AI Memos。AIM-353。MIT AI Lab。2016年 5 月 10 日時点のオリジナル(postscript または PDF)からアーカイブ。2012 年 8 月 9 日閲覧。
- ^ Gabriel, Richard P. ; Pitman, Kent (1988). 「関数セルと値セルの分離に関する技術的問題」. LISP およびシンボリック計算. 第 1 巻、第 1 号 (1988 年 6 月発行)。pp. 81–101. doi :10.1007/BF01806178 . 2012 年 8 月 9 日閲覧。
- ^ ab Philip L. Bewig (2008-01-24). 「SRFI 41: ストリーム」. The SRFI Editors, schemers.org . 2012-08-09に取得。
- ^ William ClingerとJonathan Rees編 (1991)。「アルゴリズム言語スキームの改訂版レポート」。ACM Lispポインタ。4 (3): 1–55 。 2012年8月9日閲覧。
- ^ Flatt, Matthew (2016). 「スコープのセットとしてのバインディング」。プログラミング言語の原則に関する第 43 回 ACM SIGPLAN-SIGACT シンポジウムの議事録。pp . 705–717。doi :10.1145 / 2837614.2837620。ISBN 978-1-4503-3549-2.S2CID 15401805 。
- ^ ジョナサン・リース、「The Scheme of Things The June 1992 Meeting」、Wayback Machineに 2011-07-16 にアーカイブ(追記)、Lisp Pointers、V(4)、1992 年 10 月~12 月。2012-08-09 に取得
- ^ Taylor Campbell (2005-07-21). 「SRFI 62: S 式コメント」. The SRFI Editors, schemers.org . 2012-08-09に閲覧。
- ^ William D Clinger (1999-07-01). 「SRFI 6: 基本的な文字列ポート」. SRFI エディター、schemers.org 。2012-08-09に取得。
- ^ Scott G. Miller (2002-06-25). 「SRFI 28: 基本的な書式指定文字列」. The SRFI Editors, schemers.org . 2012-08-09に取得。
- ^ JW Backus、FL Bauer、J.Green、C. Katz、J. McCarthy P. Naur、他 (1960 年 1 月 - 4 月)。「アルゴリズム言語 Algol 60 の改訂レポート」。Numerische Mathematik、Communications of the ACM、Journal of the British Computer Society。2012年 8 月 9 日閲覧。
- ^ Jonathan Rees、William Clinger編 (1986年12月)。「アルゴリズム言語スキームに関する改訂版(3)報告書(ALGOL 60の記念に捧げる)」。ACM SIGPLAN Notices。21 ( 12):37–79。CiteSeerX 10.1.1.29.3015。doi : 10.1145 /15042.15043。hdl : 1721.1/6424。S2CID 43884422。2012年8月9 日閲覧。
- ^ 「SRFI をサポートする Scheme システム」。SRFI エディター、schemers.org。2009 年 8 月 30 日。2012年 8 月 9 日に取得。
- ^ Scheme の既知の実装 75 件が「scheme-faq-standards」にリストされています。コミュニティ Scheme Wiki。2009 年 6 月 25 日。2009年 10 月 20 日に取得。
- ^ Ed Martin (2009-07-20). 「Scheme を使用している学校のリスト」 Schemers Inc. 2009-10-20閲覧。
- ^ 「SICP を使用している学校のリスト」。MIT プレス。1999 年 1 月 26 日。2009年 10 月 20 日閲覧。
- ^ Eric Grimson (2005 年春)。「6.001 コンピュータ プログラムの構造と解釈」。MIT オープン コースウェア。2009年 10 月 20 日閲覧。
- ^ アレックス・ヴァンディバー;ネルソン・エルヘイジ;他。 (2009 年 1 月)。 「6.184 - ゾンビはカフェイン入りの飲み物を飲む 6.001」。 MIT CSAIL 。2009 年 10 月 20 日に取得。
- ^ John DeNero (2019年秋)。「Computer Science 61A, Berkeley」。バークレー校電気工学・コンピュータサイエンス学科。 2019年12月17日閲覧。
- ^ CS 2500: コンピュータサイエンスの基礎 I、ノースイースタン大学
- ^ CS 1101: プログラム設計入門 (A05): コースソフトウェア、ウースター工科大学
- ^ 「CSSE 304: プログラミング言語の概念」。ローズハルマン工科大学。
- ^ 「2021年春学期 CS121b シラバス」(PDF)。ブランダイス大学。
- ^ 「ホーム」. berkeley-cs61as.github.io .
- ^ Dana Angluin (2009 年秋)。「コンピュータサイエンス入門 (CPSC 201)」。The Zoo、イェール大学コンピュータサイエンス学部。2009年 10 月 20 日閲覧。
- ^ 「プログラミング設計パラダイム CSG107 コースの読み物」。ノースイースタン大学コンピューター情報科学学部。2009 年秋。2012 年 8 月 9 日閲覧。
- ^ Structure of Computer Programming I Archived 2010-06-19 at the Wayback Machine、コンピュータサイエンス学部、ミネソタ大学、2010年春(2010年1月30日アクセス)。
- ^ CSci 必修科目のコース説明とその他の情報 2019-10-25 に Wayback Machineにアーカイブ、ミネソタ大学コンピューターサイエンス学部 (2019-10-25 アクセス)
- ^ CSCI 2041—ミネソタ大学新コースCSEカリキュラム委員会(2019年10月25日アクセス)
- ^ Robin Cover (2002-02-25). 「DSSSL - 文書スタイルセマンティクスおよび仕様言語。ISO/IEC 10179:1996」。表紙ページ。2012-08-09閲覧。
- ^ 「現在 GIMP に付属している主要なスクリプト言語は Scheme です。」 Dov Grobgeld (2002) より。「GIMP 基本 Scheme チュートリアル」。GIMP チーム。2012年 8 月 9 日閲覧。
- ^ Todd Graham Lewis、David Zoll、Julian Missig (2002)。「GNOME FAQ from Internet Archive」。The Gnome Team、gnome.org。2000 年 5 月 22 日時点のオリジナルよりアーカイブ。2012年 8 月 9 日閲覧。
- ^ "guile-gnome". フリーソフトウェア財団. 2012年8月9日閲覧。
- ^ Laurence Brevard (2006-11-09). 「Synopsys MAP-inSM プログラム アップデート: EDA 相互運用性開発者フォーラム」(PDF) . Synopsis Inc . 2012-08-09に閲覧。
- ^ Kawai, Shiro (2002 年 10 月)。「Gluing Things Together - リアルタイム CG コンテンツ制作における Scheme」。第 1 回国際 Lisp カンファレンスの議事録、サンフランシスコ: 342–348。2012年 8 月 9 日閲覧。
- ^ Bill Magnuson、Hal Abelson、Mark Friedman (2009-08-11)。「Android 向け App Inventor の内部」。Google Inc、公式 Google Research ブログ。2012-08-09に閲覧。
さらに読む
- Scheme とその実装の紹介 (ミラー)
- Christopher T. Haynes (1999-06-22)。「Scheme プログラミング言語標準化の経験」。
- Guy L. Steele Jr.、Richard P. Gabriel。「Lisp の進化」(PDF) 。2016 年 6 月 11 日のオリジナル(PDF)からアーカイブ。
- Gerald Jay SussmanおよびGuy Lewis Steele Jr. ( 1975 年 12 月)。Scheme 。第 349 巻 AI メモ。MIT 人工知能研究所。CiteSeerX 10.1.1.128.80 – Wikisource経由。
外部リンク
- Curlieの計画
- scheme.orgは、仕様を含む多くのSchemeリソースへのリンクを提供しています。
Wikibooks の Scheme プログラミング- Scheme の紹介
Wikibooks で 48 時間で Scheme を書く
ウィキメディア・コモンズの Scheme (プログラミング言語) に関連するメディア- スキームウィークリー
- あらゆるウェブサイトにインタラクティブ Scheme REPL を追加するブックマークレット
