Scheme はとんでもなく単純な言語である.この言語は数種類の基本的な 概念を実現していて,それらを興味深く強力な方法で組み合わせることに よって複雑なシステムを作り上げることができる.
これは,Schemeインタプリタの心臓部である.評価子は以下のアルゴリズム を実現している: Eval(expr: 式)
;; Define は新しい名前を定義するために用いられる.名前はあらゆる値を ;; 参照することができる.(データであろうが関数であろうが関係ない.) (define x 10) (define double (lambda (x) (* x 2))) ;; Quote は リテラルデータ(シンボルまたはリスト)を引用("quote")する ;; ために用いられる. (quote hello) => hello (quote (1 2 3)) => (1 2 3) '(1 2 foo bar) => (1 2 foo bar) ; ティックマーク ' は ; 文法的な置き換え ; (シンタクティックシュガー) ;; Lambda は 新しい関数を生成するために用いられる. (lambda (x) (+ x 10) ; 無名関数 (define plus10 (lambda (x) (+ x 10))) ; その関数を名前に結びつけた. ;; Cond は一般的な条件分岐である. (cond ((eq? 'foo 'bar) 'hello) ((= 10 20) 'goodbye) (#t 'sorry)) => sorry ;; Let は一時変数を定義/利用するために用いられる (let ((x 10) (y 20)) (+ x y))
Schemeでは数(整数,分数,浮動小数点数),文字,文字列,ブール値, シンボル,リストおよびベクトルをサポートしている.以下にこれらの 型について利用できるいくつかの組み込み関数の例を示す.
;; 四則演算: +, -, *, / ;; 関係演算子: <, <=, >, >=, = (+ 1 2) => 3 (= 1 2) => #f ; 数には = を用いる. ;; 等価性と同一性: eq? と equal? (eq? 'hello 'goodbye) => #f ; eq? は同一性のテストである (eq? 'hello 'hello) => #t ; 二つの値が全く同じものなら「eq」である (eq? '(1 2) '(1 2)) => #f (define foo '(1 2)) (define foo bar) (eq? foo bar) => #t (equal? foo bar) => #t ; 同じに見える2つの値は「equal」である (equal? foo '(1 2)) => #t ;; リスト: cons, car, and cdr ;; quote, cons, またはlist で新しいリストを作る (define foo '(1 2 3)) (define bar (cons 1 (cons 2 (cons 3 ())))) (define baz (list 1 2 3)) ;; car, cdr, and null? を用いてリストを操作する (null? '(1 2)) => #f (null? ()) => #t (car '(1 2)) => 1 (cdr '(1 2)) => (2)
;; 指数関数 x^n (define expt (lambda (x n) (cond ((= n 0) 1) (#t (* x (expt x (- n 1))))))) ;; リストの長さ (define length (lambda (a-list) (cond ((null? a-list) 0) (#t (+ 1 (length (cdr a-list)))))))
Schemeでは関数は第1級のデータである.すなわち,引数として他の関数に 渡したりすることができる.
;; 2つの関数【f, g 】と1つの引数【x】をもらって を計算して (f (g x)) を返す (define compose (lambda (f g x) (f (g x)))) (compose even? (lambda (x) (- x 1)) 10) => #f ;; ある関数をもらってあるリストのすべての要素に適用する (define map (lambda (f a-list) (cond ((null? a-list) a-list) (#t (cons (f (car a-list)) (map f (cdr a-list))))))) (map even? '(1 2 3 4)) => (#f #t #f #t)