メッセージ。 - diary

2006-03-24

# 「プログラミングは難しいよ?」 というお話 その3

ちょっと間があいちゃったけど、「プログラミングは難しいよ?」の続き。
学校の実習でC言語を学ぶことになったふじさわ。「座学よりは実習だ」と、喜び勇んでワークステーションに向かったが……。

ぼくは、お決まりの入門プログラム「Hello World」でつまづいた。画面に「Hello World」と表示するだけのプログラムさえ、ぼくには困難な壁に思えたものだった。たとえばC言語では、たいてい1行目に「#include <stdio.h>」と書く。ぼくはこれの意味を知りたかった。だけど教科書も、、まわりの友達も、それが何かを教えてくれなかった。

「標準なんちゃらだよ」と言う人がいた。「標準ってなんだ?」と思った。
「おまじないだと思えばいいよ」と言われた。「おまじない?」 ぼくは占いの類はしない。
分からないことがあって質問しているのに、質問するごとに分からないことが増える。「もういい加減にしてくれ!」。

分からなさすぎて吐きそうになりながら、とにかくそれを打ち込んでみることにしたが、それも困難だった。
ちょっとした打ち間違いを直そうと「BackSpace」キーを押すたび、よけいなゴミが文章に付け加えられるのだ(矢印キーを押しても同じようにゴミが増えた。ワークステーションの設定がまずかったらしい)。「コンピュータって便利なのか?」

 #include <stdio.h>
 
 int main(void) {
   printf("Hello, World\n");
 
   return 0;
 }


なんとかかんとか、教科書のとおり打ち込んで、言われた手順でこんぱいるし、実行してみる。

$ gcc hello.c
$ ls
a.out
$ a.out
Hello, World

この結果を見て、ぼくはうれしかったというよりも、憤りを感じた。「Hello, World」と手で打つほうが早いじゃないか! しかもプログラミングというものは、意味不明にもほどがある! stdioってなんだ? mainってなんだ? voidってなんだ? printじゃだめなのか? a.outってなんなんだ。

「Hello, World」って、誰が誰にHelloなんですかっ!?
2006-03-24 13:51:09 / ふじさわ / Comment: 10 / Trackback: 0

# チープな機器に精密なコントローラを付ける

 
 ひじょうにチープな電子機器(安そうなデジタル置時計やタイマー、ゲームウォッチのような電子おもちゃ)に、任天堂やATARIなどののテレビゲームハードについているコントローラを、強引に接続しているだけのもの(engadgetの記事によるとちゃんとコントローラとしてハードを操作できるらしい)。ひじょうにバカくさい。のだがしかし、とてもいい、というか、なんかどきどきする。 

「美女と野獣」的な心理があるのかなぁと思った。「ドラえもんとのび太」的というか。非力でローテクなものに感情移入しつつ、それと組み合わされる大きな力に憧れる。「その圧倒的な力に触れたい」という欲望。「こんなことしていいんだろうか」という倒錯。そういう感じを、たとえばぼくだったら感じるような気がする(あまりデバイスに感情移入はしないほうだけど)。

ああ、ちょっと早とちり。「チープな機器に、コントローラを付ける」という話かぁ。だとしたら、ローテクな機器が下位心理レイヤで、コントローラが超自我という感じかもしれない。原始的な「心」をどうやって論理的な自我でコントロールするか、あるいは心はどう抵抗するか、という感じが琴線に触れるのかもしれないなぁ。なんて適当な感想を書いてみる。
2006-03-24 11:55:55 / ふじさわ / Comment: 0 / Trackback: 0

2006-03-23

# SIの問題を整理する!(自分なりに)

結局のところ、「SIはパッケージとかなり違う」というのがふじさわの考えです。

違う要因として、「SIにおいて、顧客が要求するシステムを作るのはかなり難しい」というのがありますかね。要は「仕様がない」ということです。たいていは見切り発車で作るけど(顧客からもOKがもらえるけど)、仕様変更が頻発して「はいデスマーチ一丁上がり」ってなもんです。

これが起こる原因として、
- 顧客自身がどんなものを作りたいかうまく説明できないこと
- 要求が市場や現場にマッチしているか定かではないこと
- 顧客のシステム部が弱くて、現場や上の意見に揺らいでしまうこと
- 組織内部で対立があって矛盾した要求が出てくること
- SIベンダは無理な要求に「No」と言えないこと
などがあると考えてます。このへんは、日経BP社の「動かないコンピュータ」という本も、まぁ参考になります。

パッケージは、究極的には自分が作りたい(作るべきと考える)ものが仕様なわけで、システム的な要件への落とし込みをかなり正確に行えるんじゃないかと思います(あくまで「SIに比べて」ということかもしれませんが)。あとは、パッケージの仕様がどれだけ市場にマッチするかですよね。たぶん。

またパッケージは、SIに比べると要求仕様が明確で、のるかそるか自分で決められるのがよいかなぁと思います。SIは、上記のように要求仕様が後からあとから変わるので、とてもしんどいのです。SI屋は、「そんなに変更されたら、もう作れません」と言えればいいのだけど、言えないんですよね。それがゼネコン体質というやつです。一度断ると次の受注が来なくなるのかもしれないですね。

それで、予算もないのに仕様変更をバンバン受けて、みんなでタダ働きしたり、個人の機材を供出したりしなきゃいけなくなって、それでも赤字でどうしようもなくてってなるんですよね。これはたぶん、特別なことじゃないと思います。一部上場企業でこれでしたから。下請けなんかはもっとひどい労働環境です。お金とか福利厚生とか。

SIの現場にいて感じたのですが、どうもSI業界には厳然たるカースト制度があるような気がします。お客さまは神さまであって、SEやプログラマは単に言われたとおりのものを作ればいいのだと。上司と客先に行ったら、何を言われても頭を下げてばっかりですから。システム屋が顧客に意見するなんてとんでもないと。顧客の言うとおりに作っていればいいと。そして、そういう関係が、重層構造になって下請け孫請けに続いている。

でも、それでいいものが作れるのかなぁと思うわけですよ。現場の人と、時間をかけて肚を割って話し合わないと、よい業務システムの仕様なんてなかなかできないと思うんです。創造的なプロセスを経てこそ、創造的なシステムやモノができるとぼくは考えます。「お客さまは神さまではない。間違うこともあるし、対等に話し合ってこそものづくりができる」。それがぼくのポリシーです。でも、それができているSIの現場は、かなり少ないだろうと思っています。
2006-03-23 18:40:10 / ふじさわ / Comment: 2 / Trackback: 0

# 「WIDE用語集」

WiLiKiで紹介されていたWIDE GLOSSARY WIDE 用語集 by Susumu Sano。ちょっと(読んだけど)面白かった。あとで読む。
2006-03-23 16:59:34 / ふじさわ / Comment: 0 / Trackback: 0

# それでも、ちきゅうは、まわっている

最近はてなブックマーク界隈で活動してるんだけど、分かってもらえないことが多いなぁ。なんでじゃろ。おいらがよっぽど間違ってるんじゃろか。瞬間風速的に、「それでも、ちきゅうは、まわっている」という気分になったり。
まぁ間違ってるなら間違ってるで直しますけど。納得できるならば。可能ならば。ああ、人狼BBSでもこんな感じだったかもしれない。みんな分かってくれなかった。負けがこんだ日々。つらかったなぁ。
2006-03-23 13:38:35 / ふじさわ / Comment: 1 / Trackback: 0

# 青空がある

あれはつまらない、これもつまらない、それはもう駄目だ、どれそれには価値がない、そんなことばっかり言っている人がいる。だけどぼくから見たら、そう言ってる人こそがダントツにつまらない。下を見て生きていると、下のほうに足が向いてしまう。上を見さえすれば青空があるのに。
2006-03-23 01:11:37 / ふじさわ / Comment: 0 / Trackback: 0

2006-03-22

# SIベンダーはゼネコンです

 
 効率のいいプログラムを書いたほうが
 支払われる開発費が少ないなんてこんなプログラマを
 バカにしたようなことを平気でやる企業があるなんて異常だと思います。

この問題の本質は、プログラマの給与を見ても分かります。プログラマの給与形態は、たいてい基本給+残業代です。つまり、「労働時間と生産性の間に正比例の関係がある」という考え方です。また、たいていの企業では、できるプログラマとできないプログラマの間に大きな給与格差がないですが、同じ考え方に基づいています。「できるプログラマとできないプログラマの間で、生産性には大きな開きがない」と。

要は、ソフトウェアベンダーが、ソフトウェアを部品の1つとしか考えておらず、プログラマをライン工としか考えていないということです。ぼくは電機メーカー系のSEをやっていたのでとくにそう思うのかもしれませんが、日本のソフトウェア業界は、旧来の重厚長大産業の論理でビジネスをやっているところが多いのではないかと考えています。そしてそれは、給与やものづくりの仕方だけではなくて、ゼネコンのような多重下請け構造にもつながっているだろうと。
2006-03-22 19:43:26 / ふじさわ / Comment: 0 / Trackback: 0

# 働くことと暮らすこと

 とは、居場所、なのではないだろうか。

 労働組合は「既に雇われている人たち」の組織だから、その人たちの利益になることをまず追求するのは当然といえば当然だが、春闘とやらで気勢を上げる前に、もう少し社会的公正ってやつに気を配ってはもらえないか。「弱者の見方」を自称するなら、賃上げよりもまず雇用機会の拡大をめざすべきではないか。

  新規採用者は現在の組合員ではないので、新規採用ストップに反対する組合員はだれもいないのではないか。正規社員を採用するために賃金カットを受け入れ てくれと組合員を説得することはなかなか難しいことだろう。結局、どの企業でも(B案)の採用抑制とパートへの置き換えによる人件費カットを選ぶことになる。
 
  しかし、企業にとって望ましいのは、賃金カットをして正社員の新規採用を続けることである。

 今週のエコノミスト誌には、「娘、息子の悲惨な職場」というタイトルが出ています。このシリーズも4回目ですから、反響が大きいのでしょう。30歳前後の厳しい雇用の現実が描かれている。いまは、正社員として働こうと思えば、長いサービス残業などに耐えなくてはならず、かといって働いた時間どおりの賃金を受けたいと思えば、フリーターやアルバイターという立場に甘んじなければならない人が多いんですね。この厳しさの原因は、何か?

こういう意見を言ってくれる人がいるのはうれしい。
ぼくなんかが付け加えて言えることはないけど、個人的には、いまよりもっとお年寄にインセンティブがあればいいなぁと考えている。お金じゃなくて、小飼さんの言う居場所みたいなものが。

彼らにだってできることがあるし、彼らにしかできないことがある。いまの日本の社会は、お年寄の価値を単に捨ててしまっている。それはとても非合理的なことだし、悲しいことだと思う。お年寄だって、働きたいはず。なにかの役に立っていると実感したいはずだ。
2006-03-22 08:17:25 / ふじさわ / Comment: 0 / Trackback: 0

2006-03-21

# OSC2006に参加した感想をちょろっと

OSC2006に参加した感想をちょろっと書こうかなっと。結論から言うと、予想以上に面白かったですよ。行ってみるまでは不安でしたけどね。「お客さん来てくれるかな?」とか「楽しんでもらうべき核たる内容はなんだろう?」とか。

でも、実際その場に行ってみると杞憂で。個人的には、Wiki世界の外にいる人と直接話せたのが大きかったですね。Wikiばなに参加するほどではないけど、キーワードとしては知っているぐらいの人。そういう人たちから生の声を聞けたのは大きいかなと思うんですよね。雑談ばっかりしてたので、具体的な成果があるわけじゃないですけど。

たとえば、「会社でWikiを使いたいけど、パソコンにソフトウェアをインストールするのは禁止されている」という人がいました。「どうすればいいですか?」と言われて、「あーなるほどねー。あーするのはどうだろう、こんな手は使えないかな」と話すのは結構楽しかったです。いままで気づいていなかった需要を見たような気がして。

あとは、「趣味でホームページを作りはじめたところなんですけど……」というご婦人とも会話しました。「Wikiっていうのは誰でも編集できるWebサイトツールです。掲示板を設置する感覚で使えます」みたいな感じで説明してね。「そういう説明で分かってもらえるか? 興味を持ってもらえるか?」というのは、やっぱりやってみないと分からないので有意義でした。普段そういう方とお会いすることはあまりないので。

ほかにも、けっこういろんな人が見ていってくださいました。ブースの前に座って雑談・立ち読みなんて、お客さんに訴求するか不安だったんですが、それを覆す感触を得られました。また、少しではありますが、Wikiばなのことを知ってもらえたと思います。「お話しできて良かったです」と言ってくださる人もいて、Wikiばならしい、手作りと雑談の良さを確認できるものになったと思います。もちろん、反省と改善をすべきところは、まだまだあるでしょうけどね。
2006-03-21 18:34:56 / ふじさわ / Comment: 0 / Trackback: 0

# 本当にとりとめのない話

昨日はインドカレー屋さんでカレーを食べたよ。すごく慣れなれしい店員さんがいて面白いお店。「ピッピッピッのピッと。4000円いただいてもよろしいですかたまには?」。「たまには?」。息をするように冗談を言われて、こちらは咄嗟に返事を返せない。インドの人なんだけど、すごいね。日本語が上手なだけじゃない。人間として懐の深さを感じさせられる。

それでね。そのお店でインドの音楽DVDみたいなのが流れてて、ちょっと感じるところがあったんだ。どうもインド人はダンスが好きみたいで、そのDVDもダンスミュージックのようだった。若い男の人と女の人が、さまざまなシチュエーションで歌っていく構成。ストーリー仕立てになっていて、ちょうどカラオケのバックで流れる映像みたいな感じと言ったらいいかな?

そのなかの1シーン。若い男女が田舎道をバスに揺られたり、畑の脇道を歩いたりしながら旅をしているみたいだった。その旅の間中、二人でずっと歌っていて、なんとも楽しそう。バスの乗客や畑で働く娘さんたちも効果的に使われていてほのぼのムードなんだよね。ぼくは流行り音楽やダンスが苦手なほうだけど、そのDVDはけっこう楽しめた。それでね、思ったんだ。日本の映像とはちょっと違うなって。

日本の映像には、あんな風に農作業をする娘さんが出てこない。バスに揺られる田舎道の乗客たちが、音楽のバックで使われるのもあまり見ない。日本の映像は、生活というものを肯定的に描いていない気がした。テレビドラマも、ニュースも、CMも、ただひたすら無機質な素材ばかり使っていて、生活の存在が感じられないように思う。漁師さんとか、農家の人とか、いまでも日本にいるのかなぁと、ぼくなんかは考えてしまう。

毎日食べるご飯は、どこかで誰かが作ってるはずなのに、そういうものがさっぱり分からない。ご飯だけじゃなくて、身の周りのいろんなもの、いろんな人の暮らしがまったくぼくには想像できない。それがなんか、つまらないなぁと。たとえばぼくと同い年ぐらいの人が、農家として野菜を作ってたり、田舎のサラリーマンをやってたり、政治家の卵や工場の工員として働いてたりするはずで。彼らはぼくだったかもしれないし、ぼくは彼らだったかもしれない。

なんとなく、そういう彼らの暮らしを知りたい。自分が今暮らすところだけじゃなくて、誰かが暮らす土地にも何かがあると知りたい。生活というものは、もっと肯定的に捉えられるような気がする。そしてそれらはいま、路傍の石として放っておかれているような気がする。
2006-03-21 17:32:51 / ふじさわ / Comment: 8 / Trackback: 0

# ものづくりと生活

 
 褒められることを目的にしている者はartistではないのだ

小飼さんとは気が合わないときも多いのだけど、これは同感だなぁ(まったくの蛇足だけど、小飼さんのブログは、「Dan the ○○」というやつが自意識、褒められ目的を感じさせるのであまり楽しめない。この結句はないほうがいいんじゃないだろうか……。<余計なお世話)。shiroさんのコメントも、考えさせられるものがあったのでメモ。

 「芸術は、ちょうど毎日の食べものと同じように、人間の生命にとって欠くことのできない、絶対的な必要物、むしろ生きることそのものだと思います。しかし、なにかそうでないように扱われている。そこに現代的な錯誤、ゆがみがあり、そこから今日の生活の空しさ、そしてそれをまた反映した今日の芸術の空虚も出てくるのです。」 (岡本太郎、「今日の芸術」、1954)
 
 50年以上経ってもなお、芸術と生活の解離、あるいは文化の生産者と消費者の解離は縮まらないどころか大きくなっているようです。表現の専門家が創ったものをそうでない者が消費するという構図にあまりに慣らされてしまったために、せっかくネットという表現媒体を手にしても、消費されることを目的としてしか表現できなくなってしまった人も多いように見受けられます。
2006-03-21 16:21:45 / ふじさわ / Comment: 1 / Trackback: 0

2006-03-19

# Momokaのソースコード、お見せするの恥ずかしいですけど

昨日、hirofummyさんが興味を示してくださったので、現状のMomokaのソースコードを公開します。http://nnri.dip.jp/~yf/source/Momoka-0.36.tar.gzhttp://nnri.dip.jp/~yf/source/Momoka-0.35.tar.gz(えーと。まともそうなほうを持ってってくださいm(_ _)m)

一応動くコードなんですが、データがない状態ではテストしてないので、たぶんまだインストールしてもうまく動かないです。コード眺め用ということで、お願いします。あと、main関数に近いところを中心に、コードが汚ないのもご容赦を。動きがありそうなところは、あとでリファクタリングするつもりでした。

パーサ部分はこんな感じです。けっこう手抜きです。

(define-module momoka.kcdp3
  (use srfi-13)  ;; string-prefix?
  (use text.html-lite)
  (export text->kcdp kcdp->html kcdp->text kcdp->t))

(select-module momoka.kcdp3)

(define (with-lines lines proc)
  (string-join (map proc lines) ""))

(define (div istring divider)
  (map (lambda (e) (string-trim-both e)) (string-split istring divider)))

(define (getlines lines pattern)
  (let1 plen (string-length pattern)
    (let loop ((lines lines) (out '()))
      (if (null? lines)
          (values (reverse out) lines)
          (if (string-prefix? pattern (car lines))
              (loop (cdr lines) (cons (string-drop (car lines) plen) out))
              (values (reverse out) lines))))))

(define (text->kcdp istring)
  (let loop ((lines (string-split istring "\n"))
             (out   '()))
    (if (null? lines)
        (reverse out)
        (let1 line1 (car lines)
          (cond ((string-prefix? "*" line1)
                 (loop (cdr lines)
                       (cons (cons 'caption (string-drop line1 1)) out)))
                ((string-prefix? "-" line1)
                 (receive (lis remain) (getlines lines "-")
                   (loop remain
                         (cons (cons 'list lis) out))))
                ((string-prefix? ">" line1)
                 (receive (lis remain) (getlines lines ">")
                   (loop remain
                         (cons (cons 'quote lis) out))))
                ((string-prefix? "|" line1)
                 (receive (lis remain) (getlines lines "|")
                   (loop remain
                         (cons (cons 'table
                                     (cons "|"
                                           (map (lambda (e) (div e "|")) lis)))
                               out))))
                ((string-prefix? "," line1)
                 (receive (lis remain) (getlines lines ",")
                   (loop remain
                         (cons (cons 'table
                                     (cons ","
                                           (map (lambda (e) (div e ",")) lis)))
                               out))))
                (else (loop (cdr lines) (cons (cons 'plain line1) out))))))))

;; (define ecapt (lambda (e) #`"*,|e|"))
;; (define equot (lambda (e) #`">,|e|"))
;; (define elist (lambda (e)
;;                  (with-lines e (lambda (f) #`",|f|\n"))))
;; (define eelse values)

(define (pp-table obj)
  (define (add-pad istring len)
    (string-append istring (make-string (- len (string-size istring)) #\ )))
  (let* ((div  (car obj))
         (body (cdr obj)))
    (let1 nums
        (let loop ((body body) (nums '()))
          (if (null? body)
              nums
              (loop (cdr body)
                    (let l2 ((record (car body)) (nums nums) (out '()))
                      (cond ((null? record)
                             (reverse (append (reverse nums) out)))
                            ((null? nums)
                             (l2 (cdr record)
                                 nums
                                 (cons (string-size (car record)) out)))
                            (else
                             (l2 (cdr record)
                                 (cdr nums)
                                 (cons (max (string-size (car record))
                                            (car nums))
                                       out))))))))
      (string-join
       (map (lambda (r)
              (string-append
               #`",|div| "
               (string-join
                (let loop ((b r) (nums nums) (out '()))
                  (if (null? b)
                      (reverse out)
                      (loop (cdr b)
                            (cdr nums)
                            (cons (add-pad (car b) (car nums)) out))))
                #`" ,|div| ")))
            body)
       "\n"))))

(define (kcdp->t kcdp . opts)
  (let-keywords* opts ((ecapt :capt  (lambda (e) #`"*,|e|"))
                       (equot :quote (lambda (e)
                                       (with-lines e
                                                   (lambda (f) #`">,|f|"))))
                       (elist :list  (lambda (e)
                                       (with-lines e
                                                   (lambda (f) #`"-,|f|\n"))))
                       (etabl :table (lambda (e) (pp-table e)))
                       (eelse  :else  values))
    (string-join
     (let loop ((kcdp kcdp) (out '()))
       (if (null? kcdp)
           (reverse out)
           (let1 kcdpe (car kcdp)
             (cond ((equal? (car kcdpe) 'caption)
                    (loop (cdr kcdp) (cons (ecapt (cdr kcdpe)) out)))
                   ((equal? (car kcdpe) 'list)
                    (loop (cdr kcdp) (cons (elist (cdr kcdpe)) out)))
                   ((equal? (car kcdpe) 'quote)
                    (loop (cdr kcdp) (cons (equot (cdr kcdpe)) out)))
                   ((equal? (car kcdpe) 'table)
                    (loop (cdr kcdp) (cons (etabl (cdr kcdpe)) out)))
                   (else (loop (cdr kcdp) (cons (eelse (cdr kcdpe)) out)))))))
     "\n")))

(define (kcdp->html kcdp linep)
  (kcdp->t kcdp
           :capt  (lambda (e)
                    (format #f "<h3><span class=\"title\">*~a</span></h3>"
                            (linep e)))
           :list  (lambda (e)
                    (format #f "<ul>~a</ul>"
                            (string-join
                             (map (lambda (f) #`"<li>,(linep f)</li>") e)
                             "\n")))
           :quote (lambda (e)
                    (format #f "<blockquote class=\"quote\">~a</blockquote>"
                            (string-join
                             (map (lambda (f)
                                    #`">,(linep f)") e)
                             "<br />\n")))
           :table (lambda (e)
                    (format
                     #f "<table class=\"wiki-table\">~a</table>"
                     (string-join
                      (cons
                       (format #f "<tr class=\"wiki-tr\">~a</tr>\n"
                               (string-join
                                (map (lambda (f) #`"<th class=\"wiki-th\">,(linep f)</th>")
                                     (cadr e))
                                ""))
                       (map (lambda (line)
                              (format
                               #f "<tr class=\"wiki-tr\">~a</tr>\n"
                               (string-join
                                (map (lambda (f) #`"<td class=\"wiki-td\">,(linep f)</td>")
                                     line)
                                "")))
                            (cddr e)))
                      "")))
           :else  (lambda (e) (format #f "~a<br />" (linep e)))))

(define (kcdp->text kcdp linep)
  (kcdp->t kcdp))

(provide "momoka/kcdp3")
2006-03-19 09:53:50 / ふじさわ / Comment: 1 / Trackback: 0
recent days<< | >>old days