yojikのlog

yojikのブログです

SQLアンチパターンを読んだぜ!

どうしようもない僕に献本が降りてきた!

SQLアンチパターン

SQLアンチパターン


ありがとうございます。

結論を先に述べると、すごく読みやすくてためになる本です。

RDB使ったシステムを作っている人、特に長年やって人ならば必ず遭遇したことがあるアンチパターンのカタログです。アンチパターンが発生しやすい状況、悪影響や解決方法なども述べています。若い人は現実のシステムで失敗する前に予習できるので、絶対買ったほうがよいでしょう。「この問題!進研ゼミでやったところだ! 」

自分は論理設計のアンチパターンのあたりがお気に入りです。アンチパターンポリモーフィック関連」や「エンティティ・アトリビュート・バリュー」や「マルチカラムアトリビュート」をクラステーブル継承や従属テーブルをつかって回避するのはかなり好きです。*1

本書にはアンチパターンを適用しても良い状況の説明もあって好感が持てます。この本では自然キー(大抵は複合主キーとなる)を推奨しているのですが、ORマッパー利用を前提とすれば、擬似キーを主キーにすることを認めています。この本は単なる「べからず集」ではなく「パターン本」だからです。コンテキストや制約が異なれば導かれる解法も異なるというわけです。

また、後半に出てくるアンチパターン「モデルがアクティブレコードそのもの」に対する解法「モデルがアクティブレコードを持つようにする」については、最近のDCIとの関係でもう少し深く考えてみたいところです。「Entiryが複数コンテキストから使われることによって肥大化する」はDCIが解決しようとする問題の一つだと思うのですが、新しいパラダイムを導入するまでもなく、このパターンを導入すれば済むようなケースも多いんじゃないかと思います。こちらに関しては後日別エントリで。

*1:自分に口を出す権限があれば、いつだってやりたい。OOでいう継承や集約を利用したパターンと利用感覚が似ている

言語が違えば、世界も違って見えるわけ

言語が違えば、世界も違って見えるわけ

言語が違えば、世界も違って見えるわけ

よくある居酒屋談義の一つに「日本語は論理的思考に向かない」というものがあります。この論自体はおそらくほぼデタラメですが、根本的な問題提起を含んでます。すなわち

言語は思考や知覚に影響をあたえるのか?

といった点です。言語学では、この疑問に答える二つの派閥があります。この二つの派閥は、エディタにおけるemacs派とvi派のようにずっと対立しているわけです。

言語相対派
思考や知覚は普遍的なものではなく慣習や言語によって異なる。言語が思考を形作る。
生成文法
思考や知覚は人類共通の普遍的な仕組みである。言語を生み出す本能も人間に最初から組み込まれている。

言語相対派で有名な仮説が「サピア=ウォーフの仮説」です。ベンジャミンウォーフは、インディアンの言語研究を通し「西洋の言語とまったく違う構造を持つ言語を使うインディアンの世界観は、西洋のそれとまったく違うのだ!」という仮説を発表しました。これは「西洋的世界観、論理的思考は普遍的ではないのだ」みたいな議論とつながり、さらにニューエイジ的世界観と結びついて、1970年代に一大ムーブメントをおこしました。

しかし言語相対論は現在ではかなり分が悪いです。単純にウォーフの研究に穴がありまくりだったからです。たとえば彼は「時間を表す言葉が存在しないホピ族には時間という概念そのものが無いのだ」と主張しましたが、後の研究ではホピ族にも時間を表す言葉が存在することがわかっています。言語相対論に関する研究では、英語に翻訳する際の誤訳等により間違った結論を出すものが多く、信頼できる結果を出すことができなかったのです。みなさんも「Javaを使ってるプログラマは向学心の無い社畜野郎だ」とかいわないように。

現代の言語学の主流は生成文法派であり、基本的にはこの本の作者も生成文法派です(邦題とは対照的ですが)。しかし、言語が知覚や思考に影響をあたえる面もあり、なんらかの相関関係はあるだろう、という立場です。作者はこれを「言語はレンズである」という言葉で表現しています。

本書はこの観点にもとづき、言語と知覚に関するさまざまなエピソードや実験が紹介されています。本書はこういうトリビアな知識を楽しむ本かもしれません。順不同で紹介すると、

古代ギリシャ人は青色をしらなかった?

古代ギリシヤのホメロスの叙事詩には空や海の青色を表す単語が全く存在しない。古代ギリシヤ人は葡萄色の空を見ていた? そもそも殆どの文化圏では青色を表す言葉が出現するのはある程度文明が発展してからである。19世紀の知識人にはこのことを知り、古代の人に色覚はまだ発達していなかった、と結論づける人もいた。

方向を前後左右ではなく、東西南北の絶対座標系で表現しなくてはいけない言語がある

オーストラリアのある部族の言葉では、あなたの右側になにかおちていますではなく、あなたの東になにか落ちていると表現しなくてはいけない。そのためには彼らは常に東西南北を意識している。我々が同じ間取りと判断するホテルの一室も、方角が逆なら全然別の間取りだと判断する。

女性名詞のスプーンは女性らしい?

ほとんどの言語では車道は男性名詞、歩道は女性名詞、など名詞に女性形と男性形があるが、それは知覚に影響するのか?

言語が違えば空の色が違って見える?

日本では伝統的に緑色のものを青と表現している。国際的に「進め」を表す信号の色は実際には緑であるが、アオシンゴウと表記している。気弱な政府ならば、ミドリシンゴウという表記に改めるところだが、日本では信号色を日本語に近づけるという判断をとり、緑の中でも一番青っぽい色を信号色に採用した。(このエピソードは凄く日本っぽくていいなーと思いました)

などなど。もちろん古代ギリシヤ人が青色を認識しなかったわけじゃないし、オーストラリアのとある部族が左右を認識できないわけでもないし、われわれ日本人も緑色と青色の区別はしっかりできます。ただし、近年のMRIによる測定によって言語やその言語が生んだ習慣は、人間の知覚や思考にある程度の影響を与える可能性があることも分かってきたようです。

本書の結論は邦訳タイトルに反して若干フワフワしています。「言語が違えば世界もちがって見えるわけ」が説明されているわけではありません。というよりも脳の仕組みを完全に理解し、シミュレートできないかぎり、きちんとした結論を得られることはないだろうし、それは何百年先になるでしょう。現在はようやく科学的な取り組みが始まったばかりの段階です。かといって、言語学者はあきらめないで研究していきますよ!という宣言で本書は結ばれています。

イケてるしヤバい言語 REBOL

ある日ふと思い立って調べてみた、イケてるしヤバい*1言語REBOLについて紹介します。

REBOLは、 Relative Expression Based Object Language 「相対的な表現をベースにするオブジェクト言語」の略です。よく意味わからん。

Wikipediaによると、

1997年にリリースされたREBOLは、カール・サセンラスが20年に渡って設計したものである。サセンラスは AmigaOS の主要アーキテクトであり、REBOLの設計にあたっては、表示的意味論の知識に基づいて、LISP、Forth、LOGO、Self といったプログラミング言語の概念を利用した。

引用元:REBOL - Wikipedia

大雑把にいうと、LispやForthやLOGOやSelfに似たスクリプト言語です。ここからダウンロードできます。最新バージョンはオープンソースライセンスになっています。

REBOLのイケてるしヤバいところ

それではREBOLのすごいところを軽く紹介していきたいと思います。

つくった人がすごい

 1985年にデビューしたAmiga OSは、マイクロカーネルアーキテクチャを採用、設計において他のコンシューマ向けOSの数歩先を行っていた。プリエンプティブマルチタスクに対応し(略)先進性は明らかだろう。そのカーネル(Exec)の開発にあたった中心人物が、Carl Sassenrath氏だ(略)現在Sassenrath氏は、REBOL Technorogiesで「REBOL」というプログラミング言語の開発に従事している。

引用元:Amiga、REBOLの思想を引き継ぐスクリプト言語「Red」 - builder

AmigaOS は当時のフロッピーに収まるほどのサイズで、業務用(日本有名な例ではウゴウゴルーガのCG製作)に使われるほど高機能でした。マイクロカーネルOS Mach の開発開始が1985年ですから、いかに先進的なアイディアの持ち主かがわかります。シンプルで低フットプリントのソフトウェアで最大限の効果をあげるのが上手い、というイメージですね。今回のREBOLランタイムも300kbほどのサイズです。

目的がすごい

REOBLの目的は、「インターネット上のあらゆる機器間で情報がどのように格納され、交換され、処理されるかを表す新たなアーキテクチャを提供することである。すなわち、人間と機械の間の情報の意味論的交換に使われることを意味する」らしいです。

つまり、XMLやJSONのようなメッセージ交換のための言語(かつ人間が読みやすい言語)でありながら、スクリプト言語として実行可能な言語でもあるということです。他のマシンに移動して処理をおこない結果を持って帰ってくるスクリプトとか、ある意味エージェント指向的な未来像が浮かびます。インターネット全体を分散コンピュータのように使えるようにするイメージは初期のJavaも持っていましたが。。。

記述力がすごい

凄い目標を持っていても、スクリプト言語として手軽に使えなければ意味がありません。その点REBOLにはそれなりの記述力があります。

「Webページを開いてボタンを押すとemailで送るパネルを表示する」ワンライナー

view layout [u: field "user@example.com" h: field "http://" btn "Send" [send to-email u/text read to-url h/text alert "Sent"]]

カレントディレクトリにあるファイルをftpでアップロードする

foreach file load %./ [if not dir? file [write/binary join ftp://user:pass@example.com/ file read/binary file]]

このように便利な関数が最初からビルトインされていてワンライナーでいろいろできます。英語の文章のように読める点もグッド。

また上記例にある、%./ はファイル型のリテラルftp://user:pass@example.com はURL型 のリテラルです。email型など普通のコンピューティングで使いそうな型を取り揃えています。これもプログラムが短く読みやすくなるのに一役買ってるようです。

でもそれって拡張性なくてオモチャ言語っぽくなりそう… と思われるでしょうが、後述するようにREBOLは全く別の次元で柔軟性を確保しているのです。。

REBOLプログラムの例

コマンドラインインタプリタでは、このような感じで実行できます*2。下の例では関数を定義してsampleという変数に入れ、実行しています。

>> sample: [n: 1 + 3]
== [n: 1 + 3]
>> do sample
== 4

>> n
== 4
  • 明示的な型宣言は必要なし
  • 代入は変数の横にコロンをつけて、右辺に値
  • 実行可能なブロックも変数に代入可能
  • ブロックをdoという関数に渡すと実行する
  • 関数の実行には[]とか余計なものはいらない

ぐらいのことがわかりますね。また関数型言語やプロトタイプベースのオブジェクト指向言語の能力は持っています。

同図像性(Homoiconicity)がスゴい

同図像性とはデータとプログラムがまったく同じ形式でかけるということです。REBOLにはシリーズというデータ構造があり、これは [] で囲まれ、空白で区切られたデータやシンボル等の塊のことです。先ほどの実行可能だったブロックも、配列チックなデータ構造も、すべてこれで表現できます。LispのS式と似ている感じです。

>> ;これも
>> [ 1 2 3 ]
== [1 2 3]

>> ;これも一緒
>> [ 1 + 2 + 3 ]
== [1 + 2 + 3]

先ほどブロックとして紹介していたものも、数値が入ったリストみたいなものも全く一緒です。

>> do [1 + 2 + 3 ]
== 6

Lispは(+ 1 2 3 )とか見つけたらいきなりevalしますが、REBOLはdoに渡した時点で実行lします。話のわかるヤツだ。(ただしインタプリタトップレベルはいきなり実行かも)

doは素直にシリーズの中身を解釈して実行するネイティブ関数ですが、そのほかに複数のシリーズを受け取って並列実行する関数等もあるようです。

とにかくプログラムの並びとデータの並びに全く区別が無いならば、プログラムの一部をデータのように操作することもできます。

>> sample: [n: 1 + 3]
== [n: 1 + 3]

; sampleの要素の3番目の「+」を「-」に変える( /インデックスで要素を操作できます。ちなみに1オリジン)
>> sample/3: '-
== -

;実行
>> do sample
== -2

>> n
== -2

>>

このようにデータとプログラムの境界線は全くありません。

parse関数がすごい

シリーズの中の値やワードを処理するための強力なparse関数が用意されています。これを使ってマクロ(REBOLではdialect)を作成できます。

スケジュールを表現するための特殊なDSLをワンライナーでパースする例です。(細かく説明するには余白が足りない。。ハートで理解お願いします)

>> rule: [some ['when set time time! | 'where set place string! | 'who set person [word! | block!]]]

whenのあとで続く時間型をtimeに代入 or whereの後に続文字列はplaceに whoのあとに続くワードかブロックはpersonに代入する

>> parse [ Who [yojik1 yojik2]  where "Downtown Center"  when 9:30 ] rule
== true
>> time
== 9:30

>> person
== [yojik1 yojik2]

ね、簡単でしょう?

DSLが書きやすい

つまりREBOLは、

REBOLはコンテンツ依存言語であり、ダイアレクト(dialect)と呼ばれるドメイン固有サブ言語をサポートしている。例えば、return という単語の解釈がコンテンツによって変わることを見てみよう。通常、return は関数を完了して呼び出し元に値を返すのに使われる。しかし、Visual Interface Dialect (VID) では、return という単語があるとレイアウトエンジンが改行(carriage return)と解釈し、レンダリングペンを次行の先頭に持っていく。REBOLプログラマは独自のダイアレクトを生成でき、既存のREBOLの単語に別の意味を付与することができる。

引用元:REBOL - Wikipedia

目的別に小さな言語を利用することによって、シンプルなプログラムを作成するのです。

以下のようなダイアレクトがあります*3

  • do ダイアレクト - REBOLの通常の do 関数が理解し解釈できる(ネイティブ)。
  • reduce ダイアレクト - doダイアレクトで結果を集めるよう変更したもの(ネイティブ)
  • compose ダイアレクト - reduceダイアレクトで括弧だけを評価するよう変更したもの(ネイティブ)
  • function spec ダイアレクト - 関数ヘッダ記述に使われるダイアレクト(ネイティブ)
  • parse ダイアレクト - バッカス・ナウア記法風の文法規則を記述するためのツール(ネイティブ)
  • VID - GUI用ダイアレクトで、layout関数として実装されている(mezzanine)。


アプリケーションプログラマも、自分達のシステムのドメインにあわせたダイアレクト(いわゆるDSL)を作成してシステムの再利用性と記述しやすさを確保することができます。

まとめ

REBOLはイケてるしヤバい。

ちなみにREBOLはバージョン2までは商用製品だったこともあり、あんまりメジャーではないです。

以下は、matzにっきからの引用です。

_ まつもと (2004-05-27 21:47)
Rebolという言語があって、まさに括弧なしのLisp(+豊富なリテラ
ル)って感じだったりします(複数戻り値はありませんけど)。

  http://www.rebol.org/

これも最近はぱっとしませんねえ。「言語ビジネスの夢の跡」なん
て呼んだら中の人に失礼かもしれませんが。

LOGOもちょっと似た感じだけど、あれは省略できるのはトップレベ
ルの括弧だけだったような。

引用元:Matzにっき(2004-05-27)

ついでにいうとver2まではまったく日本語対応してないです。このように仕事にはたぶん利用できないですが、プログラムに対する新しい視点が開けるかも、ということで最近調べています。

以上です!

*1:Inspired by http://iketeru-nagashima.com

*2:当たり前ですがファイルを指定しての実行もできます

*3:wikipedia調べ