何某日和

「カメラ」のち「ハンダゴテ」ところにより「プログラミング」 ── そんな私“かめきち”のウェブサイト

「プログラミングGauche」読書ログ

はじめに

 なぜ、今、自分はGaucheを学ぶのか。
手続き型言語の外の世界を知るために。関数型言語の感覚を会得し、何を学び取るべきかを知り、それを学び取るため。
その学びを、今後の設計開発に反映し、また学生さんにもその価値観・世界観を紹介(共有)できるようになるため。

 大学の研究室時代、恩師からおすすめいただいた「プログラミングGauche」。 学ぼうと思いながらなおざりにしてしまって、もうすぐ10年を迎えますが、いつも頭のどこかで「あ、Gaucheを学ばねば...」と過ぎる辺り、やはり一度遠るべき学びなのでしょう。 関数プログラミングの "触り" も理解していない現況ですが、恩師がGaucheから何を学ばれたのか、どうして勧めてくださったのか、その点を自分なりに考察しながら、ひとつずつ学び修めてまいります。

1章 LispとScheme

・Lispの起源
 ・高水準言語のうち最古の言語の一つ(より古く今も生き残るのはFortranのみ)
 ・1958年 ジョン・マッカーシー(MITの助教授)により開発。
 ・記号処理、特に数式処理のために開発。
 ・「ポインタのペア」でリストを柔軟に表現できる。List Processing → LISP(リスト処理システムとして)
 ・大学院生 スティーブ・ラッセルによりLispインタプリタが誕生。(プログラミング言語として)
・S式と前置記法
 ・S式とは「基本要素」もしくは「S式を並べて括弧でくくったもの」
 ・前置記法:(+ 1 (/ (* 2 3) 4) )
 ・中置記法:1 + 2 * 3 / 4
 ・プログラムの解釈や生成が簡単 → メタプログラミングの源流に。
 ・Lisp処理系はマクロ(処理系自身の構文を拡張してゆく機能)を持つ。
 ・言語自身を自由に拡張できるため、言語機能の実験場として広く使われるようになった。
  → Smalltalkみたい。
・Scheme
 ・1975 ガイ・スティールJrとジェラルド・J・サスマンにより開発
 ・並行プログラミングにおける制御構造の理論を検証するため
 ・機能拡張を重ねたLispは複雑で不便に。逆にSchemeはスッキリさせた。
 ・基本ルールは次の2つ
  ・lambda式は「レキシカルな環境を保持した手続き」(クロージャ)へと評価される
  ・手続き呼び出しは継続を伴った引数つきgotoである
・Gauche
 ・Lisp系言語の2つの流れ
  ・1. 高機能な仕様を指向する流れ
   → 様々なプログラミングパラダイムを取り込み、Common LispとしてANSI標準になった。
  ・2.「単純で直行する少数のルール」を保ったまま使用を洗練させてゆく流れ
   → Schemeとして数年に一度ずつ改定。
 ・Schemeの思想:厳選した少数のルールを用意しておけばいくらでも強力な言語を構築できる
  → でも実用的なプログラミングは大変...
 ・Schemeの原理的な単純さと強さを保ちながら、日常の実用的な問題を素早く解決できる処理系として「Gauche」が誕生

2章 Gaucheの特徴

・Gauche:2001年公開のScheme処理系
・設計コンセプト
 ・手軽にプログラムを書いて試せるスクリプト処理系
 ・実用規模のプログラムにまで機能・性能ともにスケール可能
 ・他言語で書かれたアプリケーションに埋め込み可能
 →「プログラマの手に馴染む道具となること」が方針
・マルチバイト文字列に対応
・CLOS:Common Lisp Object System
・Gaucheでは、数値や文字列といった基本データもすべてオブジェクト
・MOP:Meta Object Protocol(CLOS等を実現する仕組み)
・既存のCライブラリを利用するネイティブコード拡張機能がある
・RDBMSドライバ、OpenGLライブラリなどもある
・Gaucheの基本機能はCライブラリとして実装されている → C/C++からGaucheの関数を呼び出せたりする

3章 Gaucheの設計思想や誕生の背景

・PerlとCommon Lispの影響をかなり受けている
・Perlから:正規表現リテラル、文字列補間、モジュールシステム、DBI/DBD
・Common Lispから:キーワード引数、オブジェクトシステム(CLOS)、コンディション
・Schemeの設計思想:簡潔性、正当性、一貫性、完全生
 → 対するGaucheは「そんなに厳密に "正しく" やらなくても、実用に使えるならいいじゃん」という感じ

4章 Gaucheの開発スタイル

・REPL:Read Eval Print Loop(Schemeでの開発プロセス)
・有理数、複素数も扱える(単一のトークンから成るリテラル)
・#t、#f(真偽値)
・文字 #\a、#\あ
・エンコードの確認は $ gosh -v
・対話モードでの出力は「そのまま入力として与えられる形」が原則(内部データと外部表現の相互変換)... 読み書き不変性(read/write invariance)... Lisp系言語の特徴
・演算子はない。全て手続きで表現。
・(define 変数名 式)
・(define (手続き名 引数 ...) 式)
・(exit) ... インタプリタ終了の手続き
+emacsの設定は ~/.emacs ~/.emacs.el ~/.emacs.d/init.el のいずれかに記載
 → cf. https://qiita.com/tadsan/items/a2018379ffaadf07a418
・C-cs:Gaucheインタプリタ起動
・.scm:Schemeプログラムの拡張子
・EmacsでのSchemerの開発基本スタイル
 1. 書く
 2. 読み込む(C-x C-f)
 3. 動作確認(*scheme* バッファ)
 4. 修正する
 5. 修正反映(C-x C-e)
 6. 動作確認(*scheme* バッファ)
 7. 必要なだけ4に戻る
・...

5章 ...