Scheme入門

SchemeというのはLISP言語の方言です。LISPが最初は人工知能(AI)の研究為の開発された非常に古い言語です。今使われているLISP重要な方言が2つです:Scheme(強調がミニマリズム:必要な機能だけ)とCommon Lisp(強調が機能:機能が非常に多いので、ちょっと複雑)。

インストール

最初は、guileをインストールしましょう。
$ sudo apt-get install guile-2.0


基本な計算

guileを使い始める為、ターミナルでguileをタイプして、Enterを押します:

$ guile

GNU Guile 2.0.11

Copyright (C) 1995-2014 Free Software Foundation, Inc.


Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.

This program is free software, and you are welcome to redistribute it

under certain conditions; type `,show c' for details.


Enter `,help' for help.

scheme@(guile-user)> 

Scheme(又は、LISP)が初心者にとって難しいということが良く言われています。例えば、数式にポーランド記法を使います:

scheme@(guile-user)> (+ 2 2)

$1 = 4

scheme@(guile-user)> (+ 2 (+ 1 1))

$2 = 4

scheme@(guile-user)> (+ 3 (+ 1 2))

$3 = 6

scheme@(guile-user)> (sqrt 16)  ;因みに、Schemeのコメントがセミコロンから始まります

$4 = 4

変数を定義する為、(define <name> <val>)とういう関数を使います:

scheme@(guile-user)> (define my-name "snoopy")

scheme@(guile-user)> my-name

$1 = "snoopy"

今のセッションを終わる為、(exit)問いう関数を使います:

scheme@(guile-user)> (exit)

データ型

Schemeの重要な基本なデータ型が以下のようです:
  • 数字(整数、実数、複数、有理数)
  • 文字列(ストリング)
  • ブーリアン
更に、複合データが一個だけで、ペーア(英:pair)と呼ばれているものです。しかし、ペーアを使って色々な他の複合データ型を定義できます。例えば、リスト配列)です。

数字

数字は色々な形で書けます:

scheme@(guile-user)> #b111 ;バイナリー

$7 = 7

scheme@(guile-user)> #o111 ;八進法

$8 = 73

scheme@(guile-user)> #x111 ;十六進法

$9 = 273

scheme@(guile-user)> 6.02e+1;指数表記

$11 = 60.2

scheme@(guile-user)> 1+2i ;複数

$13 = 1.0+2.0i

scheme@(guile-user)> 1/3 ;有理数

$14 = 1/3

Schemeの特徴が正確です。つまり、Schemeがなるべく不正確な実数の代わりに、正確な有理数と整数を使います:

scheme@(guile-user)> (define a 42) ;正確で、整数

scheme@(guile-user)> (- a 5) ;まだ正確で、まだ整数

$1 = 37

scheme@(guile-user)> (/ a 47); 正確で、有理数になる

$2 = 42/47

scheme@(guile-user)> (sqrt a); 不正確になりました

$3 = 6.48074069840786

もちろん、数字に関わる色々な関数があります。例えば、

scheme@(guile-user)> (expt 2 3) ;冪演算

$5 = 8

scheme@(guile-user)> (quotient 5 2) ;商

$6 = 2

scheme@(guile-user)> (remainder 5 2) ;剰余

$7 = 1

scheme@(guile-user)> (max 423 536 4564) 

$8 = 4564

scheme@(guile-user)> (min 423 536 4564) 

$9 = 423

scheme@(guile-user)> (<= 3 4) ; #t := TRUE

$10 = #t

もっと詳しい情報がguileのマニュアル(英語)に書いています

ブーリアン

#tがTRUEで、#fがFALSEを表します:

scheme@(guile-user)> (not #t)

$9 = #f

scheme@(guile-user)> (and #t #f #t)

$10 = #f

scheme@(guile-user)> (or #t #f #f)

$11 = #t

文字列

文字列の扱い方が他の言語とほとんど一緒です:

scheme@(guile-user)> (define s1 "hello")   

scheme@(guile-user)> (define s2 " world!")

scheme@(guile-user)> (string-append s1 s2)

$1 = "hello world!"

scheme@(guile-user)> (string-length s1) ;ストリングの長さ調べる関数

$2 = 5

scheme@(guile-user)> (substring s2 0 3);部分列を取る関数

$3 = " wo"

もっと詳しい情報がguileのマニュアル(英語)に書いています

ペーア

ペーアのアイディアを分かる為、例を見ると市場有用です:

scheme@(guile-user)> (define p (cons 1 2)) ;ペーアを作る

scheme@(guile-user)> (car p) ;ペーアの最初のメンバーを取る

$5 = 1

scheme@(guile-user)> (cdr p) ;ペーアの最後のメンバーを取る

$6 = 2

ペーアのメンバーが基本的なデータ型の元だけでなくて、他のペーアでもOKなので、consを再帰的に使うと、非常に複雑なものを作れます。

配列

定義によって、配列が再帰的に使われたconsの結果です:

scheme@(guile-user)> '()  ;空配列

$7 = ()

scheme@(guile-user)> (cons 1 '()) ;一個元の配列

$8 = (1)

scheme@(guile-user)> (cons 1 (cons 2 '())) ;2個元の配列

$9 = (1 2)

scheme@(guile-user)> (cons 1 (cons 2(cons 3 '()))) ;3個元の配列

$10 = (1 2 3)

配列は元々ペーアだけの特別な場合ので、独立なデータ型ではないです。しかし、便利の為Schemeに配列のいくつ速記があります:

scheme@(guile-user)> (list 1 2 3) ;これは(cons 1 (cons 2(cons 3 '())))と一緒

$11 = (1 2 3)

scheme@(guile-user)> '( 1 2 3) ;これも(cons 1 (cons 2(cons 3 '())))と一緒

$12 = (1 2 3)

(TODO: lists important, hence many functions, examples)

関数の定義方

(TODO: define)
(TODO, mention recursion)

制御フロー

(TODO if)
(TODO cons)
(TODO 

参考文献

  1. Daniel P. Friedman "The Little Schemer"(日本語翻訳図書館にある) -- 色々なScheme問題の収集です。数学者(特に、論理、個人言語理論又は組み合わせ論に興味がある方)にとって面白いと思います
Comments