なぜ、今、自分はGaucheを学ぶのか。
手続き型言語の外の世界を知るために。関数型言語の感覚を会得し、何を学び取るべきかを知り、それを学び取るため。
その学びを、今後の設計開発に反映し、また学生さんにもその価値観・世界観を紹介(共有)できるようになるため。
大学の研究室時代、恩師からおすすめいただいた「プログラミングGauche」。
学ぼうと思いながらなおざりにしてしまって、もうすぐ10年を迎えますが、いつも頭のどこかで「あ、Gaucheを学ばねば...」と過ぎる辺り、やはり一度遠るべき学びなのでしょう。
関数プログラミングの "触り" も理解していない現況ですが、恩師がGaucheから何を学ばれたのか、どうして勧めてくださったのか、その点を自分なりに考察しながら、ひとつずつ学び修めてまいります。
・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」が誕生
・Gauche:2001年公開のScheme処理系
・設計コンセプト
・手軽にプログラムを書いて試せるスクリプト処理系
・実用規模のプログラムにまで機能・性能ともにスケール可能
・他言語で書かれたアプリケーションに埋め込み可能
→「プログラマの手に馴染む道具となること」が方針
・マルチバイト文字列に対応
・CLOS:Common Lisp Object System
・Gaucheでは、数値や文字列といった基本データもすべてオブジェクト
・MOP:Meta Object Protocol(CLOS等を実現する仕組み)
・既存のCライブラリを利用するネイティブコード拡張機能がある
・RDBMSドライバ、OpenGLライブラリなどもある
・Gaucheの基本機能はCライブラリとして実装されている → C/C++からGaucheの関数を呼び出せたりする
・PerlとCommon Lispの影響をかなり受けている
・Perlから:正規表現リテラル、文字列補間、モジュールシステム、DBI/DBD
・Common Lispから:キーワード引数、オブジェクトシステム(CLOS)、コンディション
・Schemeの設計思想:簡潔性、正当性、一貫性、完全生
→ 対する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に戻る
・...