Scheme
lisp
入門
NucoDay 16

Lisp(Scheme)超絶入門備忘録1

はじめに

 
Lisp経験者は読むだけ無駄です、悪しからず!!

以前からLisp(scheme)を触ってみたかった。
最古のプログラムであり至高、こんな言葉を耳にしたことがあります。
このフレーズだけでも気になっていたので、徐々に学習していこうかと。

ニッチな機械学習とも相性が良いみたいですね、60年も前に開発された言語なのに、恐るべし・・・

そんなわけで超絶初学者向けにはなるかな程度の備忘録です、よし、やってこ!!!

何はともあれHello World

 
とりあえずお決まりのご挨拶を・・・
printが出力する手続き、一つの処理は括弧で括るって感じですかね。
改行、インデントは影響がない様です。

(print "Hello World") ; Hello World


(print
    "Hello World")    ; Hello World

でけたでけた!!!
どの言語も第一歩を踏み出すだけでちょっと嬉しくなりますね。
  

演算してみる

 
簡単な演算を・・・

(print (+ 1 2))        ; 3

(print (+ 1 (* 2 3)))  ; 7

(print (+ 1/2 2/5 2))  ; 29/10

演算記号は基本的に他の言語と相違ないです。
しかし、なぜ演算式が 1 + 2 でなく + 1 2 なのだろう・・・
とも思ったのですが(print "Hello World")と同様に考えると理解できました。
飽くまでもソースは最初に手続き、内容といった規則性みたいですね。

 
上記の例でいうと
 
(print (+ 1 2)) => 表示しろ、(+ 1 2)を 
(+ 1 2) => 足せ、1 と 2 を

といったところでしょうか。
 
 
3項以上、分数を含む場合もシンプルに演算可能です。
※分数でなく実数を扱うことも可能ですが割愛させていただきます。

真偽値

 
しつこい様ですが、同様に手続きを最初に!!

(print (= 1 1))      ; #t

(print (eq? 1 1))    ; #t

(print (= 1(+ 1 1))) ; #f

 

真偽値を返す手続きの一例は下記となります。

手続き 内容
boolean? 真偽値か
string? 文字列か
number? 数値か
integer? 整数か
eq? 等しいか
= 等しいか

 

eq?と=ですが下記の様に結果が異なります。

(print (= 1 1.0))    ; #t

(print (eq? 1 1.0))  ; #f

 

= は数値を、eq?は同一オブジェクトかどうかを比較しています。
また、値が等しいかどうかを調べる手続きの他にeqv? equal?がありますが
ちょっと調べる余裕なかったので今回は割愛します。

変数、条件分岐

 
変数 (define 変数名 式) // 型指定は不要
if関数 (if (条件式) (真の式) (偽の式))
 
こんな感じで定義できます。

; 変数定義
(define a 1)
(define b 2)

; if関数
(if (< a b)
    (print "aはbより小さいよ")
    (print "aはbより大きいよ")) ; aはbより小さいよ

; 変数書き換え
(set! a 3)

(print (if (< a b) "aはbより小さいよ" "aはbより大きいよ")) ; aはbより大きいよ

; 複文
(if (< a b)
  (begin
    (print "aはbより")
    (print "小さいよ"))
  (begin
    (print "aはbより")
    (print "大きいよ"))) ; aはbより大きいよ

おぉ、elseとか不要でスッキリしてますね、三項演算っぽくも書けるし、少しずつ最も美しい言語という名声を
実感してきた気がします。(気のせいです)

関数

関数の定義は以下です。
(define (関数名 引数)(処理))

; 引数を2倍する関数
(define (hoge x)(* x 2))

; 関数実行
(print(hoge 3)) ; 6

とまあこんな感じで。

あと、Schemeでは変数と関数も同列の扱いらしいです。
例えば関数hogeと同名の変数を定義して実行すると・・・

; hogeを再定義
(define hoge 10)

(print (hoge 10)) ; hogeは変数の為error
(print hoge)      ; 10

関数としてのhogeが変数hogeに上書きされるので注意!!

まとめ

Lisp(List processor)なのに今回はlistを扱ってませんw
ただ既にシンプルで無駄がない振る舞いに徐々に魅力を感じます。
次回はlambdaやらmapやら使ってちょっと関数型っぽい領域に入れたら、と思います、ではまた!!