魔術師をめざして

魔術師を目指して、相場・数学・プログラム言語を研究しています。

プログラミング言語の形式比較

プログラミング言語の記述形式の比較をしてみたいけど、すべてについては無理なので、階乗計算を再帰でおこなう例で、PythonLuaRubyPerl、Io、C、JavaScript、Scala、HaskellOcaml の10のプログラミング言語を比較してみようと思う。それぞれ完全なコードではなく関数などによる定義で階乗計算を実現している部分のみを取りあげる。また、どの言語もここで採用したコード以外にの書き方も可能だが、ごく普通の共通の書き方をした。

# Python
def factorial(n):
  if n == 0:
    return 1
  else:
    return n * factorial(n - 1)

Python のコード記述方法は合理的であり効率的でもある。最もスッキリした形で書くことができ、あとから見てもわかりやすい。ただし、改行とインデントが重要な意味を持ち、コードの全体を一行に書くようなことはできない。好みの分かれるところだが、ぼくはよいアイデアだと思っている。

-- Lua
function factorial(n)
  if n == 0 then
    return 1
  else
    return n * factorial(n - 1)
  end
end

ぼくは Lua に注目しているので、2番目に取りあげた。Python に比べると冗長な印象があり、function が長い、then や end を書くのが面倒だという人もいる。ぼくの感覚だとそうは思わない。素朴なデザインを選択しているようでぼくは好感を持っている。また、then などを固定化していることで、迷いをなくし表記を統一する役にたっていると思う。コードの書き方を柔軟にすることにも役だつと思う。(この点についてはあとで述べたい)

# Ruby
def factorial(n)
  if n == 0
    return 1
  else
    return n * factorial(n - 1)
  end
end

Ruby の書き方は、こういうレベルにおいては Lua と似ていると思う。Ruby は then が省略可能だ。書いてもよいことになっているはずだ。これは便利なようだが、統一という面に対してはマイナスだろう。

# Perl
sub factorial{
  my $n = shift;
  if($n == 0){
      return 1;
  }else{
      return $n * factorial($n - 1);
  }
}

ぼくも大好きで、愛すべき Perl だけど、これから言語を選ぶ人にはお勧めしたくはない。Perl にはとても便利なアイデアが一杯詰め込まれていて、楽しいったらない。だけど、ぼくがお勧めするのは Python だ。

// Io
factorial := method(n,
  if (n == 1,
    return 1,
    return n * factorial(n - 1)
  )
)

とってもキュートな Io だけど、処理系の安定度やライブラリの充実度など、まだ実務には向かない段階ではないだろうか。趣味で使うのなら最高に楽しいだろう。

/* C */
int factorial(int n){
  int i;
  if(n == 1){
    return 1;
  }else{
    return n * factorial(n - 1);
  }
}

永遠の言語 C だ。C の記述形式を初めて見たときは衝撃だった。それが今では標準の形式となった。現在では Java を初めほとんどのプログラミング言語が、この C の形式を採用している。

// JavaScript
function factorial(n){
  if (n == 0){
    return 1;
  }else{
    return (n * factorial(n - 1));
  }
}

JavaScript は、ウェブ・クライアントにおける市場独占言語だ。Lua の形式が Pascal から来ているとすれば、JavaScript の形式は C から来ているといえる。それを除けば、この2つは似ているようにも思える。

// Scala
def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n - 1)

Scala は思想的に優れた言語だと思う。関数型言語特性を損なわず、手続き型言語としての使用も可能にしている。Java との相性もよく、Scala をぼくは有力な言語と見つづけているがどうなのだろう。

-- Haskell
factorial :: Integer -> Integer
factorial n = if n == 0 then 1 else n * factorial(n - 1)

純粋な関数型言語として Haskell ほど美しくデザインされた言語はないと思う。ただし、ぼくのような能力の人間にはギアが重い言語でもある。Haskell は主に研究所などで用いられる言語といえるだろう。ぼくの応用は、雑多な多くのデータを操作することだから Haskell が向いているとはいえないのだ。

(* Ocaml *)
let rec factorial n =
  if n = 0 then 1 else n * factorial(n - 1)

Haskell よりは少し現実的な関数型言語だと思う。これで10言語のすべてだ。これらの似通った短いコードを眺めるだけでは、何もわからないかもしれないが、ぼく自身が書き比べてみたかったという次第だ。

さて、ぼくは Lua のデザインは優れていると思う。それに品がいいとも思うのだ。最初に書いたが、function の綴りが長い、then が嫌だ、end、end といくつも書かねばならない。冗長ではないか。デフォルトがグローバル変数で、ローカル変数に lacal と記述しなくてはならないのが嫌だという人がいるようだ。確かにそういう人たちがいるのは理解できる。でもね、ぼくはそれらのデザインも優れていると思っているのだ。詳細な論点はあるけどね、面倒だし、好みということでよいと思う。

そうだね、ぼくは Lua が好みなのだ。Python も好きだよ。申し分ない。すべての面で合理的に思える。しかしね、何といえばいいのだろう、..説明できない違和感があるんだ。機能的なことじゃない。まぁ、いいさ、Python はすべての人にお勧めできる優れた言語だということは確かだろう。

さて「Lua#1」は上で取りあげたままのコードだ。「Lua#2」は、ぼくが自然に書くであろう形のコードだ。「Lua#3」はもう少しコードを詰めてみた。「Lua#4」は一行にしてしまった。もし、then のあとに2行以上のコードを書きたければ「;」で区切ればよい。Python 以外はどの言語も一行に詰めることができるはずだ。

-- Lua#1
function factorial(n)
  if n == 0 then
    return 1
  else
    return n * factorial(n - 1)
  end
end

-- Lua#2
function factorial(n)
  if n == 0 then return 1
  else return n * factorial(n - 1)
  end
end

-- Lua#3
function factorial(n)
  if n == 0 then return 1 else return n * factorial(n - 1) end
end

-- Lua#4
function factorial(n) if n == 0 then return 1 else return n * factorial(n - 1) end end

試しに JavaScript を詰めてみよう。

// JavaScript
function factorial(n) {if(n == 0){return 1;} else {return (n * factorial(n - 1));}}

Lua と比べてみればどっちも同じようなものだけど、ぼくは Lua の書き方のほうが好きなんだ。Lua の堂々としたデザイン(外見)に好意を感じているんだろう。今回の記事を書くことで、自分自身、ぼくのこの気持ちを確認することができたと思う。どうでもいいようなことのようだけど、ぼくには大切なことに思えるのだ。

Lua については、またいつか、そのデザイン(機能)について書きたいと思っている。それは Lua プログラマとして経験を積んでからがよいだろう。