バリケンのRuby日記 RSSフィード

2008-03-19

[] 関数定義  関数定義 - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  関数定義 - バリケンのRuby日記  関数定義 - バリケンのRuby日記 のブックマークコメント

今日は、Lispで関数の定義をしてみるよ。

あ、いきなり余談だけど、Lispにはいろいろな方言があるみたいだよ。今勉強している「Lisp」は、Common Lispのことだよ。

関数定義

関数を定義するには、「(defun 関数名 (仮引数1 仮引数2 ‥‥) 関数の定義)」とするよ。たとえば引数をひとつ取ってその二乗を返す関数squareを定義するには、「(defun square (n) (* n n))」と書くよ。

[1]> (defun square (n) (* n n))
SQUARE
[2]>

以前もやったけど、関数を呼び出すには「(関数名 引数1 引数2 ‥‥)」とすればいいんだよね。じゃあ、3の二乗を求めてみよう!

[2]> (square 3)
9
[3]>

次は仮引数が二つの場合。引数をふたつ取ってその合計を返す関数addを定義するには、「(defun add (x y) (+ x y))」と書くよ。

[3]> (defun add (x y) (+ x y))
ADD
[4]> (add 2 3)
5
[5]>

名前空間

Common Lispでは、名前空間が値用と関数用で分かれているんだって。だから、変数名と関数名に同じ名前を使っても、呼び出しの位置によって区別してくれるみたい。

じゃあ、さっきは関数squareを定義したけど、今度は変数squareに4を代入してみるよ。変数の代入はsetqを使うんだったね。

[5]> (setq square 4)
4
[6]>

じゃあ、変数squareを引数として関数squareを呼び出してみるよ。

[6]> (square square)
16
[7]>

これは、まず引数のsquareが評価されて「(square 4)」となるから、それが評価されて16が返ってきたんだね。

でもややこしいから、普通は変数と関数とで同じ名前をつけないほうがいいと思うよ。

[] Rubyでも名前空間  Rubyでも名前空間 - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  Rubyでも名前空間 - バリケンのRuby日記  Rubyでも名前空間 - バリケンのRuby日記 のブックマークコメント

Common Lispでは変数名と関数名とで名前空間が分かれていたけど、そういえばRubyではどうだったっけ?ちょっと気になったから、調べてみたよ。

こういうちょっとしたことを調べるには、irbが便利だね。

$ irb
irb(main):001:0> def square(n)
irb(main):002:1>   n * n
irb(main):003:1> end
=> nil
irb(main):004:0> square(4)
=> 16
irb(main):005:0> square = 4
=> 4
irb(main):006:0> square(square)
=> 16
irb(main):007:0>

えええ!そうなんだ。

呼び出しのときに変数名なのかメソッド名なのかはどうやって区別しているんだろ。そういえばRubyのメソッド呼び出しでは、引数のカッコは省略できるんだったよね。じゃあ、square squareって書いたらどうなるんだろ。

irb(main):007:0> square square
=> 16
irb(main):008:0>

ちゃんと動くんだねえ。うーん、中断している「Rubyソースコード完全解説」の続きを読まないとダメかなあ。

トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20080319