Hatena::Diary

Keep Crazy;shi3zの日記 RSSフィード

2009-06-15

iPhoneとiモードのプラットフォームとしての未成熟さ、または「儲からないからチャンスがある」という考え方

いま、テキサスの田舎町で、たまたまDWANGOの創業者であるボブが購入したランチ(別荘?)に居るんですけど、日本で川上さんが京都から帰るや否やiPhoneプラットフォームを全否定しています。



これはたとえ川上さんを敬愛してやまない僕であっても、即座に反論せざるを得ない。


コンテンツプラットホームとしてのiPhoneの設計は間違っている - はてなポイント3万を使い切るまで死なない日記

http://d.hatena.ne.jp/kawango/20090615/1245039092

いいたいこと

・ コンテンツプラットホームではヒットコンテンツが十分にもうからないとダメ。

・ ちなみに儲かるクリエイターが存在できることではなく、たばねるパブリッシャー的な存在が儲かることが成立する必要がある。

・ プラットホーム上でプロモーション手段がなさすぎる。

・ ヒットしたときにコンテンツプロバイダー側にブランドとユーザが蓄積する構造が必要

・ オリジナルコンテンツではなく、既にあるコンテンツの2次利用と競争させるプラットホームでは既存の大企業のコンテンツホルダーが有利。(正確にはそれすらも微妙だけど)

そりゃiモードのときみたいに上手くいかないですよ。

川上さんが全否定していた(忘れたかも知れないけど)iモードは、99年の夏当時、こんな状況でした。

スタート時のコンテンツは67

ユーザ数100万人未満

ヒットしたコンテンツの会員数は2万人

ダメそうですよね。

すごく、もりあがってないし。


だけど、僕たちにとって、2万人で月額300円、つまり月の収入が600万円あるというのはそれだけで羨ましいと思ったのは事実。


ついでにいえば、当時は「ゲーム」カテゴリにはナムコ、トミー、バンダイの三社しかなくて、今だから言うけれども、どれもこれもまともなコンテンツとして成立していなかった。というか、少なくとも開発者の「やる気」が感じられたのはバンダイだけで、後はひどい有様でした。


ここまでひどい相手しかいないなら、勝てるかもしれない、と一縷の望みを託して川上さんが伝を頼って辿り着いたのがNTTドコモに居た榎氏、とその部下の夏野氏。


それでも実際のところ、夏野さんに「自分でやんなさい」と言われるその瞬間までは、下請けやる気満々だったじゃないですか。


結果的にだけれども、誰もクライアントがつかなくて、仕方なく自分で始めたところ、競争相手が極端に少なかったからそこそこ上手くいった。全てはそこからじゃないですか。



サイバードが波伝説で2万人も会員が居るって自慢してた頃です。今思うと、ちょっと笑っちゃうくらい、小さいスケールにみんなが興奮してた。



でも、新しい市場の立ち上がりってそういうもんじゃないですかね。



僕はiモードの月額300円という縛りは、当時からおかしいと思っていたし、週刊誌の値段で月刊誌を運営することなんてできないと思っていた。実際のところ、だからこそ真面目にやる会社は少なかったわけで。


それでも僕が真面目にやろうと思ったのは、その直前まで3Dのことばっかり考えていて、「面白いものを作る」という根本的な部分が自分の中で確立できていないような気がしたから。


一度、3Dという便利な表現手段を全部棄ててみて、禅の修行のように「面白さの本質とはなにか?」を考えて、ゼロからゲームを構築するという試みをしたわけです。


僕にとっては、会社のことより自分のことだったので真剣になれたし、それが確実に今に繋がっていると思うわけで。


iPhoneは多くの人にとっての、そうしたテストベッドというか、修行の場であり、壮大な実験室であることはいまのところ疑う余地がないわけで。


iモードだってコンテンツプラットフォームとして、最初からスーパースターの出現を意図的につくりあげたわけではいだろうし(夏野さんはそう考えていたって言い張るかも知れないけど)、月額300円が上限という、今考えたらバカみたいにきつい制限の中でも、必死でマネタイズしようと努力する人たちがいたからこそ今日の姿があるのだと思う。


他のコンテンツはともかく、ゲームに関しては非常にきつい制約だったと思う。

ただし、制約がきつく、儲けが出しにくいからこそ資本にものを言わせてやってくる大手とアイデア勝負のベンチャー企業が互角に渡り合えたわけで、最初からパブリッシャーだけが儲かるようなビジネスモデルを構築しているゲームコンソールではベンチャー企業がパブリッシャーとして成功するチャンスなど万に一つもない。



iPhoneも同様で、iPhoneプラットフォームは儲からないからこそ競争余地があると思う。

これが、コンスタントに億単位でゲームが売れて、投下した資本に比例してゲームの内容も売上もあがっていくというゲームコンソール的な構造になっていたら、ベンチャーの入り込む隙はなくなってしまう。


ゲリラ戦の鉄則は、巨大な敵が欲しがらない、とるにたらない領地を攻め、そこを護りきることだという。

だとすれば、iPhoneほどゲリラに適した市場はない。


有効なプロモーション手段がないなんていうけれども、99年当時のiモードだって同じだった。

月収600万円じゃまともな広告なんて打てない。


パンフレットを作って、全国のドコモショップに僕が自分で電話をかけてパンフレットを置いて貰った。

あまりに電話をかけるのでドコモが悲鳴をあげて、それから正規のルートで扱ってくれるようになった。

パンフレットは20万部くらい配ったと思う。というのも、ドコモショップの数が多すぎたからだ。

たぶん携帯電話コンテンツで初めて電車に広告を打ったのも僕たちだと思う。

でもお金がなかったから、京王線にしか出せなかったんだよね。

他にも、土日も含めて毎日コンテンツを更新したり、寿司券があたるようにしたり、地方のドコモに遠征して説明したり、そういう地道な営業・販促活動を徹底的にやった。

その結果、CMの話につながって、ようやく僕らも2万人超のサイトを作ることが出来た。

これはまあでも、殆ど運だったと言って良いだろう。



とはいえ、そういう努力の積み重ねをまるごと無視して、プロモーション手段がない、なんていってしまうのは川上さんがすっかり大企業の人になってしまった証拠だろう。


でもそれはドワンゴがiPhoneに参入しない理由にはなっても、他の人たちがiPhoneに参入しない理由にはならない。



あと

ヒットしたときにコンテンツプロバイダー側にブランドとユーザが蓄積する構造が必要

これがiPhoneにないっていうんなら、ケータイにも未だにないんじゃないですか?

少なくともうちが作ってるチャットアプリはユーザが蓄積しているから後半はあてはまらないとしても、ブランドの面でいえば、「釣りスタ」は知っていても「GREE」は知らないとか、「イロメロ」は知っていても「ドワンゴ」は知らないとか、いくらでもあったはずでは?(だからこそdwango.jpにしたんですよね?)



リングの外から文句を言うのは自由ですが、僕たちはそんなこと百も承知でやっているわけです。



そこまで言うならドワンゴは絶対にiPhoneで有料アプリを出さないでくださいね

2009-06-13

Kahuaメモその3 継続ベースで快感Webプログラミング

起きました。

まあその1、その2まではLISPはいいよっていう紹介であって、あんまり自分のメモには役立たなかったわけで、ここからが本番なんだけど


Kahuaは「継続ベース」というパラダイムのWebフレームワークです。

まず、普通のWebアプリケーションをPHPなんかでいきなり書き始める時にはどういう書き方になるかというと、だいたい、$_POSTとか$_GETとかの広域変数を参照して、処理の内容を決めると思います。

<?
if($_GET['hoge']){
   echo "hogehoge";
}else{
   echo "Hello, php";
}

だいたい、適当に書くとパラメータでモードというか、「そのアプリケーションで何をさせたいか」を選択します。

もちろん、ファイルを分ければもう少しスマートになりますが、コードを書きなぐりたい時にファイルを分けるというのは僕はぜんぜん快適だと思わないので、できるかぎりひとつのファイルでコードを書いて、リファクタリングするときに分ける、というスタイルを使っています。


まあいつもプロトタイプしか作らないので、リファクタリングするところまでコードが進んで行くことは滅多にないのですが。



そういうスタイルだと、とにかくこの$_GETとか$_POSTとかの処理が複雑になっていきます。

もちろんこれをスッキリさせるためにはMVCベースのフレームワークを採用すればいいのですが、なんか異常に大掛かりになってしまってやっぱりファイルが大量に出来てしまいます。


Kahuaも一種のフレームワークなのでファイルは大量にできるのですが、基本的にはひとつの.kahuaファイルをいじるだけで、データ構造の定義とビューとコントロールを全て扱うことが出来ます。これは僕みたいな「BASICのようにコードを書きたい」プログラマには向いています。


さらに、Kahuaでは、Webアプリのモードを「エントリー」と呼び、ネイティブでサポートしています。

上記のphpのようなコードは、Kahuaでは以下のように書けます。


(define-entry (hoge)
  (kahua:xml-template->sxml
   page-template
   :title (title/ (@/ (id "title")) "")
   :body (div/ (@/ (id "body"))
	       "hogehoge" )))

(define-entry (default)
  (kahua:xml-template->sxml
   page-template
   :title (title/ (@/ (id "title")) "")
   :body (div/ (@/ (id "body"))
	       "Hello LISP" )))

(initialize-main-proc default)

 「おい、なんだ、PHPよりコード量増えてんじゃん」

 と一見思えるかもしれませんが、これはテンプレートエンジンを使っているので直接比較するのはフェアじゃありません。

PHPだと全く同じようなコードはたとえば以下のような感じになります。

<?
$smarty = new Smarty();

if($_GET['hoge]){
  $smarty->assign("title","");
  $smarty->assign("body","hogehoge");
}else{
  $smarty->assign("title","");
  $smarty->assign("body","Hello PHP");
}

$smarty->display("page.html");

まあそれでもまだPHPの方が簡単に見えますね。

けど、Kahuaのコードには、パラメータを解釈する命令やif文がありません。

プログラムをスパゲッティなものにする原因のいくつかはif文にあると考えられます。

分岐はなるべく見えない方がコードがスッキリすると思うので、この時点でも僕はKahuaの方が好みです。

いまはたかだか二つのモードですが、Webアプリケーションは複雑化するとかなり沢山のモードを使い分けなければいけません。それは凄く面倒です。


さて、ここからが問題。

最初のモードきりかえくらいはPHPでも我慢してコードを書けばもう少しスマートにできるですよ。

連想配列使うとか。


けど、いままでWebアプリケーションを書く時に、「これは面倒だな」と思う処理の多くは、「あるモードの時に特定のボタンを押した後の遷移」だったりしませんか?


 「このリンクを押したら、次はこの関数を呼びたい」


ただそれだけのために、またモードの下にサブモードを作ったり、セッション変数になにかを保存してそれを呼び出してプログラムを書いたりしていると、本来人間が脳細胞を使うべきでない実に機械的な仕事に頭を使っている時間がだんだん空しくなってきます。

これは最初のうちはまだ我慢できるのですが、コードが複雑化していくに従って分岐や遷移、サブモード、サブモードのサブモード、サブモードのサブモードのパラメータなどが指数関数的に増えて行ってURLがどんどん長くなったり、それをきらってセッション変数にどんどん値を入れたり、データベースに書き込んだりという、本来のロジックとは無関係なところでコード量が増大していきます。


そのうち


 「あー、ここに新しいボタンつけなきゃだけど、面倒だからやめとくか」


という「変な妥協」をし始めて、そのコードは完成とはほど遠い状態で放置されます。

ま、これは僕の場合ですが。


Kahuaでは、これを「継続ベース」という方法で解決しています。

論より証拠、で実例を見せましょう。

(define-entry (greeting)
  (kahua:xml-template->sxml
   page-template
   :body (div/ (@/ (id "body"))
	       "Hello, Kahua!"
	       (a/cont/ (@@/ (cont version))
			"version"))))

(define-entry (version)
  (kahua:xml-template->sxml
   page-template
   :title (title/ (@/ (id "title"))
		 "flyrr")
   :body (div/ (@/ (id "body"))
	       (h1/ (format "flyrr: version ~a"
			    *flyrr-version*))
	       (a/cont/ (@@/ (cont greeting))
			"greeting"))))

これはKahuaのデフォルト状態で書いてあるエントリーですが、注目すべきは「(a/cont/」以降です。

「(a/ )」は言わずと知れたAタグを生成する関数ですが、(a/cont/ )は継続を伴うAタグを生成する関数です。

上記のコードでは(a/cont/)が二回出て来ますが、それぞれの中で(cont greeting)や(cont version)を呼出し、お互いのエントリへ処理を引き渡しています。

これは普通なら、継続を使わずに素のHTMLでa href=foo.php?greeting=とでも書けばよさそうなものなのに、わざと継続を使った書き方をしています。


これだけだと、単にgreetingとversionを行ったり来たりするだけなのであんまり面白くないのですが、これにパラメータ渡しを含めると、俄然便利になります。


実例で紹介しましょう。ただし、これ以降はKahuaのチュートリアルをやっておいた方が少しは理解が深まると思います。


たとえばKahuaのチュートリアルにある<bookmark>クラスのオブジェクト一覧表示するエントリは以下のコードで書けます。説明のため、Kahuaのチュートリアルとは少しだけ変えてあります。

(define-class <bookmark> (<kahua-persistent-base>)
  ((title :allocation :persistent :init-keyword :title :init-value "")
   (url :allocation :persistent :init-keyword :url :init-value "")))

(define (bookmark-entry/ bm)
  (li/ (ref bm 'title)  ))

(define (bookmark-list/ bm-collection)
  (ul/ (map/ bookmark-entry/ bm-collection)))

(define-entry (all)
  (kahua:xml-template->sxml
   page-template
   :title (title/ (@/ (id "title")) "All Bookmarks")
   :body (div/ (@/ (id "body"))
               (h1/ "All Bookmarks")
               (bookmark-list/ (make-kahua-collection <bookmark>)))))

このコードだけでもデータベースを扱うコードとしてはphpよりずっと短く、すっきりしています。



冒頭のdefine-classで<bookmark>クラスを定義し、最後のdefine-entryでallというエントリを書いています。

これの面白いポイントは、ひとつの関数でまとめて書かずに一覧を表示する関数bookmark-list/(/まで含めて関数名です)と、エントリーそれぞれを表示する関数bookmark-entry/をそれぞれ分けていることです。

ループがどこにもないように見えるので不思議かもしれませんが、ループの処理はbookmark-list/関数のmapで行っています。

ちなみにbookmark-entry/の(ref bm 'title)というのは、bmオプジェクトのプロパティtitleを参照せよ、という意味の関数呼出しです*1


さて、このコードを走らせると、ブックマークのタイトルとurlが一覧表示されます。

せっかくなので、この一覧から任意のブックマークの内容を編集できるようにしたいと思います。


そういうとき、phpでは、各ブックマークのお尻に「edit」みたいなリンクをつけてそれをクリックすると編集できるようにすると思いますが、そういうサブモードを作らなければならなくなり、まずパラメータをどんなものにするか考えることになります。


ところで<bookmark>クラスを見て下さい。

なんとあらゆるデータベースに必要なはずの「ID」がどこにも見当たりません。

ではどうやってオブジェクトを特定するのでしょうか?

ここが「継続ベース」の本領発揮です。


いきなり編集は難しいので、まず、内容の詳細表示をすることにしましょう

(define (bookmark-entry/ bm)
  (li/ (ref bm 'title) )

この部分を以下のように書き換えます。

(define (bookmark-detail/ bm)
 (ref bm 'title) (ref bm 'url))

(define (bookmark-entry/ bm)
  (li/ (ref bm 'title)
        (a/cont/
        (@@/ (cont (entry-lambda() (bookmark-detail/ bm))))
        "detail" )

これだけです。

なにが起きてるのか説明しましょう。

(a/cont/)は継続を伴うAタグでした。

普通ならhrefと続くところを@@/以降に書いた処理を行うようになっています。

このリンクをクリックすると、@@/の直下にあるcontと、それに続くentry-lambda()が呼び出されることになります。

entry-lambda()は無名エントリの定義です。

cont以降は実際には一度に呼ばれるわけではなく、その項目がクリックされた「後」に呼び出されます。

entry-lambdaの中で、<bookmark>の詳細を表示するbookmark-detail/関数にbmオブジェクトを渡して呼び出しています。

これが「継続」です。

「継続」とは、直前のプログラムの状態をリンク時に凍結し、クリック後にそのまま処理を継続することです。

いわば仮想マシンをある実行状態で止めて、クリックをきっかけにまた動きだす、という状態に近いのです。


「継続」を使うと、プログラムの大部分はかなりすっきり書けますし、サブモードに使うパラメータ名や変数などを考えたり、渡し方を考えたりといった作業から解放されます。


さて、さらにもう一歩複雑にして詳細画面ではフォームを表示し、データの書き換えができるようにしてみましょう。

(define (bookmark-detail/ bm)
  (form/cont/
   (@@/ (cont (entry-lambda (:keyword title url)
                (set! bm 'title title)
                (set! bm 'url url)
                (redirect/cont (cont all)))))
   (table/
    (tr/ (th/ "Title: ")
         (td/ (input/ (@/ (type "text") (name "title") (value (ref bm 'title)))))
    (tr/ (th/ "URL: ")
         (td/ (input/ (@/ (type "text") (name "url") (value (ref bm 'url))))))
    (tr/ (th/) (td/ (input/ (@/ (type "submit") (value "Update"))))))))

form/cont/は、ご想像の通り継続を伴うformタグです。

継続された結果はやはりentry-lambda以下に書かれています。

ここで初めてクエリーパラメータの処理が出て来ました。

けれども、驚くほどシンプルです。

(:keyword title url)とすると、それぞれの名前のパラメータが変数titleと変数urlに紐づけられます。

(set! bm 'title title)は、ブックマークオブジェクトbmのtitleプロパティにパラメータとして渡されたtitleを代入する関数呼出しです。


これが継続ベースのWebプログラミングです。

慣れてくると頭を悩ますことが減って行くような気がしませんか?


そしてLISPで書くと、ひとつひとつの関数が驚く程短く書けることに気づいたと思います。

LISP、とりわけschemeは様々の高級言語のいろいろな本質的な部分を抽出し、非常にシンプルかつ統一された方法であらゆる言語機能にアクセスできるところが実に強力なのです。


とはいえこれはまだLISPのほんの入り口に過ぎません。

LISPはデータ構造もプログラムも全てS式で表せるので、S式を吐き出すS式というのを作ることが出来、それはすなわち、プログラムを吐き出すプログラムが非常に簡単に作れることを意味します。


さらにいえば、プログラムを受け取ってプログラムを吐き出すプログラムを書くこともできます。そうすることで言語機能そのものを拡張することが容易にできるわけです。


で、本物のLISPerの人たちというのはもちろんこのマクロ機能こそLISPの最も強力な機能だと主張してやまないのですが、マクロ機能の有難味が解るには、よほどコードを書き慣れていないといけないわけです。


なにしろ他の言語には、これほど強力なマクロ機能はありませんから、比較も想像もしようがないのです。


単に「マクロ」という名前の機能はおよそあらゆる言語に備わっているものなので、LISPerの方々が「LISPのマクロは強力だ」といくら主張しても、他の言語のユーザからすれば


 「それっていまのマクロとどう違うの?」

 「まあせいぜいこれがちょっとマシになっただけなんでしょ?」


という程度の認識しかもたなかったり、最近プログラムを始めたような人たちからすれば、


 「オブジェクト指向すらマクロだけで実装できる」


という主張にしても


 「既にあるんだからオブジェクト指向そのものを作ったりするわけねえし(笑)」


というあまりにも志の低い発言で台無しになったりします。

オブジェクト指向以前の言語から現在まで、とりわけBASIC、C、C++と学んで来た僕からすると、BASICから構造化されたCになっただけで革命的な気分になり、Cからオブジェクト指向を取り入れたC++になったときにもさらに革命的な気分になり、C++がテンプレート機能(これはLISPのマクロに近い)を採用したときも「ウハー」と思ったくちなので、「オブジェクト指向そのものを作りたくなる」気持ちがどういう気持ちか想像できるのですが、ヤングの人たちにとってはオブジェクト指向も構造化プログラミングもテンプレートも、「もともとそこにあったもの」だから少々魅力を欠いた表現になることは致し方ありません。


以上、駆け足でしたがWWDC開催期間中にも関わらず、なぜかLISP談義で三回もブログを書くと言う暴挙をしたわけですけど、ここまで理解するのに、僕もやたらと無駄な時間を使ってしまいました。

けれどもいまは晴れ晴れとした気分で一杯です。


ようやく僕も「LISPの門」の入り口に立ったという段階なので、このブログで書いた内容はまだまだいろいろな誤解や誤読に基づいていることは否めません。


もし興味が出たら、ぜひLispを勉強してみることをお勧めします。

ところで僕がLispに狂うのとほぼ同時に、Gaucheの開発者である川合史郎さんに「天下一カウボーイ大会」で発表していただけないかと打診したところ、ご快諾頂きましたので、もし興味が出たら「天下一カウボーイ大会」にもご参加頂ければ幸いです。

*1:この呼び方に普通の言語に慣れてる人は違和感を感じるかもしれませんが、慣れてくると実に合理的な書き方だと解ります

2009-06-12

Kahuaメモその2 KahuaにおけるオブジェクトDBとsxmlの快適さ

さて、続きです。

前回はLispが意外にもややこしいものではないことを説明しました。

そのLispのさらにシンプルな方言がschemeで、シンプルなだけでなく独自の制御構造も持ったなかなかナイスな言語らしい、ということまでは解りました。


せっかくならこれで実用的なWebアプリを書いてみたい。

しかしLispのWebアプリケーションのサンプルはたいていがWebサーバ自身をLispで記述するという過激なもので、CGIみたいに気軽に使うみたいなことではちょっと違うぞ、というオーラを放っていました。


それはそれでしんどそうだ、と思った僕はふとしたことからKahuaというscheme上のフレームワークを知ります。

Kahuaは、scheme処理系のひとつであるGaucheで動作するフレームワークで、「プログラミングGauche」という本もKahuaプロジェクトの方が書いたということなので、かなりのGaucheハッカーなのだと思います。

もともとオブジェクト指向の規定がないschemeですが、Gaucheでは独自にオブジェクト指向の機能も実装しています。


Kahuaの特徴として非常に興味深いのは、「継続ベース」であるということ、それと内部にオブジェクトデータベースを持っているということです。


まず、解りやすい方から説明しましょう。

Kahuaのオブジェクトデータベースは、非常に扱いが簡単です。

通常、Webアプリケーションというと、DBスキーマの設計と実装に頭を悩ませます。

なぜならDBスキーマは一度設計してしまうと運用時においそれと変更することができないからです。

また、DBスキーマを扱うところだけはSQLやDDLを使わないといけないため、プログラムそのものとは違う作業が必要になって、これもちょっとだけかもしれませんがプログラマの負担になります。まあこれは「ちょっとやだなー」程度の負担ですけど、この「ちょっとやだなー」というのがプロトタイピングなどでは大問題になります。


それに比べてKahuaのオブジェクトデータベースは凄く簡単です。

どう簡単かというと、たとえば以下のようなクラスを定義するとします。

(define-class <bookmark> (<kahua-persistent-base>)
  ((title :allocation :persistent :init-keyword :title :init-value "")
   (url :allocation :persistent :init-keyword :url :init-value "")))


以下より引用
http://www.kahua.org/show/doc/Tutorial/Step3

これだけで、データベース完成です。

プログラムのどこかで

(make <bookmark> :title "Kahua Project" :url "http://www.kahua.org/")

などとやるだけで、レコードが勝手に生成され、保存されます。

あるクラスのインスタンスの一覧は

(make-kahua-collection <bookmark>)

とすると、コレクションクラスを受け取ることが出来ます。

なにこの簡単さ!

簡単すぎてオブジェクトの検索をどうやるんだろうとか、いくつか疑問がなくはないですが、プロトタイピングならこれで十分です。

データベースの実体はデフォルトではファイルにおかれるようですが、設定するとmysqlやpostgresqlでも使えるようです。

まあこれはRuby On RailsのActiveRecordのようなもんだと思いますけど、ActiveRecordももっと何倍も手間掛かるような気がしますしね(特にコマンドラインといったりきたりするあたり)。


それと言い忘れましたが、kahuaは実行中にプログラムをホットデプロイできます。

というか、プログラムではなくて関数ごとにホットデプロイできます。

関数ごとですよ?

Javaみたいにクラスごとにファイルが別れていてホットデプロイできるのとはわけが違います。関数ごとに「この関数、とりあえず適用」とかできるわけです。

それだけではなく、実行中のサーバインスタンスに直接S式を発行してインタラクティブにサーバの動作を変えることができます。

これは無茶苦茶強力な機能だと思いますね。

だからプログラムの一部を直して、C-x C-eとやると、その時点でその関数が書き変わったり、スーパーバイザーコンソールで直接オブジェクトデータベースを操作したり内容を確認したりできるわけです。


これだけでも凄くプログラムが楽しくなります。

まるで古き良き時代のBASICインタプリタで遊んでいるかのような牧歌的な気分でコードが書けます。書いて、試して、なおして、また書いて、のループが凄くクイックにできるのです。


KahuaではHTMLを書く時にsxmlという方法を使います。これはたとえば


(p/
 (h1/ "hoge)
 (ul/
  (li/ "one")
  (li/ "two")))

というようにHTMLのタグをS式で表したものです。

最初は違和感があるのですが、慣れるとそもそもタグの閉じ忘れが無くなる(括弧の対応関係だけみてればOKになる)ので、HTMLをそのまま書くよりずっと効率が良いと感じるようになりました。

凄いのは、テンプレート言語を使ってないのにテンプレート言語のように記述できることです。これはPHPとは正反対の考え方ですが、合理的です。

当然、S式ですから、なにか要素を埋込みたかったら変数を使ったり関数を呼んだりできます。


LISPはこんなふうに関数やマクロをうまく定義することで、文法を目的にあわせて最適化できるのです。


sxmlも単なるライブラリに過ぎないので、このやり方が気に入らなければ自分で新しい方法を考えだすこともできます。


さて、そしていよいよ「継続」ですが、これがもうとっても気持ちいいんです。

しかしやはり長くなってしまったのでなにが気持ちいいのかはまた次回

2009-06-11

Kahuaメモ またはなぜヤングにLispが向かないのか

個人的に年に一度くらいLispブームがやってくるのですが、今回のはけっこうビッグウエーブ

東大ではプログラミングの最初にschemeを習うとかOCamlを習うとかいう伝説を聞いたことがあるのですが、僕は大学にちゃんと行かなかったので、電通大の基礎言語であるPascalもままならない有様(R3000は出来たけど)でして、当然、そんな関数型言語なんか雲の上みたいな存在で良く知らん、という状態なのでした。


そういうとすっごい遅れてるって感じなのですが、僕がコンピュータに狂っていた90年代前半というのはマイコンで動くまともなUNIX処理系なんか存在しないに等しくて(実際には存在はしていたらしいけど手に入るような状況じゃなかった)、MINIXとかをなんとか手に入れて「UNIXなる理想郷」の存在を遠目に感じる、くらいしかできなかった僕は、迷わずマシン語の世界へ突入していったわけですけど、高級言語としてはFORTLANについで古いと言われるLISPは、僕に撮ってFORTLANそのものと同じくらい縁遠い存在だったわけです。


そのまま物心ついた頃にはC言語とインラインアセンブラだけで仕事をするようになっていて、いまさらよくわかんない関数型言語なんかしゃらくせえ、と思っていた僕は、コードを美しく書くというよりは三角形をいかに清く、正しく、美しく描いて行くか、そればかりに腐心するようになっておりました。


その後、Webプログラミングを生業にしたときも、かなり長い間はC++でFast-CGIを書いていました。「速さは正義」のゲームプログラミングの世界からそのままWebの世界にやってくると、Perlスクリプトとかはハエが止まっているようにしか見えなかった。


ただ、Cだとコンパイルの手間が入るので、どうしてもコードを書き直す度にサーバを再起動しなければならず、なんだかそれ自体がひどく非効率的な気がして来て、数年前からしばらくの間はJavaで頑張っていました。Cに似てたし。JITも随分良くなった、という印象がありましたからね。


けど、Javaもなかなか悪くないんだけど、いまいちTomcatで運用しようとすると高い負荷がかかったときに不安が残る。さりとて商用の高価なアプリケーションサーバを導入する費用もなかったので、学習コストがあまりかからないように思われたPHPに移行。実際、PHPの学習コストはほぼゼロに近かったので、開発効率、それと引き継ぎの効率はかなり上がりました。自分自身で仕事用のコードを書かなくなったというのも大きいかもしれません。


ま、PHPがベストかということに関しては諸説あるのですが、とりあえずPHPを使うことにして効率は倍増。


ただねえ、PHPのコードを書いてると、やっぱまあ良く知られているように、なんかへんてこな実装とかへんてこな組込み命令とかが目について来て、極力見ないようにしても見えちゃうのがなんとも。


個人的にはRuby1.9のJITに期待しつつも、いきなりPHPからRubyに切り替えたりすると、まあそれがPythonでも同じですけど、混乱すること必至なので、いまは様子見、といった風情です。どのみち、仕事に使う実装言語は僕じゃなくてCTOの水野君が選んでいるので彼なりの美学というか哲学があるらしく、僕が戯れに「Perlがいいんじゃない?」とか水を向けてみても「いやー」と返されてしまいます。


それとは全く別に僕個人が戯れに、もしくは真面目に、なにかのプロトタイプを作ろうとした時に使うべき言語は、たくさんあります。最近は専らJavaScriptでした。なぜなら特別な開発環境がなくてもいきなり作り始めることが出来るから。


NetBookでもJavaScriptだけでかなりのプロトタイプを作りましたね。

開発環境いらずのそういう手軽さがいい。


けど、JavaScriptも一通りやって飽きて来たなあ、と思った時、ふと、「ハッカーと画家」を思い出して「やっぱりLispだろうか」と思う瞬間があったのです。


「ハッカーと画家」はプログラマー起業家のポール・グレアムの著書で、どこを読んでもかなり面白く、説得力があるのですが、全編に漂っているのはとにかく「競争相手に勝ちたければLispを使え」ということ。なんでだよ、と思いつつもなんだか使いたい気にさせられてしまうという説得力のある文章がえんえんと展開されます。

特に川合史郎さんの訳した「普通の奴らの上を行け(Beating the Avengers)」はアジテーションとして秀逸です

私達の技術を一番理解していたのは私達の顧客だった。 お客さんはViawebが何の言語で書かれているかなんて気にしないが、 ソフトがとにかく使えるということに気付いてくれた。 私達のソフトを使えば、見栄えがいいオンラインストアを文字通り数分のうちに 作ることができた。そしてほとんど口コミによって私達は顧客を獲得していった。 1996年の終りまでに、70店程がオンラインストアを実現した。1997年の終りには500店 になった。その6ヵ月後、Yahooが私達の会社を買い取った時、顧客数は1070店になっていた。 こんにち、私達のソフトウェアはYahoo Storeとしてこの領域のマーケットを独占している。 それはYahooの中で最も利益を上げている部分の一つであり、それによって作られたオンラインストアが Yahoo Shoppingの基礎となっている。私は1999年にYahooを離れたので、 現在どのくらいのユーザーがいるのかは知らないが、最後に聞いた時はだいたい14000ということだった。

時々、Yahoo Storeは今でもLispを使っているのかと聞かれる。 答えはイエスだ。Lispコードはそっくりそのまま、まだある。 Yahooはサーバー側のソフトウェアを、 エリック・レイモンドが薦めた5つの言語全てを使って書いている。



普通のやつらの上を行け ---Beating the Averages---

http://practical-scheme.net/trans/beating-the-averages-j.html


まあそれで僕もおくればせながらLispを嗜み程度の遊びではなく、実用的なレベルで使ってみようかなと思ってここ数ヶ月、ちょこちょこと格闘していたわけです。


LispとひとくちにいってもPerlやPHPのように誰かがイニシアチブをとって開発している言語ではなく、ANSIに規定された言語なので処理系もたくさんあります。

Lispの方言のひとつでschemeというのが面白くて便利そうだ、と思って日本人の作った処理系であるGaucheと、そのWebフレームワークであるKahuaを試してみました。


ところがね、Lispの言語としての理解は驚く程簡単なんだけど、いままでの常識と違いすぎてなかなか頭がついていかないのですよ。


ある問題xがあるとして、その問題xを解くための手法yは、手続き型言語のためのものであって関数型言語でそれを特にはyに良く似た手法である手法y'を考えなければならない、とすると、かなり面倒でしょ?実際、ループのやりかたまでぜんぜん違うので、それまでのプログラムの考え方を根本的に見直さないといけない、という先入観に捕われてしまいました。


これに慣れるまで、頭の固い僕はずいぶんと時間がかかったのですが、いま思えばなんて簡単なことに時間をかけてしまったのか、バカバカしくさえ感じます。


これがいかにも古い言語というか、数学者が数学的に書いた言語、みたいな感じでとっつきにくいのですな。

たとえばLispのあらゆる教科書の冒頭にある台詞

Lispのプログラムは全てS式という形式で表されます。

この時点でけっこう絶望する。

なぜなら、他のプログラム言語では式は式であり、文は文だ。それが式ではなく「S式」というわけのわからない記法になっている時点でゲンナリする。

それでも我慢して読むと、次の記述で絶望する。

たとえば通常のプログラム言語で

 1 + 2

と書くところをLispのS式では

(+ 1 2)

と表現します。

「なんでだよ、なんで逆なんだよ。ふざけんな」

そんな気分になってきます。

さらに混乱を極めるのが

このS式の書き方だと、たとえば

 1 + 2 * (4-3)

  (+ 1 (* 2 (- 4 3)))

と書くことができ、この形式はコンパイラが解釈する構文木そのものなので…


などとつづいてしまい、構文木ってなんだよと思うともうそこでアウト。

思わなくても、「なぜこんな簡単な数式をわざわざややこしい方法で書かないと行けないのか」という根本的な疑問を解決出来ず


 「Lispは面倒くさい言語」


という評価で終わってしまう可能性が大です。

これはもうなんていうか、教えかたが悪いと思います。

また、別の教科書だと

Lispではリストを扱うことが出来ます。

リストの先頭要素をcar、それ意外の要素をcdrとして取り出すことが出来ます。

  (car '(1 2 3 4)) → 1

  (cdr '(1 2 3 4)) → 2 3 4


とかいうのが最初に来ていて、このリストの先頭要素がどうのっていう話から、3Dのゲームが作れるところまでどう考えても連続性を感じられない。


僕がヤングの頃はとにかく早く画面にかっこいい宇宙船とかを書きたかったので、リストの要素の先頭だとか後だとかはハッキリ言ってどうでもよろしい。

それで

 「ヤーメタ」

となっていたわけです。

いま思うと、ずいぶん勿体ないことをしたな、と思います。



いまの僕なら、Lispを全く知らない人に説明するときに、こう説明します。

Lispでは、関数とパラメータをカッコでひとまとまりにして表現します。

 (<関数> <パラメータ1> <パラメータ2> ...)

これをS式と言います。
たとえば、"Google"という検索をする関数があったとすると、

 (Google "綾瀬はるか")

で、"綾瀬はるか"という文字列をGoogle検索して見つけ出します。

また、例えば,メール送信する関数 "Mail"があったとすると、検索結果を"jon@moe.com"にメールするには


 (Mail "jon@moe.com" (Google "綾瀬はるか"))


などと書くことが出来ます。

関数"Google"の戻り値がリストでかえってくるとき、最初の検索結果だけを取り出すには"car"関数を使います。

 (car (Google "綾瀬はるか")) 


Google検索で最初にひっかかった項目をメールするには以下のようなS式を書きます。


 (Mail "jon@moe.com" (car (Google "綾瀬はるか")))



これなら、S式の実態としてのイメージもつきやすいし、実際の利用法も想像出来ます。

リストの先頭要素だとか、一見異常な計算式よりもずっとマシだと思うのです。


さて、まあそれはいいとして、Lispの文法自体を覚えるのはこの違和感を乗り越えれば難しくありません。

なにしろ文法が「(関数 パラメータ)」しかないのですから、覚えることは殆どありません。

Lispの入門書の大半の部分はこの「関数」を大量に紹介しているに過ぎません。

でもあくまでそれは「関数」なのですから、必要になったときにマニュアルを探せばいいのです。

次に疑問としてでてくるのは、制御構造はどうなってんだ、ということです。


もちろんLispでは制御構造すらも関数として表現しています。

(追記:と書いたらブコメで「違う!」と指摘されてしまったので以下訂正した内容です)

たとえば条件分岐命令のif文は

(if <条件> <真の時のS式> <偽の時のS式>)

となっています。

具体例を出すと

(if (null? (Google "綾瀬はるか")) (display "見つかりませんでした") (Google "綾瀬はるか"))

みたいな感じです。

※注意

僕もこれを関数だと思ってしまったのだけど、よく考えたら、if文の真の時のS式、偽の時のS式は、それぞれの場合でどちらか一方のみしか実行されないので関数では表現出来ません。つまり「S式であらわされた制御構造」であって「関数」とは違いました。失礼しました。


ということはS式は

 (<関数または命令> <パラメータ1> <パラメータ2> ...)

ということでしょう。

ただ、構成がシンプルなので解りやすいし、制御構造もS式で表現出来るところがナイスなわけです。

また、Lispの場合、マクロという機能を使って制御構造そのものも自分で増やしたり、オブジェクト指向のようなあとから発明された概念を自分で導入したりといったことも可能です。



もちろん、if文の真偽値や条件はS式なので中で入れ子にしたりもっと長くしたりすることもできます。

しいていえばややこしいのはループです。

でも、それも慣れてしまえばなんでもありません。

ここまでやってきて、さあなにかしようかな、と思った時、やっぱりどうしても手続き言語的な発想からなかなか抜け出せないため、「なにか実用的なものを作ろう」というところまで頭が行きません。


それで僕もだいたい、年に一度はLisp処理系をダウンロードしてきてはフィボナッチ数列やらエラトステネスのふるいやら、クイックソートやらを実装して飽きる、という非常に低いレベルで満足していました。


けど、いつのまにかKahuaがちゃんとMac OS Xの10.5ことLeopardで動くようになった(前に試した時にはLeopardでは動作不能だった)ので、再度LispによるWebアプリ開発に挑戦してみようかなという意欲が湧いて来たのです。


ところがKahuaはKahuaで、ドキュメントが多いようで少なく、注目は浴びているようなのに、実際に使っている人をあまり見かけないという状態で、唯一の手がかりはKahua自体のソースとKahuaプロジェクトが書いた「プログラミングGauche」という書籍だけ。

チュートリアルから先に進むことがなかなかできず、往生したのです。

・・・長くなったので続きはまた今度(メモになってない)

2009-06-10

昔の上司がブログを初めて居たってことを良く知らなかった

昨日は安達君とPier39あたりで夕飯を食べていた時に


 「川上さんがはてなーになったのが意外」


みたいな話が出て、


 「え、なにそれ?」


という反応をすると


 「清水さん、タンブラーに反応してたじゃないですか」


 「いや、知らないけど」


 「なんかアイデアを大事にするやつはダメだとかなんとか」


 「ああ、書いたけどね」


 「あれ元記事書いたの川上さんですよ」


 「えーーっ」


 「最近よくブログ書いてますよ」


 「そうなの? でも川上さんがいまのポジションで好き勝手にブログ書いたら人気でちゃいそうだな」


 「それが結構人気なんですよねー」


それでおそるおそる見てみたら、なんか僕の最近の悩み、みたいなことについてズバリ書いてあって、はてな離れすると親不孝になるな、と思った次第です。

なんで、だんだん長文がめんどくさくなってきたので、いろいろ途中の議論を、はしょって書くと、ブログを通じて伝わる自分の経営者の人格のメリット・デメリットを考えるのであれば、shi3z氏はクリエイター気質のプロデューサーを目指すか、経営者をめざすか、(少なくとも自分のブランディングに関しては)、どっちかに決めたほうがいいと思う。まあ、後者はないだろうし、あったとしても今ではないから、ようするに経営者としてふるまわないように見せたほうがいいんじゃないかと僕は思う。人間は嫉妬深いから、クリエイター兼経営者なんてキャラ設定は反感もたれて受け入れてもらえる確率を下げる。もっと、わかりやすいキャラにしたほうがいい。その場合は実績のあるほうをベースにするべきで、経営者のキャラはもっと会社が成功するまで封印したほうがいい。成功を夢見る若手ベンチャー経営者のブログなんてたくさんあるけど、そのタイプのブログでは、青臭いフレッシュさと、滲み出るセンスや頭の良さを感じさせるように手垢のついていない自分の専門分野に関しての深い洞察を書いているぐらいでよくて、一般的な経営論とか語るのは効率が悪い。レベルファイブの日野社長やスマブラの桜井さんが経営論を語っているところなんて見たことはないし(あったらごめんなさい)、そもそも、だれも期待していないと思う。損得を考えるのであれば、みんなが期待する情報やイメージを発信するのを基本とするのが安全だ。

もし、経営者方向にブランディングするんだったら、自分を露出するのではなく、もっと徹底的にだれか社員を決めてプロデュースすべきだと思うけど、shi3z氏との差を埋められる素材はいないんじゃないかなあ。しらないけど。

ネットサービスのブランディングと経営者 - はてなポイント3万を使い切るまで死なない日記

http://d.hatena.ne.jp/kawango/20090508/1241730026

川上さんがこんな長文を書くタイプだとは全く思っていなかったので、予想外のボリュームに腰が抜けそうだったけど、こんな的確なアドバイスというのはを僕は初めて頂きました。


川上さんと僕は、まあ同じ会社にいるときもそんなに沢山話す方ではなかったけど、ときどき僕のブログの内容について話題になったりはするので「まあ読んでるんだろうな」とは思っていた、くらいの認識だったのですが、こんなに深く読み込んで真摯なアドバイスを頂けるとは全く予想もしていなかったので、びっくりです。


これって逆に言うとネットがある時代だからこそ発生した感情または議論の交流と考えることが出来るのかもしれず、なかなか考えさせられるな、と思った次第です。


加えて、川上さんの仰ることは尤もだ、と思ったのでとりあえずプロフィールから「社長」っていう文字を外してみました