トップ 最新 追記

じじぃの日記、ツッコミ可

Twitter: @jijixi_org
Xbox Live: jijixi

初心者が書いた OCaml 入門
Spotlight tips サイト内リンク集
1970|01|02|
2003|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|11|
2011|05|
2012|01|

2007-02-01 [長年日記]

% [clip] バベル案内

via reddit.

おもしろすぎる。 引用したくなる文がたくさんあるんだけど、やってるとキリがなくなるからやめとく。

% [Smalltalk] 今日の言語というか処理系 GNU Smalltalk

某所のコメントより。

何度も何度も、な・ん・ど・も、Smalltalk をいじってみたくて Squeak を入れてはみるものの、いつもあの "もっさり" っぷりにぐったりして挫折するわしには、きっとこういうのが必要だったんだと思うよ。うん。

わしの Mac でも特に問題なくビルドできたんで、これからちまちまいじってみる予定。 っていうか、全然文法とか憶えてないや。 何か書く前に挫折してばっかだから(苦笑

まずは入門文書からか。どっかブックマークしてあったっけなあ?

本日のツッコミ(全2件) [ツッコミを入れる]

% sumim [お邪魔します。なにか疑問な点があったら「ここがよくわかんねー」って気軽に書いてみてください。Smalltalk は、..]

% jijixi [どうもありがとうございます。 何かわからないことがあればたぶんグチりますんで、よろしくお願いします(笑]


2007-02-02 [長年日記]

% [Smalltalk] とりあえず Smalltalk で最初にびっくりすべきところ

% rlwrap gst
GNU Smalltalk ready

st> 2 * 4 + 1!
9
st> 1 + 4 * 2!
10

な、なんだってー!?

要は演算子だろうが何だろうが全部メッセージで、優先順位とかは特別扱いしないよ…ってことなんだろうけど、知らないとビビるよ、これ。 ある意味 LISP に近いかも。 優先順位関係無しに、先に計算されるべきところはカッコで囲まざるを得ないところが。 まあ、算数へのこだわりが無ければ、こっちの方があいまいさが無くて嬉しいという見方もできるけど。

……実はわし、結構こういう状況でかけ算のところをカッコで囲みたくなるタイプなのよね。 「えーと、まずかけ算が先で…」とか考えるのがめんどくさいっつーか(苦笑)。 さすがに恥ずかしさがあって、結局カッコは付けないんだけど。

ちなみに上記の例における "!" は Smalltalk の文法的には必要の無いもののはずで、GNU Smalltalk の対話環境で「ここまで入力したものを評価しろ」という合図でしかない。 OCaml で言うところの ";;" みたいなもんか。

% [Smalltalk][Scheme][Dylan] 所詮、関数型言語とかオブジェクト指向言語なんて何を基準に抽象化するか (しやすくチューニングされてるか) の違いしか無いのさ (極論)

やー、なんかメッセージ式がカッコの無い LISP に見えるというか何というか。

% cat add.scm
(define (f . args)
  (let-keywords* args ((x 0)
                       (y 0))
                 (+ x y)))

(print (f :x 1 :y 2))
% gosh add.scm
3

こんなのがあるとして、

% cat add.st
Object subclass: #F
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: nil.

! F class methodsFor: 'adder' !
x: arg1 y: arg2
   ^(arg1 + arg2)
!!

(F x:1 y:2) printNl.
% gst add.st
3

同じじゃね? まあネタだけど。

それはそれとして、メソッド定義のときの "!" の使い方がイマイチしっくり来ない。 なんつーか、どこで必要でどこで必要無いのかがよくわからんというか。 とりあえず、適当に試してみた感じだと、F class に methodsFor を送ってる前後にはどうしても必要っぽい。 あとメソッド定義の後の二個も (これが特によくわからん)。 ともあれ、よくわからんので、そういうもんだと憶えてしまうしかないのかも。

ちなみにおまけで Dylan バージョン。

% cat add.dylan
module: add

define function f(#key x, y)
   x + y
end;

define function main(name, arguments)
   format-out("%d\n", f(x:1, y:2));
   exit-application(0);
end function main;

// Invoke our main() function.
main(application-name(), application-arguments());
% ./add
3

Dylan のキーワード引数の扱いはステキすぎると思う。 特にキーワードが :x じゃなく x: なところがポイント。 オプショナル引数だけじゃなく、必須引数にもキーワード付けられるし。 OCaml のラベル引数みたいに変なゴミ (~) 付けなくて良いし。

% [Smalltalk] 新しい言語を触るとき、ついつい調べてしまうこと

それは末尾再帰が最適化されるかどうか。(ちょっと病気です)

% cat tail_recursion.st
!Object methodsFor: 'tail recursion test'!
f: aNum
   (aNum <= 0)
      ifTrue:  [ ^ 'end.' printNl ].
   self f: (aNum - 1)
!!

|o|
o := Object new.
o f: 100000
% gst tail_recursion.st
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
'end.'

うーん、なんじゃこりゃ。 メソッド呼び出しにスタック使ってないってこと? それとも単にスタックがデカイだけか? ちなみに再帰の回数を 1,000,000 にすると、

% gst tail_recursion.st
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... done, heap grown"
"Global garbage collection... %

GC に失敗したらしくて、変なとこで止まった。 でも、そもそもあのコードでヒープフルってことは末尾再帰は最適化されてない気がするんだけど、スタックのサイズに上限が無いってことなのかね。

% [Smalltalk] コードブロック

要するに Ruby の Proc オブジェクトかな?

st> !Object methodsFor: 'test'!
Object
st> adder: x
st>   ^ [ :y | x + y ]
st> !!
st> Smalltalk at:#obj put:(Object new)!
Object new "<0x2036c78>"
st> Smalltalk at:#f put:(obj adder: 1)!
BlockClosure new "<0x20371a0>"
st> f value:2 !
3
st> [:x :y | x + y] value: 3 value: 4 !
7

なんか value: メッセージの使い方を見ると、一つ目を使った時点で部分適用されたブロックが返ってきてるような気もするんだけど…

st> [:x :y | x + y] value: 3 !
Object: BlockClosure new "<0x2037d40>" error: wrong number of arguments
SystemExceptions.WrongArgumentCount(Exception)>>#signal
SystemExceptions.WrongArgumentCount class(Exception class)>>#signal
BlockClosure>>#value:
UndefinedObject>>#executeStatements
nil

そういうわけではないようだ。ちょっと残念。 ここで使っている Smalltalk というのはシステムワイドな辞書で、こいつにシンボル (頭に # が付いてるのがそう) をキーに値を登録してやることでグローバル変数みたいな使い方ができるみたい。

メソッドに特定の値を返させたい場合は "^" を使って指定する。 逆に言うと、^ を使わないと自動的に self が返るようになってる。 なんか Python っぽい (Python で返ってくるのは None だけど)。

それはそれとして、やっぱ Ruby に似てるなあと思うね。 字面は結構違うけど、やってることは Ruby そっくり。

% irb
irb(main):001:0> class Object
irb(main):002:1>   def adder(x)
irb(main):003:2>     Proc.new {|y| x + y}
irb(main):004:2>   end
irb(main):005:1> end
=> nil
irb(main):006:0> obj = Object.new
=> #<Object:0x5cbc0>
irb(main):007:0> f = obj.adder(1)
=> #<Proc:0x000600cc@(irb):3>
irb(main):008:0> f.call(2)
=> 3

ね。 sumim さんとこでも結構 Smalltalk で書いて Ruby に直訳ってことをやってるけど、なんかすごく納得って感じ。 逆に Objective-C なんかは字面は結構似てる (メッセージ式なんかは、わりとまんまだ) けど、同じようなことやろうとするとかなり違った感じになるはず。 コードブロックにあたるものが無いし (メッセージ式に角括弧使ってる時点でコードブロックを採用する気が無かったのがバレバレ)。 そういや Objective-C 2.0 でクロージャがサポートされるとかって話はどうなったんだっけな?

% [Smalltalk] 配列は 1-origin

これは気を付けないと。 まあ、イテレータがあるからインデックスに気をつける場面って少なそうではあるが。

st> #(1 2 3 4 5) at:1!
1
st> #(1 2 3 4 5) at:5!
5
st> #(1 2 3 4 5) at:0!
Object: Array new: 5 "<0x2043f18>" error: Invalid index 0: index out of range
SystemExceptions.IndexOutOfRange(Exception)>>#signal
SystemExceptions.IndexOutOfRange class>>#signalOn:withIndex:
Array(Object)>>#checkIndexableBounds:
Array(Object)>>#at:
UndefinedObject>>#executeStatements
nil

% [Smalltalk][雑談] 先生、どうしても printNl を println って書いてしまいます

たくさんの言語に手当たり次第手を出すことの弊害がここに(笑

つーか println って何の言語だっけ。Java か? System.out.println か。

OCaml は print_endline だな。これは忘れないぞ。 Haskell は putStrLn だっけ。 Ruby は puts か? まあ p を使っちゃうこと多いけど。 Python は print、Scheme も print か? Scala は Java の影響か Console.println だな。 Nemerle はまんま .Net だから System.Console.WriteLine とか。 Erlang にはたしか改行付きの出力は無かった気がする。

なんかすごくどうでもいー豆知識を披露してしまった……

% [Smalltalk][Python] セミコロンの扱い

なんかごちゃごちゃ色んなページ見ながらやってたら、どこに書いてあったのかわかんなくなっちゃったんだけど、Smalltalk におけるセミコロンって単なる式の区切りじゃないんだね。

st> !Object methodsFor: ''!
Object
st> add: x and: y
st>   ^ x + y
st> !!
st> Smalltalk at:#obj put:(Object new)!
Object new "<0x2038cf0>"
st> obj add: 1 and: 2!
3
st> (obj add: 1 and: 2) printNl!
3
3
st> obj add: 1 and: 2; printNl!
an Object
Object new "<0x2038cf0>"

要するに、セミコロンの前で使われてるのと同じレシーバーにメッセージを投げるという動作をするらしい。

これだ。Python に今必要なのはこれですよ。 どんな記号使うかは別として、同じオブジェクトに連続してメッセージを送る文法があれば、いちいち None を返されて悲しい思いをすることもなくなるよ。 例えば $ を使うとして、

ary = [1,2,3,4]
ary.append(5); $.append(6)

こんなとかさ。 あー、でも生粋の Pythonista からはブーイングが出そうかもなー。 わしは結構欲しいけど。 記号は $ じゃない方が良いかな。$ だと Perl を思い出すから(爆

% [Smalltalk] 文法は最初にここを見るべきだった...orz

ここ→ A Simple Overview of Smalltalk Syntax.

% [Smalltalk] Class reference とか見ながら模索、Namespace 編

Namespace とか RootNamespace とか見つつ。

st> Namespace current name !
#Smalltalk
st> Smalltalk addSubspace: #Hoge !
Namespace new: 32 "<0x20369e0>"
st> Namespace current: Hoge !
Namespace
st> Object subclass: #Fuga
st>   instanceVariableNames: ''
st>   classVariableNames: ''
st>   poolDictionaries: ''
st>   category: nil
st> !
Fuga
st> Fuga new printNl !
a Fuga
Fuga new "<0x2038338>"
st> Namespace current: Smalltalk !
Namespace
st> Fuga new printNl !
stdin:12: undefined variable Fuga referenced
st> #{Hoge.Fuga} value new printNl !
a Fuga
Fuga new "<0x2039ae0>"
  1. Smalltalk というのがグローバルなネームスペースで、
  2. そこに Hoge という名前のサブネームスペースを作って、
  3. カレントネームスペースを Hoge に切り替えて、
  4. Fuga というクラスを作って、
  5. カレントが Hoge のときは単に Fuga でアクセスできて、
  6. カレントを Smalltalk に切り替えると単に Fuga ではアクセスできなくて、
  7. #{Hoge.Fuga} value で Hoge ネームスペース上の Fuga にアクセスできた

というような流れ。#{Hoge.Fuga} value というのは、さっきの文法のページに載ってた binding 式とかいうもの。 こうじゃなくて↓のようにも書けるが、ネームスペースのネストが深くなると、たぶん binding 式の方が簡潔に書ける。

st> (Hoge at: #Fuga) new printNl !
a Fuga
Fuga new "<0x203b090>"

漠然と、この Namespace って仕組みは Gauche のモジュールに似てるかなという気がする。 基本的に親ネームスペースの環境を引き継ぐので、上書きしないかぎり親と同じものが見えるとか (上の例で言えば Object を何も考えずに使えてるあたりがそう)、カレントネームスペースを切り替えられるとか。

% [Smalltalk] category って何のためにあるんだろ?

正直さっぱりわからない。 クラスオブジェクトに category ってメッセージを送るとそのクラスのカテゴリが返ってくるんだけど、だから何? って感じだし。 一瞬 Objective-C のカテゴリを思い浮かべたけど、全然違うものっぽい。

まあ、comment メッセージなんてのもあるし、単にクラスブラウザとかで見るときに分類に使われるとかその程度なのかもしれないが……

本日のツッコミ(全4件) [ツッコミを入れる]

Before...

% jijixi [こんな使い方全然知らなかったです(苦笑 うまく使えばキレイなコードが書けそうな気がしますね。]

% sumim [カテゴリーには、クラスを整理するためのクラスカテゴリーと、メソッドを整理するためのメッセージカテゴリがあります(後者..]

% jijixi [なるほど。 いずれ Squeak をいじったりすることもあるかも知れないので、そのときのために憶えておくことにします..]


2007-02-03 [長年日記]

% [clip] 力こそパワー! のガイドライン (日刊スレッドガイド)

一個一個では大したことないんだけど、淡々と羅列されてることで破壊力が増している。 ただ、カーネル大佐が出てないのが残念だな。

% [Smalltalk] シンプルイズベスト

いやー、Smalltalk の仕様ってすごくシンプルだねえ。 結局初学者がつまづくところって、あのメッセージ式の見慣れなさとか、制御構造がメッセージで表現されてるとか、オブジェクト指向の仕組みが C++ 的なのとかなり違うとか、そういうところなんだろうな。 幸いわしの場合は、Ruby に慣れてるし、Objective-C をいじったことあるおかげでメッセージ式も見慣れてるし、心理的なバリアが少なかったわけで。 こうなると逆に Ruby ユーザがハマりがちな罠がまとまってるページとかあると嬉しいんだが。

まあ、あとは Smalltalk で何かを書こうと思ったら、どんなライブラリがあるかを把握していくのが肝なんだろう。 なんかクラス構成が Ruby なんか比較にならないくらい細かいんで、結構大変そうなんだけど。 つーかサブセットである GNU Smalltalk ですらこれなら、フルセットな Squeak とか VisualWorks なんかいじろうと思ったらどうなるんだ? と心配になるな(苦笑

ともあれそれなりに Smalltalk のコードを読めるようにはなったつもりなので、sumim さんとこの過去記事を (Smalltalk 読めないからスルーしてたのとか、たくさんあるんで) 読み漁ろうと思ったら、今日は朝からはてながメンテ中で出足を挫かれたのであった...orz

% [雑談] プリングルス シーソルト&ペッパー

うまいんだけど、しょっぱすぎる。 飲み物無いと食えんわ。

ちなみに一緒に買ってきた、チョコかっぱえびせんは歴史に残る微妙さだったな。 なんというか、柿の種チョコと同類の微妙さ。

% [Smalltalk] コレクション関係

うーむ、Array は固定長なのか。 Ruby の Array みたいな感覚で使えるのってどれだ? OrderedCollection がそれっぽいか?

st> Smalltalk at:#tmp put:nil!
nil
st> tmp := OrderedCollection new!
OrderedCollection new: 16 "<0x20369f0>"
st> tmp size!
0
st> tmp add:'hoge'!
'hoge'
st> tmp add:'fuga'!
'fuga'
st> tmp do:[:x| x printNl]!
'hoge'
'fuga'
OrderedCollection new: 16 "<0x20369f0>"
st> tmp at:1!
'hoge'
st> tmp at:2!
'fuga'
st> tmp at:3!
Object: OrderedCollection new: 16 "<0x20369f0>" error: Invalid index 3: index out of range
SystemExceptions.IndexOutOfRange(Exception)>>#signal
SystemExceptions.IndexOutOfRange class>>#signalOn:withIndex:
OrderedCollection>>#at:
UndefinedObject>>#executeStatements
nil

うみゅぅ…… Ruby 的感覚だと、そこは何事もなく nil が返ってきてほしいが。

st> tmp at:4 put:'foo'!
Object: OrderedCollection new: 16 "<0x20369f0>" error: Invalid index 4: index out of range
SystemExceptions.IndexOutOfRange(Exception)>>#signal
SystemExceptions.IndexOutOfRange class>>#signalOn:withIndex:
OrderedCollection>>#at:put:
UndefinedObject>>#executeStatements
nil

あー、これもダメか。 Ruby の Array というよりは Python の list に近いのかな。 Ruby の添字に対する適当さが結構好きなんだけど、まあそこら辺はいろいろトレードオフなところもあるし……

Collection (Array や OrderedCollection の大元) には , という二項メッセージがあって、Collection 同士の連結に使える。 これは良いね。

st> tmp inspect!
An instance of OrderedCollection
  firstIndex: 8
  lastIndex: 9
  contents: [
    [1]: 'hoge'
    [2]: 'fuga'
  ]
OrderedCollection new: 16 "<0x20369f0>"
st> (tmp , #(1 2 3 4)) inspect!
An instance of OrderedCollection
  firstIndex: 3
  lastIndex: 8
  contents: [
    [1]: 'hoge'
    [2]: 'fuga'
    [3]: 1
    [4]: 2
    [5]: 3
    [6]: 4
  ]
OrderedCollection new: 10 "<0x203bd10>"

他に便利そうなのは SortedCollection とかかな。 Ruby のコレクション構造って Array 一つしか無いから、たまーに不満に思うこともあるよね。 まあ一つしか無いからこそ、迷わずそれを選べるというシンプルさがあるのも事実だけど、Array.new のときに構造を切り替えたりできると嬉しいんじゃないかなーとか思ったりもする。

あと、Link とか LinkedList とかってのがあるけど、イマイチ使い方がわかんない。 各ノードに値を持たせる操作が無いみたいなんだよな。 生で使わずにサブクラス作るべきなのか?

他には、Dictionary とかのスーパークラスで HashedCollection てのがあるけど、それとは別に MappedColection てのがあるのが意味不明。 何がどう違うんだろ。

% [雑談][Ruby] ちょっと嘘書いてしまった

コレクション構造が Array しか無いって嘘やんね。Hash もあるやん。

ただまあ、あそこで言いたかったのは要するに常に整列済みなのが欲しいときもあるよ…とか、特定のシチュエーションで速くなるような構造になってて欲しいときもあるよ…とか、そういうことであって、そういうときに別に Hash が代替になるわけじゃないのでね。

% [Smalltalk] 例外処理

こいつも一環してメッセージで。 ほんと徹底してるわ。

st> [ 1 / 0 ] on:ZeroDivide do:[:e| e inspect].!
An instance of ZeroDivide
  exception: a CoreException
  arguments: ()
  tag: an Object
  messageText: 'The program attempted to divide a number by zero'
  resumeBlock: a BlockClosure
  onDoBlock: a BlockClosure
  handlerBlock: a BlockClosure
  context: BlockClosure>>#on:do:
  isNested: nil
  previousState: 0
  creator: 1
  dividend: 1
ZeroDivide new "<0x203e5d0>"

この例では最初のブロックの中で 0 除算をしていて、それを BlockClosure#on:do: というメッセージで処理してる。 ZeroDivide は 0 除算をしたときに起こる例外。

調べた限りだと、例外が起こらなかった時の処理とか (ensure: ってのはあるけど、それだと今度は例外をキャッチできないし)、どっちでも必ずさせたい処理とか (finally に類するものは無いみたい) ができないのがちょっと残念。 そういうのが無いと処理の順番とか考えるのがめんどいんだよな……

例外を起こすときは例外クラスに signal メッセージを送る。 new してインスタンスに signal でも良いが。

st> Exception signal!
Object: nil error: An exception has occurred
Exception>>#signal
Exception class>>#signal
UndefinedObject>>#executeStatements
nil
st> [ Exception signal:'test' ] on:Exception do:[:e| e messageText ].!
'test'

% [Smalltalk] インスタンスメソッドの表記

むむ、Ruby で Class#method と書くような場合、Smalltalk では Class>>#method と書くのがお作法のようだな。 気をつけよう。

% [Smalltalk] やっぱ Smalltalk をほんとの意味で味わうには Squeak なり VisualWorks なりをいじらなきゃダメかもしれない

やっとはてなのメンテが終わったので、sumim さんとこをぺらぺらめくりつつ眺める。 で、ハローワールドはどう書くべきかという記事で、

ここで“文字が入力できれば場所ならどこでも”というのはある意味、ミソで、ワークスペースはもちろん、エディタ、入力欄、果てはドロー系テキストオブジェクトまで該当します。たとえば、Squeak の Morphic という現行の GUI フレームワークでは、メニュー項目を shift クリックするとテキストとして選択できる(余談ですが、この状態でコピーして持ち出せるので、チュートリアルを書くときなどには重宝する機能です…)ので、ここにペーストしての評価も可能です。

あーもー、アホか (褒めてます)。 ほんとどーかしてるよな (良い意味で)。

やっぱこういう (良い意味での) アホさ加減を味わうためには、もっさりしてるとかそういうちゃちな理由で敬遠するのは良くないと思った。 そーだよなー、もっさりが何だってんだ。 お前は Mac OS X Public Beta のことを忘れたのか? 10.0 の頃を忘れたのか? 初期の Mac OS X はこんな今みたいな快適な環境じゃなかったんだよ。 でも未来があると思って使い続けてきたんじゃないか。 その意気で行け。

……でも Squeak で生活できるようになるかと言うとちょっとなあ……

本日のツッコミ(全4件) [ツッコミを入れる]

Before...

% jijixi [> (MappedCollection >> #at:) methodSourceString! いやぁ、これを実行..]

% sumim [こういった「楽しいけれど、いちいち式を書いて評価するのはどうも…」的作業を GUI 操作に置き換えてくれるのがシステ..]

% sumim [逆に、GUI ありのシステム → 逆に、GUI ありの Smalltalk システム ジョブズがこの種の… → ジ..]


2007-02-04 [長年日記]

% [Smalltalk] MappedCollection が何物かを調べてみるテスト

sumim さんがステキな方法を教えてくれたので、これを利用していじってみる。

st> (MappedCollection >> #at:) methodSourceString!
'at: key
    "Answer the object at the given key"
    ^domain at: (map at: key)
'

ふむふむ?

st> MappedCollection >> #at: !
CompiledMethod new: 10 "<0x202e0b8>"

ははあ、そういう仕組みなんだ。

st> (MappedCollection >> #at:put:) methodSourceString!
'at: key put: value
    "Store value at the given key"
    ^domain at: (map at: key) put: value
'

ともあれ、MappedCollection てのは domain (実際に値を保持するコレクション) に map (外部向けのキーと domain 向けのキーを関連付ける辞書) を間に置いてアクセスするラッパーのようなものだと。 インターフェイスは同じだから map は配列系でも良いのかな? んで、

st> (MappedCollection class >> #new) methodSourceString!
'new
    "This method should not be used; instead, use #collection:map: to
     create MappedCollection."
    SystemExceptions.WrongMessageSent signalOn: #new useInstead: #collection:map:
'

new でインスタンスを作るんではなく、

st> (MappedCollection class >> #collection:map:) methodSourceString!
'collection: aCollection map: aMap
    "Answer a new MappedCollection using the given domain (aCollection)
     and map"
    ^self basicNew setCollection: aCollection andMap: aMap
'

既存のコレクションを使って作るもんだと。 もう少し追ってみようと思ったけど、#basicNew だとか #setCollection:andMap: だとかがどこにあるのかわからんのであきらめた。 あとは実際に使ってみるしかないな。

st> Smalltalk at:#mc put:nil; at:#col put:nil; at:#map put:nil !
nil
st> col := Dictionary new !
Dictionary new: 32 "<0x2036d30>"

st> map := Dictionary new !
Dictionary new: 32 "<0x20372d8>"
st> map at:#hoge put:#foo !
#foo
st> map at:#fuga put:#bar !
#bar

st> mc := MappedCollection collection:col map:map !
MappedCollection new "<0x2038080>"
st> mc at:#hoge put:1 !
1
st> mc at:#fuga put:2 !
2
st> mc at:#foo put:3 !
Object: Dictionary new: 32 "<0x20372d8>" error: Invalid argument #foo: key not found
SystemExceptions.NotFound(Exception)>>#signal
SystemExceptions.NotFound(Exception)>>#signal:
SystemExceptions.NotFound class>>#signalOn:what:
[] in Dictionary>>#at:
Dictionary>>#at:ifAbsent:
Dictionary>>#at:
MappedCollection>>#at:put:
UndefinedObject>>#executeStatements
nil
st> mc at:#hoge !
1
st> mc at:#fuga !
2

st> col at:#hoge !
Object: Dictionary new: 32 "<0x2036d30>" error: Invalid argument #hoge: key not found
SystemExceptions.NotFound(Exception)>>#signal
SystemExceptions.NotFound(Exception)>>#signal:
SystemExceptions.NotFound class>>#signalOn:what:
[] in Dictionary>>#at:
Dictionary>>#at:ifAbsent:
Dictionary>>#at:
UndefinedObject>>#executeStatements
nil
st> col at:#foo !
1
st> col at:#bar !
2

まあ、なんとなく感触は掴めた。 これをどんなシチュエーションで使えば嬉しいのかまでは、ピンと来てないけど。

本日のツッコミ(全2件) [ツッコミを入れる]

% sumim [そのクラスのインスタンスが起動するメソッドが、スーパークラスのどれに定義されているのかは、Behavior >> #..]

% jijixi [丁寧な解説ありがとうございます。 すごく勉強になりました。]


2007-02-05 [長年日記]

% [雑談] スーパーボウル、インディアナポリス・コルツ vs シカゴ・ベアーズ、前半 (ネタバレ注意)

今年はリアルタイムで見るの無理かなーと思ってたんだけど、幸か不幸か見れてしまっているのであった。 で…

しょっぱなから波乱含み。 いきなりシカゴがキックオフリターンタッチダウンで先制。 所要時間 4 秒。 ちょwwwありえねーwww

試合開始時のリターンタッチダウンはスーパーボウル史上初だそうだ。

その後は、雨がひどいこともあってファンブル多発で、しかもそれがターンオーバーに繋がるという泥々っぷり。 0:7 からインディアナポリスがタッチダウンを返すも、ポイントアフタータッチダウンでホルダーがボールをこぼして得点できず 6:7 。 さらにその後、シカゴがタッチダウンを決めて 6:14 で 1Q 終了。

2Q 開始後、とんとん拍子にインディアナポリスが得点 (フィールドゴールとタッチダウン) して、あっという間に逆転。16:14 。 雨の勢いは変わらずだが、慣れてきたのかプレイが安定してきた様子。 それにしてもシカゴはろくに攻撃してねーぞ(苦笑

two-minute warning 後、またもやファンブルからのターンオーバーが続いて、もうぐちゃぐちゃ。 結局、インディアナポリスがおいしい目を見て得点圏へ到達するものの、攻めきれず 35y のフィールドゴール。 …を外して 14:16 のまま前半終了。マジか。

やー、波乱な展開だなー。 しかし、どう見てもインディアナポリスが押しまくってるんだけど、最初のタッチダウンが効いてて点差はほとんど無い。 雨のせいでしかたないとは言え、こうもファンブルが多いと白ける部分が少なからずあって、微妙に楽しくなかったりするのが残念。

% [雑談] スーパーボウル後半開始

ん、雨止んだっぽい?

あーやっぱ降ってるか。

% [雑談] スーパーボウル後半 (ネタバレ注意)

3Q まずはインディアナポリスがフィールドゴールで追加点。19-14 。

インディアナポリスは最初のキックオフ以来、ヘスター (リターンタッチダウンを決めた選手) にボールを持たせないキック (パント含め) が徹底されているなあ。 まあ気持ちはわかるが、見てる方からするとちょっとつまんないぞ。

シカゴのオフェンスは 2Q 以降、良いとこ無し。 その辺の流れの悪さも影響してるのか、ディフェンスまで調子がおかしくなってきてる感じ。

3Q 残り 4 分でインディアナポリスが 1st & goal のチャンスを得るも、シカゴのディフェンスが踏んばってフィールドゴールに留め、22-14 。

その後のキックオフ。 ヘスター避けの浅いキックに加えて、反則で 15y 罰退が付いてシカゴは大チャンス。 でもやっぱり攻めきれず、44y のフィールドゴールを決めて、22-17 。

4Q 残り 12 分ほど、インディアナポリスがインターセプトリターンタッチダウン。 これで 29-17 。これは決まりかなー。

って、またインターセプトされてるしー。グロスマン、ダメぽ。 なんか風が結構影響してるっぽいが。 おお、ここでディフェンスが奮起して初サック来たよ。 パントになって、ヘスターにボールが行ったけどフェアキャッチになっちゃってリターンは無し。

4Q 残り 7 分程からシカゴの攻撃。 時間も微妙になってきたんでノーハドル。 でも、自陣 45y あたりで 4th ダウンギャンブル失敗。

残り 5 分、インディアナポリスは時間を使う戦法に移行した模様。 シカゴはタイムアウトが一つしか残ってないし、よほどのことがないとこれで終わりかなあ。

インディアナポリスのボールのまま two-minute warning 。 はい、これで終わりです。

% [Erlang] パッケージ

久しぶりに Erlang とかいじる。 つーか、実は結構頻繁に遊びでいじったりはしてるんだが、日記に書くほどのネタが無いんだよなー。 んで、今日はパッケージの話。

Erlang におけるパッケージとは、まあぶっちゃけ Java のソレである。 つまりモジュールの名前空間を広くする仕組み。

% cat com/azito/jijixi/mod.erl
-module(com.azito.jijixi.mod).
-export([f/1]).

f(X) -> .io:fwrite('~p~n', [X]).

ライブラリパスの通ったところに、こんなファイルを作る。 この例では com.azito.jijixi がパッケージ名になる。 実際はモジュール名がこうなってるからと言って、必ずしもディレクトリ構成までこうなってる必要は無いんだけど、とりあえずこうしておいた方が管理は楽だろう。

ちなみに、パッケージ付きでモジュールを作る場合、モジュール内のデフォルトの名前空間はそのパッケージと同一になるので、普通に io:fwrite とか書くと com.azito.jijixi.io:fwrite の事だと見做されてしまう。 ので、トップレベルのモジュールを使うときは先にドット一つ付けて .io:fwrite のように書くと良い。 もしくはあらかじめ -import ディレクティブを使って io モジュールを取り込んでおくこと ( -import(io). ) で io:fwrite として使えるようになる。

% erl
Eshell V5.5.2  (abort with ^G)
1> c('com/azito/jijixi/mod').
{ok,'com.azito.jijixi.mod'}
2> com.azito.jijixi.mod:f(hoge).
hoge
ok

こんな感じで使う。 import を使うことでモジュールをトップレベルに取り込むことができる。

3> import(com.azito.jijixi.mod).
ok
4> mod:f(hoge).
hoge
ok

他に import_all(com.azito.jijixi) でパッケージ内の全てのモジュールを import できたりするんだけど、どうも挙動が変というか想定どおりに動いてくれない。 結局よくわかんないので、素直に import 使うのが吉かも。


2007-02-06 [長年日記]

% [Mac] MPEG Streamclip 1.8

なんかいつの間にか、YouTube の URL 入力すれば flv ファイルをダウンロードしてくれるようになってるな。 いろいろと微妙なアレではあるけど、便利と言えば便利かもしれなくもない、たぶん (なんかはっきりしないのは、きっと大人の事情)。

このソフト、いつの頃からか Windows 版も用意されるようになったけど、Windows なら他にたくさん選択肢ありそうだし微妙な気がするよね。 実際どうなのかは知らんけど。

% [雑談] その代わり貧乏ですが何か? (笑

木村さんとこで、

ああ jijixiさんリアルタイムで見られるなんていいなあ。

とか言われちゃってるわけですが。 ほんとの意味で『いいなあ』と、うらやましがられるべきなのは、生で観戦しちゃってる人なのでありますよ。 テレビ中継を見るくらいなら、衛星放送さえあればあとは何かしらのダメ人間スキルがあれば可能なわけで (ずる休みでもニートでも何でも可)。

一生に一度くらいは生でスーパーボウルを観戦してみたいっすね。

% [game] セカキュー日記、攻略ページ解禁編

基本的には自分でなんとかした方がおもしろい系のゲームなんで、攻略情報とかは意図的に視界から外すようにしてたんだけど、そろそろ自力だけではツラくなってきたんで攻略 Wiki を見始めた。

んで、とりあえずクリアできずに溜ってたクエストの解法だけ見れば良かったんだけど、ついつい勢い余って 3 匹の竜を倒したら戦うことができる最後の敵の情報とか読んでしまって鬱入った。 めちゃくちゃ倒すのツラそー...orz

いや、たぶんアバタールチューナーの人修羅よりはマシだろうけどさ……つーかアレは比べる対象として無理があるが。 そういや公式 PodCast で、隠れボス作ったのは人修羅作った人と同じだとか言ってたっけ? 攻略法を読んでも倒せる気がしない敵ってそうそういないと思うけど、人修羅はもうほんとヒドすぎたな。 3 回くらいチャレンジしたけど (当然全員レベル 99 で)、一度も「もしかしたら勝てそうかも」などと思う間も無く全滅したよ。

さて、今回のはどんなもんなんだか……


2007-02-07 [長年日記]

% [雑談] LinkedList はどう読む?

わしは英語ダメな人間なので、英語圏の人がどう読むのかわかんないんだけど、ググると『リンクドリスト』と『リンクトリスト』の二種類が拮抗してるようではてさて。 まあ、実際は上記二つは非常に少数派で、大抵は -ed を華麗にスルーして『リンクリスト』と表記されてる事が多いわけだが。 そしてわしは、そこら辺の宗教戦争に巻き込まれないように『連結リスト』と表記するようにしているわけだがだが。 ふむむ。

せっかくだから「よみかたあんけーと」に登録しといたんで、気が向いた人は投票してください。

% [独り言] 履歴書は送り返すと言っておいて、一週間以上経っても送って寄こさない件

まあ郵便事故の可能性も無いことは無いけど可能性は低いよな。 個人情報がどうのこうのとうるさい昨今、まったくだらしのないことだ。 かと言って、催促するのもバカバカしいしめんどうなのでスルーしとこう。

% [Dylan][Mac] なぜかビルドできない件 (未解決)

MacPorts で gwydion-dylan がインストールできない件は、どうも途中で mindy (ブートストラップ用の dylan インタプリタ) がエラーを出して止まってるせいらしい。 何が原因なのかはちょっとわかんないんだが、port info でバージョンをよく見ると 2.3.11 となっていて、最新のバージョン (2.4.0) ではないのであった。 ちょうど FreeBSD にインストールしたときの tar 玉があったので、とりあえず 2.4.0 を自前でビルドしてみるが、やっぱり似たようなところで止まる。(完全に同じところではないっぽいのが微妙と言えば微妙)

で、ダウンロードのページをもう一度よーく見直してみると、なんだバイナリが用意されてるではないか。 Mac OS X 10.4 のところを見てみれば、2.4.1pre1 というバージョンのものが置いてあった。 さっそくダウンロードして、一応中身を覗いてみるとインストール先が /usr/local 決め打ちで libgc も一緒に入っている様子。 まあ、これは Mac OS X のリンク事情から仕方ないと言えば仕方ない。

でもやっぱ、すでに Boehm-GC はインストールされてるのに、別のところに同じライブラリ置かれるのも好かんなーと思ったので、バイナリが用意されてるってことはこのバージョンならビルドできるんだろーと予想しつつ 2.4.1pre1 のソースを拾ってきてビルド。 ……が、やっぱり失敗...orz

とても原因を追いかける気力は無いので、結局日和ってバイナリをにょろっと展開して終了ってことにした。 微妙に納得は行かないが、FreeBSD マシンで 20 秒かかってたコンパイルが 10 秒で終わるようになったんで嬉しい。 これで現在のマイブーム言語である Erlang, Dylan, Smalltalk はメインマシンで完結できるようになった。 Dylan いじるために、いちいち FreeBSD マシン立ち上げるのウザかったんだよな、うるさいから。 メインである iMac G5 は我が家で一番静かなマシンで、こいつに慣れてしまうともうそこらのデスクトップ機はうるさくてイヤになるのよ。

ところで、ドキュメントとか漁ってると、d2c はコンパイルに時間がかかりすぎるので、ちょっとしたテストとかプロトタイピングには mindy を使うと良いよ…みたいなことが書いてあったりするんだけど、またこの mindy ってのがクセのあるやつで、d2c とは使い方が何もかも違うので全然うまく動かせない。 そんなわけで、しばらく悪戦苦闘したんだけど、結局あきらめて d2c を使ってる状況だったりする。 プロトタイピングに使えとか言うんだったら、せめてもう少しユーザインターフェースを統一してくれよなー。

% [Dylan] Open Dylan の方も試してみたくて Windows にインストールしてみたんだが…

1.0beta1 というやつ。 どうも VC++ 2005 Express との組み合わせだとうまく動いてくれない。 IDE は動くんだけどプロジェクトのビルド (厳密には link コマンド) が失敗する。 ビルドスクリプトがテキストで用意されてるだけだから、VC++ に詳しければ何とか対処できるのかもしれないが、いかんせんわしはそっち方面全然ダメで。

VC++ Toolkit 2003 なら動くみたいだけど、もう MS のサイトには置いてないみたいなんだよな。 前にインストールしたときのアーカイブは残ってないし、その後 OS の再インストールしたんで現物も闇の彼方。

まあ良いや、単に興味本位で入れてみただけだし。 つーか IDE がどんなか見てみたかっただけなんだから、当初の目的は果たせてるんだよな。 あ、でもデバッガとかも使ってみたかった。 こればっかりは何かビルドできないと試せないな。

% [Haskell] Liskell

2ch の LISP スレより。

なんつーか、要するに S 式で Haskell のコードを書くためのもの…なのかな。 視点を変えると、抽象データ型とパターンマッチが組み込まれた LISP とも言えるのか?

おもしろい気はするけど、どういう人が使うんだ? これ。

% [Smalltalk][Mac] GNU Smalltalk を JIT つきでコンパイル

sumim さんとこの carver さんのコメントで --enable-jit というオプションを知ったので試してみたんだが……

st> Time millisecondsToRun: [
st> ((1 to: 1e2) inject: 1 into: [:e :i | e + (1 / i factorial)]) asScaledDecimal: 100] !
7822

これが JIT 無し。 次に JIT 有り。

st> Time millisecondsToRun: [
st> ((1 to: 1e2) inject: 1 into: [:e :i | e + (1 / i factorial)]) asScaledDecimal: 100] !
45238

……えーー...orz

なんだこりゃ。 性能が変わらないどころか、大幅に下がってるよ。 どうも、少なくともウチの環境では JIT 無しの方が幸せそうだ。 ちょっと残念。

% [Smalltalk] GNU Smalltalk には、どうやら LargeInteger に穴があるらしい件

例の sumim さんとこの件で、具体的にどこが遅いのかいろいろ探ってみた。 プロファイルの取り方とか知らないんで、めっちゃ手作業だけど(笑

んで、結果から言うと、どうも LargeInteger が絡む計算が絶望的に遅いようだ。 特に割り算。

st> Smalltalk at:#time put:[:block| Time millisecondsToRun:block] !
BlockClosure new "<0x20361f0>"
st> Smalltalk at:#x put:1000 factorial !
LargePositiveInteger new: 1067 "<0x2040220>"
st> time value:[ x * x ] !
760
st> time value:[ 1 / x ] !
6008
st> time value:[ 2345 / x ] !
6011

割り算一回に 6 秒とかかかってちゃ話になんない。 つーか、この 1 / x の結果って Fraction クラスになるんだけど、なんでそんな時間かかるの? だって…

st> Smalltalk at:#y put:(1 / x)!
Fraction new "<0x2066940>"
st> y denominator = x !
true

こうだよ? いったい何が起こっているというのか。あなおそろしや。 きっと効率とか全然検討されてない実装なのであろう。

今日の教訓
GNU Smalltalk を使うときは LargeInteger に気をつけるべし。

おまけ。

% irb
irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> require 'rational'
=> true
irb(main):003:0> x = (1..1000).inject {|a,b| a * b}
=> 402387260077093773543702433923003985719374864210714632543799910429938512398
(略)
irb(main):004:0> Benchmark.bm {|r| r.report { 1.to_r / x }}
      user     system      total        real
  0.000000   0.000000   0.000000 (  0.000614)
=> true
irb(main):005:0> Benchmark.bm {|r| r.report { 2345.to_r / x }}
      user     system      total        real
  0.000000   0.000000   0.000000 (  0.024790)
=> true

ま、そうだよね。

% [Smalltalk] GNU Smalltalk Float リテラルの罠

ちょっと思うところあって Float な辺りをちょろちょろいじってたんだが…

st> 1e100 !
inf

…は?

st> 1e37 !
1.00000e+37
st> 1e38 !
1.00000e+38
st> 1e39 !
inf

何これ。 Float クラスのページには 1e308 が INF にならない最大値のように書いてあるんだが。 で、いろいろ試行錯誤して……

st> Smalltalk at:#y put:(10 raisedTo:308) !
LargePositiveInteger new: 129 "<0x20218a8>"
st> y asFloat !
1.00000000000000d+308

ぐはっ!!

st> 1d308 !
1.00000000000000d+308

そういうことか……

st> 1e38 class !
FloatE
st> 1d308 class !
FloatD

どうやら FloatE が単精度で FloatD が倍精度らしい。 そんでリテラルも e を使うと単精度で d を使うと倍精度と。 ちょっと予想できなかった……つーか何の意味があんだよ、これ...orz 単精度なんてイラネって。

あーなんか無駄に疲れた。 それにしてもユーザーズガイドのページはどうも情報が古いみたいだなあ。 クラスリファレンスなんかも、実際の挙動と合わないところが多いし。 最新版てどこにあるんだ?


2007-02-08 [長年日記]

% [objc] ささださんが Objective-C でメモリ管理ってどうしてるんだろう、みたいなことを書いてるのを見て

つNSAutoReleasePool というコメントを付けようかと思ったんだが、よく考えると件の本を読み進めていけばどうせそのネタが出てくるに決まってるので止めておいた。

ちなみに Apple のランタイムで基底クラスになっている NSObject にはリファレンスカウンタがあるが、GNU のランタイムの基底クラス Object には無い。 GNU Objective-C では new と free で確保と解放をする。 その代わりといってはなんだけど、メモリ関係の関数は関数ポインタとして保持されてるので、そこを入れ換えてやると色々できるようになっている。→参考 (過去のわしの日記)

まあ、なんつーか GNU のランタイムも結構おもしろかったりするんだけど、いかんせんライブラリの揃いが絶望的なので、やっぱり Cocoa Framework あってこその Objective-C なんだろうなあ。

% [Smalltalk] gst-mode が便利そうだったんで、Carbon Emacs で使えるようにしてみた

そりゃもうあんた、何度もキレそうになったけどな。 まあ、便利なのは認めるよ。それでも言おう。I hate Emacs!

たぶん、ちゃんとした知識のある人ならもっとスマートにやるんだろうけど、わしゃ Emacs なんてちゃんと憶える気は無いのですごく適当である。 とにかく何とか動けば良いだろうという精神で。

とりあえず Carbon Emacs は /usr/local/share/emacs/site-lisp がライブラリパスに含まれてないので、泣きそうになりながら何とかする方法を探して、よくわかんないけどとりあえずこんな感じ↓で対処。

% cat ~/.emacs (抜粋)
(setq load-path
      (append load-path
              (list "/usr/local/share/emacs/site-lisp")))

良いのか、こんなんで。まあ動いてるから良いよ。

あとは Emacs を起動して、

M-x load-library
Load library: smalltalk-mode
C-x C-f
Find file: ~/tmp/smalltalk_test/test.st
M-x smalltalk-mode

ここまでで、Vim と同等に。 んで Vim を越えるために以下。 あー、ところで、単に対話環境の代替として使うなら、別にファイルを開かんでも *scratch* バッファを smalltalk-mode にしちゃっても良いのかな? そんな気がすんね。 ともあれ。

C-c m もしくは M-x gst

これで別ウィンドウに gst のインタプリタが開く。 あとは、ファイルの方のバッファで、

'Hello world!' printNl

とか書いて C-Space C-a とかでリージョン選択して C-c e (M-x smalltalk-eval-region) で評価するとインタプリタの方のバッファで実行される。 C-c p (M-x smalltalk-print) だと値の表示。Squeak の print みたいな動作。

あと、

'Hello world!' printNl
!

みたいに先頭に "!" を入れておくと、前回の ! から ! までの式を C-c d (M-x smalltalk-doit) で実行できる。

……まあなんつーか、便利なことは便利になったけど、そのために払った代償 (精神的苦痛) はわりと大きかった気がするよ(苦笑)。疲れた。

本日のツッコミ(全3件) [ツッコミを入れる]

% ささだ [いや,それを含めて「実際にどうやってんのかわからない」のですよね.あれを書いた時点で,そこまで読んでいました.]

% 向井 [load-path は単なるリストなんだから、1つだけ加えるときは (setq load-path (cons "...]

% jijixi [やってみたらバッチリでした。> 向井さん ああ、こうやって慣れていくのね、Emacs に。少し敗北感。 ちなみに l..]


2007-02-09 [長年日記]

% [PC] 超今さらだけど Windows PowerShell を入れてみた

どうせ command.com に毛が生えたようなもんでしょ? と馬鹿にしてたんだけど、結構楽しいね、これ。 まあ、純粋にシェルとしての機能を気にするなら Cygwin で zsh 使ってれば良いんじゃないかと思うけど、PowerShell 独自の機能がおもしろい。 特に PSDrive 。 エイリアスとか関数とか変数とかレジストリとか、そういうもろもろをファイルシステムのように扱うことができる。

こういうのって、キャラクタベースのシェルだけじゃなくエクスプローラとかでも使えて欲しいけどなあ。 もしかして Vista ってそういう機能あるんだろうか?

% [Mac][objc] うーん、そうすると、ここら辺の話なのかな

ささださんからツッコミ貰ったんだけど。 上記の文書にだいたい Cocoa 的お作法みたいなのは網羅されてる感じかな。 翻訳されたものもあったような気がするんだけど見付けられなかった。

ぶっちゃけ、わしは Cocoa アプリケーションをちゃんと作ったことなんて無いので、偉そうに語る資格は無いんだけども、聞きかじりのにわか知識で書くと……

  • AppKit.framework を利用している場合、イベント処理メソッドを呼び出すときには自動的に NSAutoreleasePool のインスタンスを用意してくれるので、プログラマは NSAutoreleasePool のことは意識する必要が無い。せいぜい必要に応じてオブジェクトに autorelease メッセージを送っておくだけ。
  • Appkit のお作法に則らない処理をする場合は自前で NSAutoreleasePool のインスタンスを用意する (参考)
  • アクセサなんかは、返り値に retain と autorelease を送ってから返してやるのがお作法 (参考)。たぶんささださんが想像してたのは、この話?
  • 自分で作ったオブジェクト (alloc とか new とか copy とか付いたメソッドで返ってくるのがそう) や、自分が retain メッセージを送ったオブジェクトに対しては、責任を持って release なり autorelease なりを送るべし。(参考)

こんな感じでやってるみたい。 Objctive-C ってかなり動的な言語なんで、どうしても規約ベースな開発手法になっちゃうんだと思う。 でもリファレンスカウンタのおかげで、「誰がどこで free してるか」とか気にせずに、その都度自分の責任範囲だけでオブジェクトの解放 (するつもり…という意思だけだけど) が完結できるから、C++ なんかよりは全然楽だと思う。 まあ、自動変数にオブジェクトの実体を保持できないのが不便と言えば不便だけど、それを補うために NSAutoreleasePool ってものがあるわけで。

ちなみに Mac OS X 10.5 で採用される Objctive-C 2.0 には GC が付いてくるみたいなんで、もっともっと楽になるでしょう。

% [Emacs] なんか微妙にハマり始めてる自分がちょっとイヤ

向井さんが色々教えてくれたりしたんで、ちまちまいじってるうちに何だか妙に楽しくなってきてる自分がいるよ。 なんかあれだよね、設定ファイルいじるのは Vim より Emacs の方が楽しい気はするよね。

……まあ、依然として .emacs いじるときに使ってるのは Vim だったりするんだが(苦笑

設定をいじるのは楽しいかもしれないけど、エディタとしてはやっぱり Vim から離れられるとは思えないな。 もう完全に脳味噌が Vim に最適化されちゃってるし (vi に…じゃないところが結構ポイント)。 vi-mode とやらを入れたとしても、Vim 相当にはならんだろうしなあ…… って、今見たらすでに vi-mode って入ってるのか。 うーん、せっかくだからしばらくいじってみるかな。

それにしても、つい最近まで (上下左右と行頭行末を除いては) C-x C-c しかコマンド知らなかったのに、それに比べると随分進歩したなあ。 これまでに憶えたコマンド↓

  • C-x C-f でファイルを読み込む
  • C-x o でウィンドウを切り替える
  • C-M-f で vi の w (微妙に違うけど感じとしてはそんな風味)
  • C-M-b で vi の b (同上)
  • M-x hoge でなんか関数呼び出し
  • C-Space → カーソル移動でリージョン選択 (Vim の visual モードのノリで領域選択したあと ex コマンド入力したくなるけど、できないからストレスが溜まる)

たった数日で知識量が 7 倍にも膨れ上がりました!!(ぉぃ

いやいや、ほんとすごい進歩だよ。 なんせわし、zsh 使っててもちょっとややこしいコマンドライン編集になると、すぐ esc 叩いて vi モードに入るくらいの人間だから (キーバインドは基本 vi で emacs モードの一部を追加してある仕様)。 tcsh の vi モードは微妙すぎるけど、zsh の vi モードは結構本格的に vi だから好き。

それはそれとして、Emacs いじってると小指が破壊されそうになる。 これは何と言うか、skk を使い始めた頃の感覚。 Vim だと Ctrl キーなんてそんなに押さないしなあ。 や、素の vi に比べれば遥かに押す機会が多いとは思うけど、カーソル移動にまで Ctrl キーが必要なのはさすがにツラい。

% [Emacs] vi-mode 役に立たねー

なんじゃこりゃ、vi ユーザをバカにしてるのか(笑

特に ex コマンドが使えないんじゃ意味ないなー。 とりあえず ex コマンドを入力しようと思ってコロン入力したら表示される tips が、それなりに役に立つかも。 以下丸写し。

Ex commands are not implemented in Evi mode.  For some commonly used ex
commands, you can use the following alternatives for similar effect :
w            C-x C-s (save-buffer)
wq           C-x C-c (save-buffers-kill-emacs)
w fname      C-x C-w (write-file)
e fname      C-x C-f (find-file)
r fname      C-x i   (insert-file)
s/old/new    use q (vi-replace) to do unconditional replace
             use C-q (vi-query-replace) to do query replace
set sw=n     M-x set-variable vi-shift-width n

そうそう、こういう対応表みたいなのが欲しいんだよな。 これのもっと詳しいようなやつって、どっかに無いもんかねえ。

% [雑談][clip] セガ、「バーチャスティック ハイグレード」の一部不具合を発表。販売中止に−−販売済み製品は返金・返品対応 (ITmedia +D Games)

最近のセガはこんなんばっかだな。 金取ってベータテストやらせるようなゲーム作ってる空気が、ハード部門にまで伝染したのか?

本日のツッコミ(全1件) [ツッコミを入れる]

% Hiro [viのw,bに近いのはM-f, M-bかも。 C-M-f, C-M-bはviの%に似た動きもします。]


2007-02-10 [長年日記]

% [Emacs][Mac] メタキーって結構悩ましい

Hiro さんからツッコミいただきました。どうもありがとう。

viのw,bに近いのはM-f, M-bかも。

C-M-f, C-M-bはviの%に似た動きもします。

なるほど。 でもなんだかこう…長年の Mac ユーザとしては (Carbon Emacs ではコマンドキーがメタに相当する) メタ+なんちゃらを使いまくるのは気持ち悪いよね(苦笑)。 M-x みたいに一発押せばオーケーな場合はまだ良いけど、カーソル移動のために M-f とか M-b を連打したり押しっぱなしにするクセが付いちゃったら、他のアプリでえらいことになりそう。 ちなみに OmniWeb では Command+B はブックマークウィンドウの On/Off なので押しっぱなしにすると、ちょっと何事か? という状態になる。 Command+F は普通検索機能だし、そうすると Windows の FireFox でついつい行編集中に Ctrl+F 押しちゃって検索窓が出てムキーっていう状態と同じことが起こりかねない。

一応設定でコマンドキーじゃなく別のキーに割り振ることもできるみたいだけど、それはそれで不便な気がするしなあ。 や、まあ、ちゃんと頭を切り替えれば大丈夫…だとは思うけど、Emacs いじってるつもりで他のアプリにフォーカス移ってたりすると鬱だよなー。 ……そこまで一生懸命 Emacs を使うようになるかっつーと、それはそれで微妙なんだが。

% [zsh] zsh におけるわしのキーバインド設定

昨日ちょっとネタにしたので、参考までに。

bindkey -v               # vi key bindings
bindkey '^P' up-line-or-history
bindkey '^N' down-line-or-history
bindkey '^A' beginning-of-line
bindkey '^E' end-of-line
bindkey '^F' forward-char
bindkey '^B' backward-char
bindkey '^D' delete-char-or-list
bindkey '^U' kill-whole-line
bindkey '^K' kill-line
bindkey '^_' history-incremental-search-backward
bindkey -a 'q' push-line

#bindkey -a '/' history-incremental-search-backward
#bindkey -a '?' history-incremental-search-forward

bindkey ' ' magic-space    # also do history expansion on space
bindkey '^I' complete-word # complete on tab, leave expansion to _expand

昨日書いたとおり、基本が vi キーバインドでカーソル移動に emacs キーバインドからパクってきた設定を追加してある。 実際のところ、vi キーの設定を上書きしてるところはほとんど無いはず。

bindkey -a というのは vi キーのコマンドモード時の設定で、'/' と '?' には通常 history-vi-search-* が定義されてるんだけど (コマンド名違うかも)、一瞬インクリメンタルサーチの方が便利かなーと思って設定してみたこともあった。 結局、検索後に n で同じ条件のものを遡って探せる通常の vi-search の方が便利だと気付いてやめちゃったけど。 magic-space と complete-word は設定ファイルの雛形に元からあった設定。

ちなみに push-line は今編集中の行を一旦よけといて、何かコマンド実行したあとにまた編集するためにスタックに積んどく動作。 emacs キーだとたしか ^Q あたりに入ってた気がするけど、vi キーだとどこにも設定されてないんで追加した。 たまーに便利。

あらためて設定を見直してみて、どうしてインクリメンタルサーチを ^_ に割り当ててるのか自分でも謎だったんだけど、たぶん Terminal.app に移行する前の設定だろうと思って mlterm を使ってみたら思い出した。 なぜか ^/ を押すと mlterm では (X では?) ^_ として入力されるからだ。 要するに、ほんとは ^/ に検索を割り当てるつもりだということ。 でも Terminal.app では ^/ は何もキーコードを発行してくれないので意味が無いのであった。 まあ、検索するときは Esc 叩いて / っていう流れができちゃってるから別に不便でも無いんだけど。

% [zsh] グローバルエイリアス

わしはいちおう zsh ユーザではあるけど、あんまりヘビーな使い方はしてないので微妙にもったいないと思うこともあったりする。 でもまあ、zsh というのは Emacs と並んで奥が深い症候群に陥りやすいアプリケーションの筆頭のような気がするので、適当なところでやめておくのが良いのであろう、などとも思う。

それでもまあ、ライトユーザであっても憶えておくと便利な事柄というのはいくつもあって、グローバルエイリアスなんかはそういう類じゃないかなーと。 ぶっちゃけ、わしも設定ファイルの雛形に書いてあったから知ってるだけで、詳しいことは何にも知らないんだが、ともあれこんな↓である。

# Global aliases -- These do not have to be
# at the beginning of the command line.
alias -g M='|more'
alias -g H='|head'
alias -g T='|tail'
alias -g L='|lv'
alias -g V='|vim -'
alias -g N='|nkf -We'

上三つが元からあったもので、残りはわしが追加したものだ。 こんな風に使う。

% cat /etc/passwd H -3
##
# User Database
# 

パイプ記号ってわりと入力しにくいところにあるんで、地味に便利。 ちなみに N の設定は、わしが LANG=ja_JP.eucJP な環境で生活してるので、ls が文字化けすることに対処するためのもの。 ls の出力を UTF-8 -> EUC-JP で変換してやって、とりあえず読めるようにする。 まあ、日本語のファイル名なんてめったに使わないんで、あんまり必要無いんだけど。

濫用しすぎると大変なことになりそうだけど、それなりに使うなら便利な機能だと思う。

% [Emacs] 何かするときは全部 M-x で、というのが正しい vi ユーザの姿ではないかと思った

あたかも、何かするときは全部 ex コマンドで…と言わんばかりに。

正直 C-x とか C-c からのコマンドは憶えられる気がしないのである。 でもさ、要するにあれでしょ、それらのコマンドってのは vi/vim で言うところの map なわけでしょ。 他人が設定した map なんて憶えられるわけないよ。 っていうか、わしは自分で設定しても憶えられないから、map なんてほとんど使ってないよ(苦笑

本来のコマンド (関数) が元々あって、キーコンビネーションにそれらの機能をマッピングしてるだけで、憶えれば便利ではあるけど、憶えないとその機能が使えないわけではない……んだよね? 多分。

長い名前のコマンドで憶えてしまえば、忘れかけても何となく想像が付くし、どうせ補完もしてくれるしね。 ところで補完のとき Ctrl+D で候補一覧の表示をしてくれないのは tcsh や zsh や vim に慣れ親しんでるわしとしてはうざったい。 なんでいちいち TAB 二回押さなならんのだ。 だから Bash も嫌いなんだよ。

% [Emacs] M-x help-with-tutorial

こういうのは初めに教えてくれるべきです (誰が?)。 ちなみに Vim ならシェルから vimtutor コマンドを実行しませう。

んでまあ、チュートリアルだが。 最初のうちはまあ良かったんだけど、やっぱり C-x が絡んでくるあたりから脳が拒否反応を起こし始めたのであった。 なので、やっぱりこれ以降はさらっと読み流して終わりにしとく。 何とか憶えられた分を vi との対応でメモ。

                 vi/vim                  emacs
一画面移動       C-f, C-b                C-v, M-v
半画面移動       C-d, C-u                (欲しいんだけどあるのか?)
キャンセル       Esc                     C-g
数値指定         コマンドの頭に数値      C-u 数値 コマンド
アンドゥ         u                       C-x u もしくは C-_ (Ctrl+/)
切り取り         d*                      C-w
貼り付け         p                       C-y
コピー           y*                      (わからん)

vi/vim だとコピーが「ヤンク (yank)」なのに Emacs だと貼り付けがヤンクなのがややこしい。 C-v とか C-w も語源がわからんので憶えにくい。 コマンドを途中でキャンセルしたいときに C-g というのがわかったのは収穫 (この操作は skk のおかげで実は慣れてる)。 今まではついつい Esc 連打して、beep 音連発されてたよ(苦笑

ともあれ、少しは扱いやすくなってくれた気がする。

% [vim] 今日の言語 Vim

……え、えーと、なんと言うか Emacs の中身は腐っても LISP なわけで、なんともそのパワフルと言うか……つまり何かこう悔しくなったのね。 そんでまあ、あれよ、vim スクリプトの勉強とかしてみようかと思ってさ。

そんなわけでちょろっといじり始めてみたんだけど、あー泥くさい。 なんか 7.0 になってだいぶスクリプト環境が良くなったらしいけど、じゃあ 6.0 以前はどうしてたんだろなあ。 いやあ、機能拡張作ってる人には頭が下がる。 いちおう :help eval をざっと眺めた感じではリストや辞書もあるし、それをいじる map とかの手続き (vi 用語の map と非常にややこしいんだが。それ系の map なんちゃらって関数もあったりするし) なんかもあるみたいだし、それなりにちゃんとした言語にはなってるみたいではある。 でもなんか泥くささを感じてしまうのはナゼだろう。

とりあえず練習として、日付によってディレクトリを作って、バックアップファイルをそこに突っ込むというのをやってみた。 :set backupdir=hoge でバックアップファイルを一箇所にまとめられるので、それを利用する寸法。 つーか、たかがそれだけなのに、えらく時間を食ってしまってぐったり。 全ては expand() の呪いなのだ。くそぅ。

set nobackup
let backupdir_base = expand("~/tmp/.vim_backup/")
let today = system('echo -n `date "+%Y-%m-%d"`')
let backupdir = backupdir_base . today
if ! isdirectory(backupdir)
   call mkdir(backupdir, "p")
endif
let &backupdir = backupdir
set backup

こんな感じ。 日付文字列を取得する方法がわからなくて system 関数に逃げている時点ですでにショボい。 そして、let &backupdir = backupdir としているところは set backupdir= しているのと同じことなのだが ('&' が頭に付いてるのはオプション変数)、実は厳密には同じでなくてそこで猛烈にハマってしまったのであった。 というか、ハマってる原因に気付くまでは mkdir のところも system 使ってたりしたのだ。 それに isdirectory で条件分岐とかもしてなかったし。

勘の良い人は気付いたかもしれないけど、要するにそれぞれ組み込み関数 (isdirectory とか mkdir とか) に渡すパス文字列は expand 関数で特殊文字を展開した表記に直してやらないとダメなのだね。 そして、オプション変数に代入する文字列も。 いや、まあそりゃわからんでもないんだけど、他のところでは (ex コマンド全般ね) 何もしなくてもチルダを展開してくれてるから、てっきりどこでもそうだと思うじゃないか。 あー、ほんと無駄に疲れた。

ともあれ、今回苦しんだおかげで、だいたいクセも掴めてきた気がするんで、いずれもう少し規模の大きな何かをやってみたいな。 まあ、キリが無いからやめておけ…っていうささやきが聞こえる気もするんだけど(苦笑

% [Emacs] C-x がとっさに押せない病

つーか A の隣りに Ctrl があるキーボードだと C-z とか C-x とか C-s とか押しづらくない?

わしの場合、Ctrl を押す場合でも人差し指は f から離れないんだが、そうすると C-x のときに x に近いのは中指になるんだよね。 でも通常は x って薬指で押すもんだから、C-x を押そうと思ってもまず薬指が動いちゃう。 で、「あ、違うぞ、えーと……」と一瞬考えてから中指を動かすって感じ。 無理に薬指で押そうとして指つりそうになったこともある(笑

そもそも今まで C-x を押す習慣てのがまったくと言って良いほど無かったからなあ。 Windows だとカットが Ctrl-X だけど、大抵カットなんかしないで Delete で消しちゃうし (Ctrl+C や Ctrl+V はよく使うけど)。 まあ、そういう意味では Mac でも Command+X ってあんまし使わないんだけど、x キーは Command キーのすぐ上だから間違えにくい。

とまあ、そんなこともあるし、C-x の次に何を押せば良いのかしばし考えないと思い出せないので、結局ファイル開くときは M-x find-file の方が早いし、バッファを消すときは M-x kill-buffer の方が早いという(苦笑

でも、わしはこれで良いような気がするよ。十分だ。 M-x find-file ってやると、毎回「C-x C-f で同じことできるよ」って教えてくれるけど、そんなもんすぐ忘れるんだよ。 C-x なんてくそくらえだい。

% [Mac][Emacs] M-q とか M-w の呪いはおそろしいねぇ

いやあ、くわばらくわばら。(呪いについてはツッコミ欄参照)

とりあえず soutaro さんは OmniWeb とか Opera みたいに、終了時に開いてたタブを憶えておいてくれるブラウザに乗り換えるべきだと思った。 つーか Firefox にも探せばそういうアドオンとかありそうな気がするけど。

あと向井さんは Terminal.app のターミナルインスペクタ (Command-I) のプロセスタブで『以下を除くプロセスが実行中の場合』のとこから ssh を取り除くべき。早急に。

いやほんと Emacs 使いの人は苦労しますね。 わしは Vim 使いで良かったなあ。 まあ、Vim 以外のあらゆるテキスト入力のシチュエーションでストレスが溜まるという弊害はあるんだけど……

本日のツッコミ(全6件) [ツッコミを入れる]

Before...

% jijixi [情報どうもです。 しかし M-w か……Command+W はウィンドウを閉じるのに頻繁に使うから気持ち悪いなあ(苦..]

% 向井 [carbon emacs は Command をメタキーとして使えるので Command-w でいいんだけど、 Te..]

% jijixi [これはなかなかアグレッシブな使い方ですね。 わしはこの手の使い方は誤操作が怖くてできないタイプです(苦笑]


2007-02-11 [長年日記]

% [Emacs] vip-mode, viper-mode

某巨大掲示板とは関係無くて、vi-mode の親戚。 vi-mode があまりにもアレな出来でがっかりしたんだが、こっちは結構よくできてる感じ。 特に viper-mode の方。

たいていの ex コマンドが使える上にコマンド補完もできるので、素の vi よりも高機能なくらい。 あくまで vi のエミュレートで vim 独自の拡張とかは入ってないけど、visual モードの代わりにリージョン選択が使えるし、わりと使う気になるレベル。 vim から乗り換えるってことは無いと思うけど、Oz をいじるときみたいに Emacs 使うのを強制されるシチュエーションでは重宝しそう。

でもやっぱ、変に似てる分だけ細かいところの違いでストレスが溜まりそうだから、使うのは最後の手段にしておきたいところだな。 わしの脳は vi じゃなく vim に最適化されてるし、結構 vi と vim って細かいところで違うんだよね。 例えばファイルの先頭に飛ぶのに vim だと gg っていうコマンドが使えるんだけど、vi だと 1G とか :1 とかやらないといけないとか。 gg の方が押しやすいから、すっかりこっちを使うクセが付いちゃってるんで、これが使えないとストレスが溜まる。

ところで Vim にも Emacs の真似をする機能拡張があったような気がしたんで調べてみた。 これ→ Vimacs : Vim-Improved eMACS: Emacs emulation for Vim

再現度がどの程度なのかは知らない。使ったことも、使おうと思ったことも無いし。

% [Emacs] 行番号が表示されてないと落ち着かない男

:set number させてくれ〜

いや、Emacs じゃ行番号なんてあんまし意味無いのはわかる。 わかるんだけど、やっぱり表示されてないとどうにも座りが悪い。 わしは Eclipse だろうが VisualStudio だろうが行番号を表示させる人間である。

そういうわけなんだけど、どうも Emacs の標準機能の中には vi の :set number に相当する機能は無いみたい。 仕方なくちょっとググってみたら、wb-line-number というのを見付けた。 ……けど Carbon Emacs ではちゃんと動かないみたいで、行番号が変。 次に上記ページで「イマイチ」と評されている setnu.el を試してみる。 ……一応動くことは動くけど、シンタックスハイライトの設定に影響されてところどころ色が変わっちゃったりするのが、すごく美しくない。イマイチ。 他に line-numbers-mode というのも見付けたが、Carbon Emacs では動かず。

やっぱおとなしく諦めるしかないのかな……

% [Firefox] 前回終了時のウインドウとタブを表示する

あれー、あるじゃん。いつから?

指定方法は、環境設定→一般→『Firefox を起動するとき:』のコンボボックスから『前回終了時のウィンドウとタブを表示する』を選択。

そうかー、どんどん OmniWeb の優位性が無くなってくるなあ。 そんで、Firefox が 3.0 になってレンダリングが Cocoa ベースになっちゃえば、フォントのキレイさも大差無くなりそうだし、ますます苦境に。 がんばれ Omni 。

まあ、わしは今のライセンスが有効なうちは OmniWeb を使い続けると思うけど、新規にライセンスフィー払ってまで OmniWeb を使う意味は無くなりつつあるね。 現状残ってる独自色と言ったら、ワークスペースとかタブのサムネイル表示とかか。 タブはともかくワークスペースなんかは Firefox でも機能拡張でありそうだなあ。


2007-02-12 [長年日記]

% [Emacs][vim][clip] Emacs で正規表現を使うなら re-builder を使おう (ひげぽん OSとか作っちゃうかMona-)

ほう、これは便利なものですな。 ちなみに vim でこれに相当する機能は知らないけど、ちょっと工夫すれば多少面倒ではあるけど似たようなことはできる。

  • とりあえず :set hlsearch してあるのが前提。
  • まず / で検索モードにして適当に正規表現を打ち込む。
  • マッチした文字列がハイライト表示されるので、想定通りか確かめる。
  • 想定と違っていたら、再度 / で検索し直す。このとき Ctrl+P で検索式の履歴が使えるので、Ctrl+P で一つ戻って Ctrl+F で編集すると楽。
  • 思いどおりの検索結果が出るようになったら、必要な範囲に対して (visual モードでも行番号指定でもお好きに) s/old/new/g で置換をかける。このとき old の部分で Ctrl+R → / と入力すると直前に使った検索式が挿入されるのでそれを利用する。

てな感じ。 ex コマンドや挿入モード時に使う Ctrl+R は続けて指定したレジスタの値を貼り付けるという動作で、実は / も検索式に割り当てられた特殊なレジスタの名前。 / の代わりに " だと一番最近 d や y したものを意味する。

% [雑談] 逆ポーランド Lisp というネタを見て…

萌香』を思い出した。 なんか他にも後置記法の LISP もどきを見たことがあるような気がするんだけど、思い出せない。


2007-02-14 [長年日記]

% [あなごる] わしにはこの手の才能が絶望的に欠けていると思う

なんかどこもかしこも、anarchy golf のネタでいっぱいなので、わしも OCaml あたりでやってみようかな…などと思ったのだが。

いきなり hello world で 27 Byte の出し方わかんねー

どうしてこんな数字になるんだー!! と叫びながら悶々と考えて結局…

print_string"Hello, world!"

こういうのに辿り着いたんだけど…… 28B なんだよね。 どう考えてもこれ以上縮まる気がしなくて延々考えて、最終的に「もしや?」と思ってバイナリエディタでファイルの最後に付く改行を削ってやったら 27B で通っちゃったよ。 えぇ〜!? そうなの? みんなこうやってんの? それとも改行が付いてても 27B なコードがあるの?

もしかしてゴルファーの人は、ファイル末尾の改行を削るツールを用意するところから始めるんだろうか。 いやまあ、そんなのすぐできるけど、なんかこう精神的にショックを受けるというか…… だいたい出力に改行が含まれてなくても通る時点で、「なんてお行儀が悪い…」とか思っちゃう人間なんだよなーわし。

% [あなごる][vim] そういや vim で EOL を付けない方法があった気がするな…と思って考えた

そうそう、:set binary して :set noendofline だ。 バイナリモードにしないと noendofline は意味無いので注意。 とりあえず↓こんなエイリアスでも作っとこう。

alias vimb='vim -b "+set noeol"'

noeol は noendofline の短縮形。

% [あなごる][OCaml] OCaml で e

Num モジュール使わないと 100 桁なんて出せないんじゃないかと思うんだが、ましてや 115B って m.ukai さんはどんだけスーパーハッカーなんだよ!!……と思ったわけ。

……ん、あれ? 100 + 15 ってなんかピンと来るものが……

print_string"27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274"

これかー!!

なるほど、なんかこのゲームの楽しみ方がわかってきた気がする。 あんまりマジメに考えちゃダメなんだよね、きっと。

% [あなごる][OCaml] 99 shinichiroes of hamaji

現状 320B。全然お話にならない...orz

いったい何をどうやったら 250B レベルになるんだ? 今の戦法だと、あともう数バイトくらいは縮まりそうだけど、とても 60B 以上縮まるとは思えないので、たぶん根本的に考え方間違ってるんだろうなあ。

% [あなごる][OCaml] 文字列に改行文字を入れるときの小技

こんなものが影響するほどの差まで迫れれば良いんだけど...orz

OCaml では文字列に改行文字を含める場合、

"hoge\n"

と、

"hoge
"

は等価になる。 下の例の方が 1byte お得。

本日のツッコミ(全5件) [ツッコミを入れる]

Before...

% ksk [はじめまして. 99 shinichiroes of hamajiに関してですが, 私のコードにはif-then-e..]

% m.ukai [99shinh はまだif-then-elseを使ってますが、jijixiさんの改行技を利用させていただきました。て..]

% TrackBack [http://d.hatena.ne.jp/KeisukeNakano/20070226/1172482223 λx..]


2007-02-15 [長年日記]

% [あなごる][OCaml] 正直ここまで夢中になるとは思ってなかった

ksk さんや m.ukai さんのツッコミを元に 99 shinichiroes of hamaji の短縮法を模索中。 あと、soutaro さんの影響で echo にもちょっかい出し始めたり。 (こっちも全然お話になってない)

% [あなごる][OCaml] soutaro さんの while 1=1do に感銘を受けた

ので、for でも似たようなことを試してみた。

# for i=1to 5do print_int i done;;
12345- : unit = ()

これ通る(笑

要するに変数名と誤認される恐れが無ければ、スペースは必要無いってことなんだな。 でも、while にしろ for にしろこのネタを使うと vim の構文支援が効かなくなって書き(読み)づらいので、いきなりこう書くのは良くないと思った。 最後の仕上げで使おう。

% [あなごる][OCaml] やっぱりわしには、ゴルファーとして必要な何かが欠けているとしか思えない件

99 shinichiroes of hamaji はループするときの区切り方を見直すことで、多少縮んだんだけど、それでも 301B と上位陣に比べて絶望的なまでに差がある。

ぶっちゃけ、わしは「共通部分まとめ病」にかかっているので、共通する部分はどんどんどんどんまとめていってしまうんだが、ゴルフの場合必ずしもそれは良いことではないんだよな。 かえって長くなったりする。 とは言え、その損益分布みたいなのが感覚的に掴めてないから、とにかく適当にやってみるしかない。

ともあれ、さすがに 40B とか 50B の差があるってことは、わしが見落としてる何かがある気がするんだけど、いくら考えてもわからないので、一旦あきらめて他の問題をやることにしよう。 さすがに根気が保たない(苦笑

% [あなごる][雑談][Erlang] わしって頭固いのかなー?

固いんだろうな。年ですか?...orz

ところで密かにわし、あなごるに Erlang が追加されるの期待してたりするんだけど、あれって結構めんどくさそうなんだよね。 なんつーのか、分散環境に重点が置かれてる関係か、どこからでも開始できるためにどこからも開始しない、みたいな特徴があるわけ。 要するに C の main 関数みたいなエントリーポイントも無いし、かと言ってスクリプト言語全般のようにトップレベルに書いておくとそっから始まるみたいなのも無い。

じゃあどうしてるのかって言うと、.erl という拡張子のソース (モジュール) とは別に .script という拡張子のブートスクリプトファイルを用意して (これ自体はまた別のファイルから自動生成するものみたいだけど)、適宜必要なモジュールを読み込ませて適当なモジュールの適当な関数を呼ぶって感じらしい。 らしいってのは、つまりわしはブートスクリプトとかに手を出したことが無くて、ドキュメント斜め読みしただけの知識だから。

他には -s オプションで指定した関数を呼ぶことができるので、(参考→過去の日記)

% cat m.erl
-module(m).
-export([f/0]).

f()->
   % do anything.

みたいなファイルを用意しておいて、

% erl -compile m
% erl -noshell -s m f -s init stop

てな感じで使うとか、そういう感じ。

とにかく、あなごるに Erlang を導入するとなると、どうしてもあらかじめ何らかの約束事を決めておかないと事が回らないのが微妙というか何というか。 (上の例で言うなら、モジュール名は m で開始するポイントは f 関数にしましょう…みたいな)

% [あなごる] delete blank lines を awk で

や、OCaml では素朴な答えしか出せなかったんで、逃避で。 つーか awk はちょっとしか使ったこと無いんだけど、それでもこの問題は awk だとチョー簡単だということくらいはわかるので、ランキング見てみたら……

2B って?

チョー素朴な答えだと 3B になると思うんだけど、2B ってどんなだ? かじった程度の知識じゃわからない何かがあるんかねえ。

…と、しばらく man awk を眺めてて気付いた。 number of fields in the current record だ。 ……正解。

OCaml では、ちょっとせつない思いをしてるので(苦笑)、少しだけ嬉しくなる出来事であった。

% [あなごる] 開き直った

なんつーか、こう、あれだ。 周りの人達の成績を気にしすぎてはいかんな。 もう自分の凡人さ加減は十分すぎるほど身に染みたし、そもそものレベルが違う人を相手に、競争意識を持っても空回りするだけだ(苦笑

そんなわけで、わしはわしのペースでまったり楽しむことにしたよ。 別にダブルスコアだって良いじゃない。 いきなり良いスコア出さなくたって、だんだんと縮めていけば良いさ。 それがゴルフってもんだよ。

% [あなごる][雑談] や、まあなんつーか、どうでも良いっちゃーどうでも良いんだけど

7-0 とか 7-3 ってテニスのスコアじゃないよなー……とか。

テニス知らない人のために一応説明しとくと、通常は 6 ゲーム先取なので 6-0 とか 6-3 で終わるという話。 5-5 になったときだけは、それ以降 2 ゲーム差を付けないと終わらないので 7 まで行く。 んで、昔々はそのまま延々と終わらないなんてこともあったんだけど、今は 6-6 になると必ずタイブレーク (特別なルールで必ず決着を付ける) になるので、最大スコアは 7-6 ということに。


2007-02-16 [長年日記]

% [あなごる][OCaml] 各所で OCaml 用のノウハウが紹介されている模様

m.ukai さんや、shinichiro.h さんのとこ。 すでに気付いていることもあれば、目から鱗なこともあり。 ともあれ、ありがたく参考にさせていただきます。

% [あなごる] sh: ul: not found

キター…と思ったのに残念。 やっぱサーバと同じ環境が無いと、こういう方面はツラいなー。 でも今、手元に Linux 環境無いんだよな。 FreeBSD ならあるけど、Mac OS X と大して変わらんし。

% [OCaml] あなごる特別編、tennis を普通に書くの巻

あなごる、おもしろいんだけど、通常「読みやすく書く」というポリシー (実践できてるか否かは置いといて) のわしとしては、微妙にストレスが溜まるのも確か。 そんなわけで、息抜きのために (何か間違ってる気がするが) 短かくすることを全く考えないで素直にコードを書いてみることにした。 お題は tennis だが、昨日も書いたとおりこの問題は実はテニスじゃないので、テニスになるように改良を加えつつ。

% cat tennis.ml
type status = { games:int; player:string }

let is_tie a b = a.games = b.games

let is_finish a b sd =
   let fc = if sd then 7 else 6 in
   a.games = fc || b.games = fc

let winner a b = (max a b).player

let rec update_status a b =
   let input = read_line () in
   if input = a.player then
      { a with games = a.games + 1 }, b
   else
   if input = b.player then
      a, { b with games = b.games + 1 }
   else begin
      print_endline "bad name!! input again."; 
      update_status a b
   end

let rec play a b sudden_death =
   let x, y = update_status a b in
   let m, n = max x y, min x y in
   if is_finish x y sudden_death then begin
      Printf.printf "Player %s wins the set %d - %d\n"
         (winner x y) m.games n.games;
      exit 0
   end else
   if is_tie x y then
      Printf.printf "Set is tied at %d\n" m.games
   else
      Printf.printf "Player %s leads %d - %d\n"
         (winner x y) m.games n.games
   ;
   match x.games, y.games with
   | 5, 5 -> play x y true
   | _, _ -> play x y sudden_death

let main () =
   let a, b =
      if Array.length Sys.argv >= 3 then
         { games = 0; player = Sys.argv.(1) },
         { games = 0; player = Sys.argv.(2) }
      else
         { games = 0; player = "1" },
         { games = 0; player = "2" }
   in
   play a b false

let () = if not !Sys.interactive then main ()

特段、何か変わったこととかやってるわけじゃないので、まあ解説とかは不要だろう。 強いて言えば、OCaml の比較演算子はコレクション的構造に対しては再帰的に比較していくので、max や min が普通に使えるように、status の要素は games を先にしてるとか、そういう話はある。 比較のプライオリティが高いものほど、先頭側に置くようにするのがポイント。

5-5 になるまでは 6 ゲーム取った時点で終了するとか、起動時に名前を二つコマンドラインに渡しておけば、それを使った表示にしてくれるとか、間違った名前を入力したときは聞き直してくれるとか、そういう細かい機能が追加してある。

ところで、play 関数の最後のところや、main 関数の最初のところみたいなシチュエーションって結構悩むんだけど、こういうのってどうするのが良いのかな。 例えば play 関数の例で行くと、

match x.games, y.games with
| 5, 5 -> play x y true
| _, _ -> play x y sudden_death

というところ。 共通部分まとめ病患者としてみると、ついつい、ここは…

play x y (if x.games = 5 && y.games = 5 then true else sudden_death)

とか、

play x y begin
   match x.games y.games with
   | 5, 5 -> true
   | _, _ -> sudden_death
end

みたいに書きたくなっちゃうんだけど、これってやっぱ読みづらいよね。 そんな風に思って、読みやすいように…というつもりで書いてるんだけど、微妙に趣味と実益の狭間みたいなのを感じちゃうというか……

% [あなごる][Python] even lines

ちょっぴり息抜きで (だから何か違うって) Python に浮気してみた。 なんか OCaml はわし一人だけアプローチが違うみたいだなー。 それでも 1B 差に付けてるってのは、ある意味わしとしては奇跡的だ(苦笑

最初、知らずに input 使ってハマって、sys モジュールに逃げて 51B くらいだったんだけど、リファレンスをよくよく読んだら input は eval(raw_input(prompt)) と同じだって書いてやんの。 eval しちゃダメだよな(笑

ってことで raw_input 使ったらすんなり一位と同じスコアを獲得できた。 なんつーか、あまりよく知らない言語で挑むと、それなりに勉強になったりするね。

% [あなごる] そういや Statistics を公開するのがハヤりっぽいけど…

クッキーが名前しか憶えててくれないので、ついつい公開のチェックを入れ忘れたまま最短コードを通しちゃうと、もう公開できなくなっちゃうのが微妙に不便かも。


2007-02-17 [長年日記]

% [あなごる][OCaml] 空気読まずに Sys.command 使ったやつ入れちゃって、ごめんなさい @ delete blank lines

や、ほんと申し訳ない。 言い訳すると、試しに書いたやつ間違えて送っちゃったんすよ。

って、今見たら ksk さんが noexec バージョンでも登録してるな。 わしも 60B 切れたら登録します。

% [あなごる][OCaml] invert case

現在 63B で二位。 ksk さんと同じアプローチなのかどうかはわかんないけど、少なくともわしのやってることは C と同レベルで、OCaml のライブラリの貧弱さに苦笑するしかない。 禁断のアレも使ってます。

ためしに Python でもやってみたが、こっちはそのものズバリなメソッドが存在するので、誰が書いても同じ結果になってる模様。 Ruby にはあったっけな? あるとしても Ruby の場合は数値扱いした方が短いかもしれないけど。 Python は文字型って無いんで (文字列型しかない)、文字単位で扱うときも結局文字列だったりすんだよね。

% [あなごる][OCaml] げ、char_of_int の存在に騙されてた

こんな穴場にこんなものが。 魔法よりこっちの方が 1B お得。

これで 62B か、あと 1B って何だ?

% [あなごる][OCaml] Expression に OCaml プレイヤーがいないので一番乗りしてきたよ

やったぜ、初の単独首位!!

どうせ誰かが手を出した瞬間、落ちていくのは目に見えてるけど、一瞬でも輝いたさ!!

本日のツッコミ(全2件) [ツッコミを入れる]

% ksk [それで得をするということは,62Bは私と違うコードだと思います.具体的な想像はできないのですが….]

% jijixi [うーん、てことは方向性を変えないとダメか……]


2007-02-18 [長年日記]

% [あなごる] ぬぉっ!! Erlang が追加されてるぞ

さっそく hello world から、やっとくか。

うーん、-module とか -export とかのディレクティブは、どうしても改行が必要みたいだな。 あと、io:write('hoge') だと hoge じゃなく 'hoge' が出力されちゃうのでダメだった。 fwrite (もしくは format) を使うべし。 対話環境で試してると違いがわからんのがワナ(苦笑

% [あなごる][Erlang] それにしても、

hello world で 1.6 秒って時間かかりすぎ。 手元で試してみると、どうも init:stop() が時間かかってるみたい。 なんか後処理とかごちゃごちゃやってんのかね。

まあ、とりあえず処理が遅いってんじゃなくて、何を実行しても常に init:stop() の分、時間がかかるってだけだから、タイムアウトの心配はそれほどしなくても良いのかな。

% [あなごる] あり、サーバ刺さっちゃってる? (at 17:35)

さっき、つい Erlang で止まらないコード送っちゃったのが良くなかったなら、ごめんなさい。 というか手元では、適当なとこでクラッシュダンプ吐いて死んでくれるんで、それでも通るかどうか試してみたかったんすよ。

% [あなごる][OCaml] Booklet Printing

うごー、100B も差が。 完璧にアルゴリズム間違ってるなあ(苦笑

% [あなごる][OCaml] char リテラルの罠

なんか、

print_char'
'

みたいなコードが激しくエラーになるんで、しばらく悩んだ。

print_string"
"

はオッケーなのにナゼ? みたいな。 んで、よくわかんないから、

print_char'\n'

って書いたら、これもエラー。 もう混乱しまくって、どうしてじゃーと天を仰いだわけ。

…でも、よくよく考えると何てことないことだと気付いた。 つーか、あなごるに毒されすぎ。

print_char '
'

これで良い。もちろん

print_char '\n'

でも。 要するに、print_char' という識別子として認識されてたってことね。 そりゃそうだよな、普段 f' とかって名前平気で使ってるじゃん(苦笑

% [雑談] ここ数日、日記のネタがあなごる一色な件

ヤバい。ある種の麻薬(苦笑

とりあえず OCaml については比較的小康状態というか、まったり行こう、くらいのノリに移行しつつあったんだけど、そこに狙いすましたかのように Erlang 投入という。 まだ眠れない日々は続くのか……

ところで Erlang はゴルフ的にはすごく不利。 だって、必ず、

-module(a).
-export([m/0]).
m()->.

これだけは書かなきゃならないわけで。 -module と -export のとこの改行も必須みたいなんで、何もしなくても 34B も消費してしまう。 短い問題だと、他の言語と渡り合うのは無理。 長い問題でも、34B は結構でかいよなあ。 実際の処理の部分では OCaml よりずっと短くなりそうではあるんだけど。


2007-02-19 [長年日記]

% [OCaml] printf and positional specifier

当時は大して気にも留めてなかったんだけど、あなごるのせいでちょっと思い出したんでアーカイブから発掘。 要するに、Printf のマニュアルには、

The optional positional specifier consists of an integer followed by a $; the integer indicates which argument to use, the first argument being denoted by 1.

とか書いてあって、

# open Printf;;
# printf "%2$d %1$s" "abc" 2;;

とか書けそうな気がするんだけど、

Bad conversion %$, at char number 0 in format string ``%2$d %1$s''

って怒られる。どしたらいいの? という話。 結局何も解決策が無いままフェードアウトしちゃったんだけど、これが例えば、

printf "%1$s %1$s %1$s" "hoge"

とか書けて、

hoge hoge hoge

って表示されるみたいな感じだと、あなごるで役に立ちそうだよなー……とか思ったのであった。 まあ、実際は使い方わからんのだから、絵に書いた餅なんだけど。 もしかして知ってる人いませんか?

% [あなごる][Erlang] とりあえずコード書く前に…

使えそうな武器を物色するべくリファレンスを眺めてるところ。 ちょっとしたものなら書ける程度には知識があるつもりだけど、それだけじゃゴルフには足りないしね。 とりあえず眺めておく必要がありそうなところをメモ。

こんな感じか。 あと、場合によっては、

この辺りも。 それと sets, dict と同じインターフェイスで ordsets, orddict というのもある。

他には単品物で os:cmd/1 とか (インチキ用にはイマイチ向かないけど)。 あと string:strip(Str,both,$\n) の代わりに lib:nonl(Str) とか。

% [あなごる][Erlang] とりあえず頭使わないところは埋めとこう、とか思ったんだけど…

e で、↓こんなコードが、

-module(e).
-export([m/0]).
m()->io:fwrite("27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274").

exec is denied! って言われて通らん(死

何が起こってるんだ? と思って io モジュールとか、そっから参照されるその他のソースを見てみたけど、いまいちハッキリ原因は掴めない。 ただ、斜め読みした感じだと、io モジュール用のサーバプロセスにメッセージを送ってるみたいで、そのサーバプロセスは最終的に erlang:open_port で外部ポートを開いているっぽい。

open_port 関数は VM 組み込みらしくて、さすがにそこまで追いかける気にならなかったんだけど、リファレンスの説明を読む限り、外部コマンドを呼ぶものらしいので、どうやら exec 系のことをやってる予感。 っていうか vfork とか fork とか使ってるとか書いてあるのかな。

ってことは…… exec is denied な問題は Erlang で解くの不可能ってことでつか。 そ〜れ〜は〜死〜ね〜る〜...orz

えーと、もしできるなら、Erlang だけは exec is denied 縛りは無効に…とかしてもらえると嬉しいんですががが。 どうせインチキしても 34B のハンデがあるんで、少なくとも他の言語に対する脅威にはあまりならないんじゃないかと。 open_port は、やたら使うのめんどくさそうだし、os:cmd で echo とか使っても速攻で戻ってくるから意味無いし。

% [Erlang] IO 処理は外部におまかせ…に、なっている理由

たぶん、言語として副作用を排除するためなんだろうな。 つまるところ Haskell のモナドみたいなもんで。

io:format の説明を読めばわかるけど、この関数が返すのは ok っていう atom だけなんだよね。 どっかわかんないところに出力のためのリクエスト投げて、あとは知らんというスタイル。 Haskell で IO() が返ってくるようなもん。 まあ、実際にはリクエスト投げたあと、しばらく終了ステータスが返ってくるのを待ってるみたいだから、Haskell ほど知らんぷりではないみたいだけど。

というわけで、Erlang は OCaml に比べると随分と純粋に近い関数型言語なんだけど、プロセス毎に辞書を持っていて、それを使えば大域変数のようなものも可能なんで厳密に参照透明性が保証されてるわけではない。 ただ、プロセス辞書に別のプロセスが直接変更を加えたりはできないので (何にせよ他のプロセスに作用を及ぼすには、メッセージを投げて、あとは投げた先のプロセスが自分でなんとかしてくれるのを期待するしかない)、排他制御なんかが必要になることは無い。

そういえば、用意されてるデータ構造の中に、queue はあるのに stack が無いのは何でだ? と思ったことがあったけど、Erlang のデータ構造は全て関数的に作られてるので (要は更新する関数は、中身を直接いじるんじゃなくて、更新した結果の新しい構造を返す)、そういう形で stack を表現するなら結局 list で間に合っちゃうということなんだろう。

% [雑談] ところで Rimo は…

4ch がお薦めだよね。

% [あなごる][OCaml] 通常時は好きな言語ベスト 3 に入る OCaml だが

ゴルフ中だけはクソッタレと思うことも多いよね(笑

他の言語ならフリップフロップなんて n^1 で良いのに、なんだよ n lxor 1 って長すぎ。 かと言って even とか odd みたいな関数があるわけでもなく。 交互にどうのこうのって問題で、みんなはどうしてるんだろ。 やっぱ m.ukai さんの、

n/2*2=n

が一番短かいんだろうか。

本日のツッコミ(全10件) [ツッコミを入れる]

Before...

% shinh [ふむふむ。となると Erlang はユーザ側で自制してちょ、って感じの方針しか無い気がしますねぇ…今度少し調べてみま..]

% m.ukai [Printf の $ による引数並べ替えは魔法使えばとおせるようです。 # Obj.magic Printf.p..]

% jijixi [それは何ともがっかりな結果ですな(苦笑]


2007-02-20 [長年日記]

% [あなごる][OCaml] 通常は全く文句なんて無いんだが…

let rec が憎い。ゴルフ的に見て超憎い。 そもそも let からして憎いが、rec はもっと憎い。 そんなもん無くても暗黙で再帰しやがれ。

や、通常使用時は、むしろコンパイル時に間違いを発見しやすくなる要素の一つだと思ったりしてるんで、あった方が良いと思ってるんだけどね……

rec が無ければ、大抵の問題は再帰で書いときゃ間違い無いのに、こいつのせいで、よほどうまい再帰の仕方を思い付かないと while の方が短かったりすんだよ。 そのせいで、何度も何度も同じ処理を再帰で書いたり while で書いたり、あーもー。

% [clip] コンピュータ関連名言(迷言)集 (Geekなぺーじ)

via reddit.

おもしろかった。12 とかすごくウマイ。

% [あなごる][Erlang] IO がかなり隠蔽されてる関係か…

io:get_line は EOF が来ても例外を上げたりせず、単に eof という atom (シンボル) を返す。 なので…

m()->io:fwrite(io:get_line('')),m().

こういう関数は無限ループ。 結局 get_line を使う場合は、

g()->case io:get_line('') of
   eof -> halt();
   S -> S
end.

みたいなのを用意しとかんとあかん (もちろん一度しか使わないならインラインで書くけど)。 ゴルフ的には結構不利。 とりあえず EOF のときにいかに短かく死ぬかは、まだ研究の余地がありそう。

ところで、また submit サーバが死んでる(?)っぽいが、今度はわしのせいじゃない……よね? ……たぶん。 変なのは送ってない……はず。


2007-02-21 [長年日記]

% [OCaml][Erlang] 変換関数がややこしい

OCaml だと dest_of_src なんだけど、Erlang は src_to_dest なのね。 もうごっちゃになって、間違えまくるったら。 しかも OCaml の場合、場合によっては Array.to_list とかだったりするから手に負えない。

ところで Erlang では / 演算子は浮動小数点演算になる。 整数として割り算したいときは、中置の div を使わないといけない。 むー、ゴルフ向きじゃないな。

% [雑談][OCaml] rec で間違い発見しやすくなるか?

あー、それはあんまり深く考えずにノリで書いてしまった話なので、具体的に間違いを発見しやすくなる実例が思い浮かんでたわけじゃなかったり。 ただ、rec のおかげで凡ミスに気付いたということが何度かあった気がするのは確かなので、コストパフォーマンスはともかく、それなりに意味があるんだろうとは思ってますが。 でも、それは人によるのかも。

ところで『akr さんのハフマン符号がどうこうの精神』ってどんなのか思い出せない (読んだことある気はするんだけど) けど、「よく使うものの記述量は少なく」とかって話かな。 たしかにそういう意味では OCaml は失格だ。 Haskell のラムダ表記とか、たまにうらやましくなるし(苦笑

ただまあ、それって「書く側」の視点で言えばまさしく正義だけど、「読む側」の視点も混じえれば、必ずしも正義とは言えない気も。 Haskell でポイントフリースタイルを多用したコードとか、全く読みやすいとは思えないし。 Ruby が愛されるのって、書きやすいってだけじゃなく「書きやすくて、かつ、読みやすい」っていうのが理由な気がする。

% [あなごる][Erlang] Erlang は予想以上にゴルフ的に厳しい特徴を孕んでいる

昨日も書いたとおり、io:get_line は EOF が来ても勝手に死んでくれないので、勝手に死んでくれる他の言語に比べて厳しい。 io:get_line を囲む case 文を関数の返り値そのものにできる場合は eof の時の値を halt() じゃなく 0 とかにして短縮できるけど、それでも…

case of eof->0;end

これだけで 18B も食う。ただでさえ 34B のハンデがあるのに、さらにこれだと厳しいを通りこしてイジメじゃないのかと(苦笑

あとは OCaml の open みたいにモジュール名を簡単に省略する方法が無いのもツラい。 一応 -import() ディレクティブ (Erlang 的には Module Attributes と呼ぶのが正しいらしいが) ってのがあるけど、これって -export と同様に関数ごとに書かなきゃならない。 はっきり言って、短かくするためには全く無意味。

あとモジュール名の省略に使えそうな要素としてはマクロがあるけど、

-define(L,lists).
... ?L:map(...),?L:seq(...)

こんな感じなので、同じモジュール名をやたらたくさん使ってるとか、モジュール名が異様に長いとか、っていう状況じゃないと役に立たない。 実際、e を計算で求めるバージョンを書いたときには lists モジュールの関数を 5 回使ってるんだけど、5 文字のモジュールを 5 回じゃ元が取れなかった。 ゴルフで使いそうなモジュールで一番長そうな名前なんて、せいぜい string とか regexp とかだと思うけど、それだと 5 回以上使わないと元が取れない。

まあ、そんなこんなで、厳しいっす(苦笑

% [あなごる][Erlang] Expression でタイムアウト

なぜかいまだに OCaml でわしが単独一位の (や、一人だからあたりまえだが) Expression のコードを Erlang に移植して submit してみたんだけど、手元では普通にうまく行くにもかかわらず、どういうわけかタイムアウトで失敗する。うーん、なんでだろ?

submit サーバの調子がおかしいのかとも思ったが、試しに OCaml のコードを投げると普通に通るので、何か Erlang に特有の問題がある模様。 現状のコードは io:get_line の eof チェックをしてないんだけど (どうせ一回こっきりだから)、その前に eof チェック有りで submit したときも同様にタイムアウトだったんで、クラッシュしてるわけではなさそう。 無限ループは無くて、処理速度も問題が無いのにタイムアウトになるということは、io:get_line でブロックしてるくらいしか思い付かないが、だとするとどういうことだ?

うーん、stdin にデータが流れるタイミングの問題かなあ。 io:get_line がデータ待ちに入る前に入力データが流れちゃって因果地平の彼方へ→そこで io:get_line がデータを読みにいく→すでに行っちゃてるんでデータ来ずにブロック→タイムアウト、って感じ? よくわからん。

本日のツッコミ(全3件) [ツッコミを入れる]

% ksk [recは間違いが発見しやすいというよりも,毎回再帰だと思われると困るというのがあるのだと思います. let s=s^..]

% jijixi [あー、そうですよね。 どの言語だったか忘れましたけど、他の言語でまさにそういうことをやろうとしてハマって、暗黙に再帰..]

% m.ukai [Expression は手元で書いてみたんですが時間がかかりすぎて Timeout 食らうだろうと思って投げてません..]


2007-02-22 [長年日記]

% [Mac] AquaSKK のキーバインディングを変更する方法

Ctrl+J で改行するクセが付いちゃってるわしとしては、skk デフォルトの Ctrl+J でひらがなモードってのが激しくウザいのである。 そんなわけで、AquaSKK のデフォルトキーバインディングも激しくウザいので、結構前から設定を変更して使っている。 でも、この設定の仕方を探すのに結構苦労したんで (もはやどこで見つけたのか憶えてないし)、同様に不満を持っている誰かのために、ここに書き記してみる次第。

…と、ここまで書いて、なんかこのネタすでに書いたような気もしたんで検索してみたけど、とりあえず見当たらないんで、まあ書いとこう。 もし、かぶってたら、それはわしの脳が劣化しているせいである。

ともあれ、やり方自体は簡単。 ソースの Resources/config というファイルを参考に ~/Library/AquaSKK/config を編集するだけ。 あとは次回ログイン時から有効になる (ただし画面上の表示は変わらないので我慢)。

まあ、それだけ。 ……それだけなんだけど、これが何だか微妙に変で。 例えば、わしがやりたいのは Ctrl+O でひらがなモードだったりするんだけど、その場合いじるべきなのは、kana-mode-key じゃなく kakutei-key だったりする。 んで、変換を確定するキーの設定が kana-mode-key 。 どう考えても設定が逆になってる。 しかも、確定キーは Ctrl+J にしたいんだけど、kana-mode-key を "\C-j" に設定すると強制的に kakutei-key の方の設定も Ctrl+J に上書きされてしまう。 要するに、『確定が Ctrl+J でひらがなモードは他のキー』っていう設定ができない。 結局現在は、Ctrl+M で確定、Ctrl+O でひらがなモード、っていう設定で我慢してる。 ちなみに、しばらく前まではひらがなモードは Ctrl+K にしてたんだが、Emacs を使うときにこのキーが取られると不便なので変えたのであった。(まだちょっと慣れてない)

そういや、この辺の設定がおかしい件については、ソース読もうと思いつつ放置してるなあ。

(追記) 気になって試してみたら、記憶違いしてたみたいだ。 確定を Ctrl+J に設定しても、ひらがなモードを他のキーにできるんだけど、Ctrl+J で確定しようとすると確定されずに変換中の文字列が消えちゃうという謎の挙動をする。 だから、実質使い物にならないので、結果的に『確定が Ctrl+J でひらがなモードは他のキー』という設定はできないってことになる。

% [vim] ついでだから skk.vim の設定も

まあ、これは skk.vim のファイルを眺めればわかることなんだけど、.vimrc に

let g:skk_control_j_key = "<C-o>"

と書いとけば、Ctrl+O で skk モードの ON/OFF ができるようになる。 でも skk モードのまま l で英数モードにした場合に、かなモードにするキーはなぜか Ctrl+J のまま。 なんかこれも微妙にバグっぽいんだよな。 かなモードキーをカスタマイズする変数は設定されてないし、skk_control_j_key の説明には『<C-j> の働きをするキー。』と書かれてて、これを素直に解釈すれば元々 Ctrl+J に設定されてる機能は全部変更されないと変な気がする。

どうにも AquaSKK と skk.vim で操作法に一貫性が無いんで、ほんとは vim でも AquaSKK を使えばすっきりするんだけど、Terminal.app は Ctrl 修飾のキーイベントを IM に回してくれないみたいで、Terminal.app 上で AquaSKK を使うときは Command+Space で IM を切り替えなきゃいけない。結局一貫性が無いんだよな。 MacPorts の vim +aqua でできる Gvim.app はインライン入力が効かないから論外だし。

いつか何とかしよう…と思い続けて、結局めんどくさくて『直すより慣れろ』な状況になってるダメさ満点なわし...orz

% [あなごる][Erlang] うーむ、ultimate problem でタイムアウトはさすがに問題があるような…

いくらなんでも、↓こんなコードがタイムアウトするのは、どこかおかしい気がします(苦笑

-module(u).
-export([m/0]).
m()->io:write(42).

shinh さんが何とかしてくれるのを期待しつつ、Erlang は、しばし封印。 ちょっぴり Ruby に手を出そうかと思ってみたんだけど、ためしにちょっと書いてみたやつが、あまりにもお話にならないレベルだったんであきらめましたよ、ええ。 ただでさえゴルフの才能無いのに、こんなゴルファー御用達みたいな言語は使いこなせません(笑

% [あなごる][雑談] Erlang のコードを直接実行するシェルスクリプトを書こうと思った

…のが一昨日の話。とりあえず vim erlrun とかやって、

#!/bin/sh

と書くまでは 5 秒で終わったんだけど、その後が一向に続かない。 単純なものなんで、仕様というか、何をどうすべきかはすでに頭の中できあがっていて、あとは淡々とコーディングしていくだけなんだが、全然コードが浮かんでこないわけ。 結局 5 分くらいかけて、

if [

まで書いた(苦笑)ところであきらめて、一行目を…

#!/opt/local/bin/ruby

に書き変えたら 3 分でできあがった。 まあ、テストとデバッグで、さらに 3 分くらいかかったけど (ARGV の構造とか細かいとこは忘れてるんで)。

なんだか、ちょっと火をつけるだけなのにマッチの使い方がわからなくて、しかたなくガスバーナーを探しに行っちゃうようなダメっぽさを感じてしまって、苦笑い。

tcsh 使ってた頃は、ちょっとしたことは csh スクリプトで書いてたりしたんだけど、zsh に乗り換えたのを契機に sh スクリプトで書くように改めて (つーか sh を憶えないと設定ファイルが書けないからさ)、そうこうするうちに csh の方はすっかり忘れてしまって、かと言って sh の方もかなり知識があやしい状態のまま今に至るという感じ。 読めることは読めるけど、いざ書こうと思うと全然出てこない。

そして Ruby に逃げる。 なんかダメっぽい。 ダメっぽいけど、Mac OS X なんかだと Ruby は標準添付なわけで、sh 使うのと変わんねーじゃん…という気もしなくはない。 なんかクールじゃないけど。

% [vim] skk.vim の設定続き

良い機会なんで、AquaSKK と skk.vim の挙動が近くなるようにがんばってみようと思った。 んで、AquaSKK のソース読むよりは skk.vim を読んだ方が楽そうなんで、まずは読む。 とりあえず現状の設定だと、AquaSKK の場合 l で英数モードになった場合に次にひらがなモードにするには Ctrl+O なわけだけど、skk.vim だと Ctrl+J になっちゃうのが混乱の元。 なので、その Ctrl+J の役割を Ctrl+O に割り当てるか、skk 自体の ON/OFF は Ctrl+O に設定できてるので l で skk を OFF にできれば目的は達成できる。

そんな感じで調べた結果、Ctrl+J がハードコーディングされてる部分を見付けて、そこを Ctrl+O に直してみたんだけど、なぜか英数モードの時に Ctrl+O 押しても skk の ON/OFF 機能の方が優先されてしまって一旦英数モードになると、ひらがなモードに戻れなくなるので却下。 最終的に l の機能を上書きする方法を見付けて、それを使って対処することで幸せになれた。 ↓こんな感じ。

let g:skk_user_rom_func_rules = ""
         \. "l  SkkMode(0)\<NL>"

書式は skk_rom_func_rules を定義している箇所を参照。 SkkMode というのは skk の ON/OFF をする関数で、non-zero を与えれば ON。 これと、さっき書いた

let g:skk_control_j_key = "<C-o>"

とを併せて、AquaSKK に近い挙動になる。

ちなみに skk_user_rom_kana_rules という変数を使えば、ローマ字かな変換のルールを追加できる。 わしは↓こんなの書いてる。(わかりづらいけど、z→スペース、で全角スペース。他の z 系のルールは大体すでに設定されてるので、必要無い)

let g:skk_user_rom_kana_rules = ""
         \. "z   \<NL>"

あと、↓こうしとくと、insert モードでの skk の ON/OFF 状態を記憶してくれるようになるので、gvim の iminsert=2 のような挙動になる。 好みにもよるけど、便利なときは便利。

let g:skk_keep_state = 1

他には↓これで、何回変換キーを押したら候補一覧が出るかの制御。

let g:skk_show_candidates_count = 3

他にもいろいろ設定項目はあるけど、わしが設定してるのはこの程度かな。 あ、もちろん辞書の設定とかはしてるけど、そこら辺は基本だからここには書かない。


2007-02-23 [長年日記]

% [Mac] ヒラギノよりK14がいいという人は…

東風フォントを入れて、アンチエイリアスをオフにして使うと幸せになれるかも。 たしか東風の埋め込みビットマップの 14 ドットは K14 だった気が……あれ、違ったっけ? 東風じゃなくても、さざなみとか IPA フォントとか、何か K14 を埋め込んでるのがあったはず。

TTF ファイル (kochi-gothic-subst.ttf とか) を /Library/Fonts とか ~/Library/Fonts に突っ込めばすぐ使えます。 14 ドットでもアンチエイリアスがオフになるようにするには、なんだっけ、とりあえず Terminal.app はフォントの設定でオフにできるし、システム全体でオフにしちゃうには、えーと名前が出てこないからすぐには調べられないけど、そういうことするソフトがあるんで、それを使うと良いです。

究極的には、X 入れて、必要なものは全部 X 使うものを揃えちゃうのも一つの手。 つーかわしは、古くから Mac ユーザだけど、一時期ずっと FreeBSD で暮していて、その後メイン環境を Mac に切り替えたときには X 使いまくってましたよ。

ともあれ、たぶん shinh さんは単にアンチエイリアスに慣れてないだけなんではないかという気がする。 アンチエイリアスを前提にした (比較的安価で手に入る) 日本語フォントでヒラギノは最高級だと思うですよ。 あとは、印刷時の品質も兼ね備えてるんで (むしろ、よく聞く絶賛の声って印刷結果のことを言ってる気も)。

% [Mac][w3m] そういや最近 w3m-img が無い生活にも慣れてしまったなあ

mlterm から Terminal.app に乗り換えて以来、w3m-img を使うことも無くなってしまったが、すっかり慣れて不便に思わなくなってしまった。 と言うか、そもそも最近は JavaScript が使えないブラウザだとどうにもならないサイトが多すぎて、w3m 自体、日記を書くときか、怪しい URL を開くときくらいしか使ってないからなあ(苦笑

一応、External Viewer に以下のような設定はしてるけど、全然使ってないや。

application/pdf open -a /Applications/Preview.app %s
video/*         open -a /Applications/QuickTime\ Player.app %s
image/*         open -a /Applications/Preview.app %s

他には External Browser のところに、

/usr/bin/open %s

とか。

% [Mac] iTerm が良い感じになってきてる

shinh さんのとこにツッコミした手前、久しぶりに iTerm を使ってみたところ、以前は「機能はともかく、もっさりしてて使い物にならん」と思ってたものが、なんかそこら辺すごく良くなって Terminal.app と差を感じない程度に動いてくれる。 これは乗り換えを検討しても良いかもしれん。

ってことで、しばらく使ってみようと思った。

% [Mac][vim] iTerm は Terminal.app より AquaSKK と相性が良いかと思ったら、実はむしろ悪いかも知れないことがわかってきた件

iTerm はコントロールキー絡みのキーイベントもグローバルな方面に投げてくれるので、AquaSKK を使うときに便利かと思ったんだが、投げたはずのイベントをきっちり自分でも処理してくれるので、例えばわしのように Ctrl+O を AquaSKK のひらがなモードに割り当ててるとすると、端末上の vim やなんかにもきっちり Ctrl+O というキー入力が渡ってしまう。

…で、vim では挿入モードにおける Ctrl+O は連鎖コマンド用に予約されている。 要は Emacs の ^X とか ^C みたいな役割。 んで、これが imap とかで上書きできないもんだから、どうにもならない。 かと言って、前に使ってた Ctrl+K も特殊キーの入力待ちになるキーなので似たようなもん。

つーか、vim の Ctrl+O に割り当てられてる機能は、どのモードでもわしは使わないものばっかりなんで、この無駄にイベントを取りこぼさないようにする仕様が無ければ全て丸く収まるんだが……

Ctrl+K と Ctrl+O の他に、どのモードでも必要の無いキーって思い付かないんだよな。 まあ、どっちにしても l で英数モードにするときにもいちいち l って入力されちゃうし、どうにもこりゃダメだな、わしのライフスタイル (つーか主に vim) に合わなすぎる。

その他の部分は、結構気に入りかけてたとこなんで、ちょっと残念だが、やっぱり Terminal.app に戻るとしよう。

% [あなごる][OCaml] いろんな人がネタばらしを始めているんだが、わしはそれを読むべきか否か非常に悩ましい

なんつーのか、わしのレベルから言って、「ネタバレを見たらつまらなくなる」ではなく「ネタバレを見たら自信を喪失する」からなんだけども。 や、自信なんてあったのか?っつーと、別に無いわけだが、自分のセンス無さを思い知ってぐったりするのはイヤだなあ…と(苦笑

幸いなのは、ゴルフなコードはうっかり目にしてしまっても、じっくり見ないと意味がわかんないので、あえて「読もう」と思わないかぎりは、うっかり読んでしまうことはおそらく無いだろうということで。

……やっぱ、もう少しほとぼりが冷めてから読もう。


2007-02-24 [長年日記]

% [雑談] 唐突に脳の機能が低下している

要するに風邪気味で、なんかボーっとしてる。 何もする気になれん……


2007-02-25 [長年日記]

% [雑談][Mac] Mac OS X に X 入れると負け…みたいに思ってる人が結構いるみたいだけど…

気にしすぎなのと違うかなあ。 別に使えば良いじゃん普通に。 せっかく Apple がオフィシャルにパッケージ作ってるんだし (と言うか、OS に含まれてる)。

わしがなるべく X なアプリ使わなくても済むようにしてるのは、単に X サーバの分のメモリ消費がもったいないと思うからで、必要な時には普通に使ってるし。 GIMP とか。

Mac OS X で X Window System を使うのが不健全だと言うなら、Windows で coLinux を常用することの方がよほど不健全だよなー。 まあ、フルスクリーンモードで X11.app を使うとかっていうなら不健全だと思うけど、さすがにそういう人はそろそろ絶滅危惧種だろ。(以前は結構いたみたいだが)

とは言え、何でもかんでも X 使えば良いじゃん…とか言ってるとバッドノウハウスパイラルに巻き込まれて、新しいものが生まれなくなるんで、代替物を作る能力のある人はどんどん作れば良いんだと思う。 わしはあんまり作れる方じゃないんで、バッドノウハウに埋もれていくわけだが。

% [Mac][w3m] w3mimg を試してみた

おお、ちゃんと表示されてる (@ iMac G5)。 こういうのささっと作っちゃうなんて、えらいなあ、shinh さん。

表示される画像の位置が、w3m が用意するプレースホルダよりちょっと左上方向にずれてるのが気にならなくもないけど、とりあえず十分実用になりそう。

とは言え、元々わしは Load inline images automatically オプションは NO な人。 んで、~/.w3m/keymap に、

keymap C-I DISPLAY_IMAGE

とか書いておいて、必要なときに Ctrl+Shift+I で画像を表示させたりとか、そういう使い方。 要するに、画像が無いと何が何だかわからないページ以外は、インラインイメージはオフという使い方をしてたので、(そういう時は他のブラウザで表示しちゃえば済むから) w3m のインラインイメージ表示に対する依存度は元々高くなかったのであった。

% [Mac][w3m] この前書いた External Browser の話

今、ふと試してみたら、なぜか Safari が起動してアレ〜?ってなった。 そういや、これって Safari を常用してた頃に試したっきりだっけ。

あ、ところで Safari を常用するなら、Safari Stand は必須アイテムなので入れておくべき。

ともあれ、外部ブラウザは OmniWeb が開いてもらわないと困るので、前回書いた、

/usr/bin/open %s

を、

/usr/bin/open -a /Applications/OmniWeb.app %s

に、変えて終了。 なんかデフォルトブラウザの指定の仕方がころころ変わるのか、OS のバージョンが上がるたびに open コマンドの動きが変わったりして微妙なんだよな。 OmniWeb も、ちゃんとデフォルトブラウザとして扱われることもあれば、扱われずに何故か Safari が開いちゃったりすることとかもあって、すごく微妙。 Firefox だとどうなんだろう。デフォルトにしたこと無いからわからんな。


2007-02-26 [長年日記]

% [あなごる][OCaml] e で 79B

ksk さんのとこで。 えー、どうやってんの、これ?

バイナリ使うインチキは、わしもちょろっと考えてはみたんだけど、どれも 115B を切れそうには思えなかったんであきらめてたんだよな。 あー、すごく気になる……

% [Mac] Terminal.app の tips

実は Terminal.app のウインドウは、コマンド+数字でフォーカスの切り替えができる。 でもデフォルトの状態だと、どのウインドウがどの数字に対応してるかわかんないから、イマイチ使い出が無い。

そんなときはターミナルインスペクタのウインドウタブで『コマンドキー』のチェックを入れると、ウインドウタイトルに、そのウインドウに対応したキーが表示されるようになるので、あとはそれを見て切り換えるようにすれば良い。 ついでにカラータブで見づらくならない程度に透明度を上げておくと、重なって下になってるウインドウのタイトルも読めるようになってなお良い。

わしの場合、キーボードから手を離さずにウインドウを切り替えたいシチュエーションって、端末をいじってるときくらいしか無いので (エディタも端末上で vim だし)、これで十分だったりする。 他のウインドウいじるときは、どっちみちマウス使うことになるんだから、それなら Expose で十分だ。

ちなみに Expose もマウス使うほど直感的じゃないけど、ウインドウ一覧状態にしたあと、tab でアプリケーションごとの選択とか、矢印キーでウインドウ選択とかできるんで、一応キーボードだけで操作できる (決定は Return キー)。 ほんとは矢印キーだけじゃなく、Ctrl+F,B,N,P あたりを使って選択できるなら嬉しいんだけど、残念ながらそれは不可。

% [雑談] 世の中には screen が大好きな人がたくさんいるが

わしはわりとどーでも良いと思っちゃうタイプ。 あ、セッションがブツブツ切れるような環境でリモート操作するときなんかは便利だと思うが、ローカルな操作ではありがたみがよくわからないというか。

複数のシェルを使いたいなら、複数の端末立ち上げれば良いじゃん、と思っちゃうし。 デカイ一つの端末窓を分割して使うくらいなら、小さい手頃なサイズの端末窓を複数使った方が便利だと思うんだけどね。 その方が他のアプリの邪魔にならないし。

端末間の移動はさっきも書いたようにキーボードでできちゃうし、他に screen のありがたみってあったっけ。 キーボードだけでコピペができる? vim 内部ならそもそも必要無いし、その他のシチュエーションって滅多に無いなあ。 せいぜいコマンドの実行結果を日記に貼るときくらいか。

端末の表示エンコーディングをウインドウごとに切り替えられる、とかもあったけど、Terminal.app では必要な状態に設定したウインドウを『別名で保存』で保存しておけば、utf-8 でも euc-jp でも好きに使えるし、あんまり必要無い。

そういや、わしが screen をあまり使う気になれない理由の一つに、Terminal.app のスクロールバッファが意味を為さなくなる、ってのがあるな。 まあ実用上は、screen の側でバッファを操作すりゃ良いんだから良いんだけど、それならそれで必要の無いスクロールバーは消したくなるのが人情。 でも Terminal.app って、それができないのよね。 結局消せないんだったら、スクロールバー使った方がマシじゃん、とか思っちゃうんだよなー。 あと、スクロールバーだったらホイール使えるしさ。

いくつも screen の啓蒙記事を読んだ気がするけど、いまいちわしの心に響くネタが無いんだよな。 それでも、FreeBSD で暮してた頃は結構使ってた (別窓開く分のメモリがもったいなかったから) んだけど、今の環境になって、そこら辺気にする必要が無くなったら、どうでもよくなってしまった。

% [あなごる][Erlang] Little Endian Calculator

短かく書ける自信は無かったけど、ネタ的に bit syntax を使って遊ぶのに丁度良いと思って書いてみた。 380B だった。短縮のための努力を全くしてないせいもあるけど、とにかく長い。

……いやまあ、長さはともかく。 タイムアウトで通らない...orz

なんか何を書いてもタイムアウトなんで、ただでさえ自己満足なのに、さらに自己満足度が高まってるというか何というか(苦笑

なので、何となく bit syntax 使ってる to little endian のとこだけ抜き出して晒してみる。

I=list_to_integer(X),
lists:map(
   fun(A)->io:format("~.16b",[A]) end,
   lists:reverse(
      lists:dropwhile(
         fun(Z)->Z==0 end,
         binary_to_list(<<I:4/unit:8>>))))

ところで、io:fwrite と io:format は名前が違うだけで同じ関数なんだけど、どっちかと言うと fwrite の方が名が体を表わしてる気がする。 ってことで、そっちを主に使ってたんだけど、どうも fwrite より format の方が個人的にタイプしやすいんで、最近は format を使うようになりつつあったり。 ……激しくどうでも良いな。

ほんとは bit syntax のとこを、

<<I:4/little-unit:8>>

にすれば、いきなりリトルエンディアンで持ってこれるんだけど (デフォルトはビッグエンディアン)、それだといらない 0 を落とすのがめんどいので、こんな形に。 そこら辺がんばれば、もっと短くなりそうな気もするんだが。 何はともあれ、bit syntax は他の言語ではあまり見ないちょっとおもしろい機能なんで、いじってると何か楽しい。

本日のツッコミ(全1件) [ツッコミを入れる]

% ksk [> e で 79B まだ詳しくは言えませんが誰か他の人が100Bを切った時点でヒントを公開しようと思っています. S..]


2007-02-27 [長年日記]

% [雑談] nohup(1) が嫌いだ

tcsh から zsh に乗り換えたときに、csh 系→ sh 系の違いを別にして一番困ったのが nohup の問題だった気がする。

csh/tcsh には組み込みの nohup コマンドがあって、わしは結構よく使ってたんだけど、zsh にはそれが無いので結果外部コマンドの nohup(1) を使うはめになる。 なるんだが、これがどうにも慣れ親しんだものと違うんで、想定している使い方をしようとすると不便でしょうがないわけだ。

nohup(1) の何が気にいらないって、問答無用で出力をファイルにしてしまうのが気にいらない。 csh/tcsh の nohup は、特に指定しないかぎりは通常のコマンド実行と同じように端末に出力を吐くので、リモート作業のときなんかに、長くなりそうな作業に「とりあえず保険として」付けておくという使い方ができる。 当然、そういう長くなる作業の場合 script を使うのは csh 系ユーザの嗜みなので、端末に出力しつつ、万が一ネットワークが途切れても大丈夫という状態を簡単に作れるわけだ。 その点、nohup(1) はそういう…なんというか適当さが無いというか、放置して後から結果を見るのを前提とした作業にしか使えないのがダメ。

ついでに言うと、tcsh では nohup で始めておいて、途中でネットワークの接続を切る必要ができたら、Ctrl+Z でサスペンドして bg でバックグラウンドジョブとして再開させれば、そのままログアウトできちゃうから、後から attach できないことを除けば screen いらずだったんだよな。 というか、screen の存在を知らなかった頃はこれですごしてたし。

組み込みコマンドといえば、nice と nice(1) の違いも結構困ったものだ。 組み込みの nice はプライオリティのデフォルトが +4 なんだが、nice(1) は +10 だったりとか、あとそもそも引数の書式が全然違ったりとか、とにかく混乱した。 さすがに nohup と違って nice は無いと困るんで、それなりに憶えたけど、おかげでもう組み込みの方の使い方は忘れちゃったよ……

今ではすっかり zsh に安住してしまってるが、それでもいまだにわしはインタラクティブシェルとしては csh 系の方が良くできてると思ってる。 まあ、tcsh の良いところは、かなり zsh にも取り込まれてはいるんだけど。 つーか、そうじゃなかったら、いくら zsh が高機能でも乗り換える気にはならなかった気がするし。

% [あなごる][Erlang] 一応合法的な e

OCaml でバイナリ使うやり方はまだ思いつかないので、Erlang に逃避。 相変わらずタイムアウトで通らないので、めんどくさいからここに晒す。 114B.

-module(e).
-export([m/0]).
m()->io:write(32#cdm3mh8tk2cvbrsojnvoaova5uot2pr7o5u915f1hqp2i9r6l8o0aj22i4vo10e0kci).

Erlang の整数は多倍長で、しかも 32 進数リテラルが使えるのである。 というか、2 進数から 32 進数までよりどりみどりなのである。 13 進数とか、29 進数とか、変態的なのだってオッケーさ。 よくわからんとこがスゲーぜ(笑

ちなみにこの数値は、

Eshell V5.5.2  (abort with ^G)
1> io:format("~.32b\n",[271828182845904523536028747135266249775724709369995957
49669676277240766303535475945713821785251664274]).

とかやって調べた。

% [あなごる][OCaml] バイナリで e (失敗編)

そういや、短かくなりそうだけどめんどくさいから試さなかった案が一つあったのを思い出した。 で、あー、めんどくせー、とボヤきながらやってみたら、86B になったので「お、これは」と思ったんだが、なんか思ったような結果が表示されないな……なぜだ。

とりあえず、この線でもう少し研究してみる。

(追記) あー、ダメだこりゃ。手抜きすぎか。 でもある程度手抜きのエンコード法じゃないと、短かくならない気がするんだが、うーん……

% [あなごる][OCaml] バイナリで e (とりあえず 94B)

すんげー手作業(苦笑

夢中になってるうちに airobo さんに先を越されてたが、多分アプローチは同じ気がする。 Statistics の違いは単にどこで区切ってるか程度じゃなかろうか。

しかし、こっから 10B 以上も縮めるなんて、一体どうすんだ?

本日のツッコミ(全7件) [ツッコミを入れる]

Before...

% jijixi [> &! はどうですか あ、これは結構良いかもです。 いきなりジョブコントロールの範囲外に飛んでいってしまうのが微妙..]

% odz [今さっき zsh のソースを読んでいて気づいたんですが、 setopt nohup setopt nocheckjo..]

% jijixi [なんだか、setopt nohup は良さげなにおいがしますね。 少し調べてみたいと思います。]


2007-02-28 [長年日記]

% [雑談][Mac] って言うか、Osaka-等幅 (の ASCII 部分) と Monaco は同じフォントなわけだが

などとボソリ。(参考資料)

% [Mac][Emacs] Carbon Emacs のフォント

細かい設定の仕方とか知らないんだけど、とりあえずメニューの Help -> Carbon Emacs Package -> CJK Fixed-Width Fontset にチェックを付けとけば、普通に Osaka-等幅になってくれてて、それで十分だと思ってた。

そういや、そのチェックを入れる入れない関係無く、デフォルトのフォントは Monaco ベースだと思うんだけど、どっかで Carbon Emacs のデフォルトフォントがコーディングに向かないとか書いてあって「はあ?」と思ったことがあったな。 どう考えても Monaco はコーディング向きのフォントだと思うんだが、実は Carbon Emacs を自分でビルドしたりするとデフォルトフォントが違ったりするのかね (わしのはここから拾ってきたもの)。

% [feed] 最近 livedoorReader でここのフィードが異様に早く更新されるようになった

一応動作確認というか、ちゃんと RSS が生成されてるかどうか確認のために自分の日記も LDR に登録してあるんだけど、以前は一日一回程度だった更新が、なんか妙にたくさんされるようになったのか、日記の更新結果が速攻で反映されるようになっててびっくりした。

以前から登録数によって更新頻度が違うような気がしていたんだけど、ちょうど最近うちの日記の登録数が 50 を越えたんで、もしかするとそのタイミングで変わったのかも知れない。

% [Mac] まあ、フォントは非常に好みの差が出るものだと思うけど

Monaco がコーディング向けなフォントだ…という話に対して、『うちで見ると I がありえんですね。 l や 1 と区別つかなさすぎというか。』って、そんなバカな!と思ったんだけど、そうか、shinh さんはアンチエイリアス切ってるんだっけ。 確かめてみると、確かにアンチエイリアス無しで埋め込みビットマップなサイズだとツラいかも。 つーか、もともとこんなデザインだったかなあ……

えーと、ともあれ訂正で、Monaco (や、Osaka-等幅) はアンチエイリアス有りに限りコーディング向きのフォントだ…ということで。 アンチエイリアス有りの状態で I と l と 1 の区別がつかないってことは、さすがに無いと思うんだが。

% [雑談] わしの場合、コマンド名が長いだけならエイリアス設定はしないなあ (補完が効くし)

書くの忘れてたが、向井さんとこの、

こういうエイリアスの設定は、べつにzshに限ったことではないと思うのだけど、やってるひとってどんだけいるのかな。

という話。でも、わしも、

alias less=lv

は、やってるなあ。 こういう「指が憶えちゃってる」系は、やっておかないと結構ストレス溜まるし。 他には、

alias w3m='w3m -B'

とか。実際は LANG に応じて -Oe 付けたり -Ou 付けたりもしてるが。 あと、LANG=ja_JP.UTF-8 のときには、

alias ls='ls -v'

とか。

今見ると、環境が変わったせいで、すでに使ってないけど何故か残ってるのとかもあるな。 こんなのとか。

alias ochelp='w3m /usr/local/share/doc/ocaml/html/index.html'

ヘルプが HTML で用意されてるものはみんな w3m で見ていたんだけど (なんか OCaml の他にも 5 個くらい登録されてる)、最近は OmniWeb で見るようになっちゃったから使ってない (というか、今の環境に合わせた修正すらしていないし)。 まあ、こういうのは単にブックマークしとけよ、って話もあるけど、ブックマークが無駄に太っていくのが嫌いなお年頃だったんだよ、たぶん(謎


トップ 最新 追記

日記ってのは本来、自分で読み返すためにあるもんだよなあ……
もしくは有名人になったら死後に本になったりとかか?

RSS はこちら

jijixi at azito.com