(rubikitch loves (Emacs Ruby CUI Books)) このページをアンテナに追加 RSSフィード

2008-06-23

[][]リストの総和

はてなダイアリー

applyがあるじゃない。

gosh> (define l '(1 2 3))
l
gosh> (apply + l)
6

Common LispEmacs Lispでも。

(apply #'+ '(1 2 3))                     ; => 6 (#o6, #x6)

2008-05-24

[][][]配列の先頭要素が「0番目」であることは気持ち悪いか…「N番目」という言葉考察してみる

JavascriptやPHPの配列や関数などで 配列の最初の要素がary[0]に.. - 人力検索はてな

言語RubyLispなど多くの言語では配列は0起点である。つまり、先頭の要素のインデックスは0である。

なぜそうなっているか‥それは実装上の都合であったり歴史的理由だったりする。

言語配列は「連続したメモリ空間の、先頭アドレス」で表現している。そして、オフセットを進めることでそれぞれの要素にアクセスしている。だから配列の最初の要素を「0番目」とすることでアドレス計算が楽になるわけだ。

多くの言語はC言語の文法を拝借しているし、C言語は十分普及しているから、「C言語にあわせて配列は0起点でいいや」となっていると推測している。コンピュータ世界じゃ歴史的理由ってのがけっこう多い。

そういうわけでプログラマ配列の要素を数えるとき、勝手に「0番目」→「1番目」→「2番目」と数えている。新しい言語でも0起点とするのは、プログラマにとって自然だ。

しかし、日本語の観点では「0番目」というのはいささか気持ち悪い。「日本語」では、順番に並んでいるものの先頭は「1番目」として数えるからだ。

気持ち悪いのは確かなんだが、こうは考えられないか?「N番目」という言葉は、プログラミングの文脈では「インデックスがN番目」という意味にオーバーライドされていると考えるのだ!言葉なんて文脈によって意味が異なるじゃん。「鯖」という言葉をとってみても、一般的な意味では魚のサバだが、インターネットの文脈ではserverを意味する*1

それでもいささか気持ち悪いのは、(0起点の)「N番目」という言葉は、通常の日本語意味の(1起点の)「N番目」という言葉で表現できてしまうからだろう。Rubyなどのオブジェクト指向プログラミング言語でいえば「super」だ。

この「N番目」という言葉はかなりの曲者で、プログラミングの解説の文脈でも0起点だったり、1起点だったりするのだ!

たとえば解説でインデックスが「+1」されていれば普通の日本語の「N番目」という意味だ。

ary = [:foo, :bar, :baz]
ary.each_index do |i|
  puts "#{i+1}番目の要素は#{ary[i].inspect}です。"
end
# >> 1番目の要素は:fooです。
# >> 2番目の要素は:barです。
# >> 3番目の要素は:bazです。

一方、Array#[]の解説では「N番目の要素を得る」と書いてある。これは0起点の「N番目」が使われている。Array#[]の解説で「N+1番目の要素を得る」と書かれているのはほとんど見かけない。これは…理解のしやすさ、文章のすっきり度なんだろうね。

こんな感じでプログラミング解説で「N番目」という言葉が出てきたら、プログラマ脳内無意識に「0起点かな、1起点かな」と考えさせられる。脳味噌のCPUタイムの無駄である(笑)それでも、経験的にプログラミング解説では0起点の「N番目」が使われていることが多いようだ。

どうしても気持ち悪いのが抜けないならば、いっそのこと新しい表現を使えばいいじゃないか。(0から数えて)「N番目の要素」という表現を「インデックスがNの要素」と言い換えてみる。それなら間違いなく0起点なんだからね。

[2008/05/25]追記

ruby - 配列を1番目からはじめてみる - まめめも

class Array
  alias aref_org []
  def [](x)
    aref_org(x - 1)
  end
end

当然、これでは不十分です。 a[1, 2]やa[1..2]の場合に対応できていません。

他にも配列インデックスを扱うArray#values_atとか、Array#indexとかもありますし。

Array#begin、Array#begin=で起点を指定できればいいのですが…

Rubyオブジェクト指向だから $[ なんて嫌ですw

[2008/05/25]追記

404 Blog Not Found:perl - 配列を1番目からはじめてみる

$[ キターーーーーー(゜∀゜)ーーーーーー!!

Perlな人は「1からやり直しです」を「$[からやり直しです」って言うんだっけか。大昔0か1の代わりに $[ と書いてるのを見てコーヒー吹いたことがある。

[2008/05/25]追記

はてなブックマークコメントより。

これ、現実世界との接点がある説明で結構困る。「HTML上で1番目の<form>を配
列から抽出」と か。0番目の<form>ってあるの? みたいな。結局「HTMLで1番
目の<form>を配列の0要素目から 選択」とか妙な表現に

まったく…そうなんですよorz

やっぱりRuby配列は起点を指定できると嬉しい…もちろん組み込みで。

[2008/05/25]追記

先頭要素が「1番目」であるFortran - @author pyridoxin

FORTRANCOBOLBASIC(可変)の配列は1起点ですね。他にはどんな言語があるのでしょう。

しかしなんでCとその子孫達は配列の要素が0からなのだろうか?Fortranは1なのに?だれか教えて?

推測ですが、C言語FORTRANの問題領域が異なるからでしょう。C言語は機械寄りだからアドレス計算が楽な0起点になっています。

FORTRAN数値計算がメインだから1起点が無難なのでしょう。行列にしたって、左上の要素は1行目1列目の要素(A_1_1)であって0行目0列目の要素とは言わないでしょう。

*1隠語なんだけどね…。だから正式な文書で使ってはいけないのは言うまでもない。

2008-03-05

[]Lisp言語のカッコは慣れの問題

Schemeではじめての計算 - Mattari Diary

LispやSchemeは日常使っている中置記法ではないから慣れるまでが大変かも…でも慣れたら普通に読めるので。LispやSchemeは四則演算等他言語だと演算子で提供されるものも関数やマクロであることがポイント。「+」、「-」、「*」、「/」は演算子ではなくて関数名。で、「(関数名 引数 ...)」という文法になっているので、そういう形式に目を慣らそう。

Emacsを使うならばquack.elとscheme-complete.elを入れると快適になると思う。カッコの対応を目視で取ると挫折するので、カッコの対応を自動で取ってくれるエディタの習得は必須。

[]SとKしかないLisp

COSAK

ちょwカオスwww

2008-02-28

[]Gaucheはどう?

メモっぽい日記

Scheme処理系はいろいろある。作者が日本人のものはGaucheがある。goshコマンドで対話的環境になる。

2008-02-26

[]Schemeやるならまともなエディタを使おう

メモっぽい日記

Schemeは俺もけっこう好きな言語だ。set!とかはあるけど、雰囲気が正統派の関数型言語という感じで美しい。最近の言語は関数型パラダイムを取り入れているのが多いから、Schemeで学んだことは他のプログラミングにも生かせるはず。

SchemeにせよCommon Lispにせよカッコだらけだから、Emacs等カッコの対応を取るエディタは必須だ。絶対使え。そしてS式ベースの移動を覚えよう。でないと間違いなく挫折する。

俺も大昔Emacsにあこがれていた。懐しい…あのころは矢印キーでポイント動かせなかったな。C-p、C-n、C-b、C-fを覚えさせられた。