日本でハリウッドVFXを制作! 「経産省アイディアボックス」 結果:  
●まとめエントリはこちら ●FAQ ●お問い合わせは左のメールフォームから

2009年12月28日月曜日

命令構文と関数構文(3): 「関数構文」

今回は最後に残った「関数構文」について調べていきます。

オンラインヘルプの「関数構文」の説明をよんでみましたが、(自分には)わかりにくいことこの上ない。
「関数構文はコンピュータ言語の標準的な関数コールに似ています。」

いくら何でも省略しすぎw
「Melはプログラミングの知識が無くても使えます」と言っておきながら、これでは「関数コール」というものがわかっていなければ理解することができない。

しかたないので、まず「関数」から調べていきます。


----------------------------------------
(1)数学用語の「関数」
関数」は英語で言うと「Function」、これは数学用語の「関数」も同じです。
どちらの「関数」も基本的概念は同じだからと思います。
(きっと、数学の「関数」からきているのだと思います)

これについてはKIT数学ナビゲーションにある「関数」の説明がわかりやすい。

特に図に書いてある
「ある入力に対して一つの出力に変換する機能を持つ箱」
という考えは、プログラミング用語の「関数」にも当てはまると思います。


----------------------------------------
(2)プログラミング用語の「関数」

ではプログラミング用語の関数の定義を見ていきます。

IT用語辞典BINARY
関数とは、入力された値に対してある決まった内容の計算を行い、入力された値に応じた処理結果を返す、数式、あるいは命令の集まりのことである。


IT用語辞典e-Words
関数とは、引数と呼ばれるデータを受け取り、定められた通りの処理を実行して結果を返す一連の命令群。

例えば「二つの数を受け取って、それらを合計した結果を返す」という命令は関数である。
この関数をfと呼ぶとすると、「関数fに引数1と2を与えると3という結果が返ってくる」ということになる。
必ずしも数字を扱うものだけを指すのではなく、「入力された文字を画面に表示する関数」なども存在する。
言語によっては引数を取らない関数や結果を返さない関数を作成できるものもあるが、通常はそうしたものは関数とは呼ばないことが多い。


wikipedia(サブルーチン)
サブルーチンを、
●結果として値を返すものと
●処理だけを行い値を返さないもの
に分類することがある。
その場合、前者を関数(かんすう)、後者を手続き(てつづき)と呼んで区別する。



以上の定義から考えてみた。

関数とは、
1)名前を持つ :「関数名」
2)入力値を持つ :「引数」
3)それに対して処理を行う。:「処理」
4)処理を実行して結果(値)を返す。:「戻り値」
以上を行うために必要な命令を書き並べたものが関数と言うことになる。
(参照:「Programing Place」の「C言語編 第8章 関数とは」)

※ここでいう「命令」とはMayaでは、MelのコマンドのことではなくC言語やAPIレベルの命令である。
(プロシージャを関数と考えればMelコマンドも上記の命令に該当すると考えることは可能)


----------------------------------------
(2)Mayaの関数

C言語では、あらかじめ用意されている関数を「ライブラリ関数」と呼ぶ。
また、プログラマが独自の関数を作る事もでき、それらは「ユーザー関数」と呼ばれる。
そしてどちらの関数も基本的には、上記の特徴(引数、処理、戻り値)をもっている。

Melではそれぞれ以下のように対応していると考えて良いだろう。
●ライブラリ関数(C言語): 関数(Mel)
●ユーザー関数(C言語): プロシージャ(Mel)


以下はMelにある関数の例である
例:sin, cos, log, mag, size, rand, linstep, eval

※関数には戻り値を持たない物もあると書かれている定義もありますが、Melでそれに該当するものがあるのかどうかは私にはわかりません。

「コマンド」との違いで思いつくのは、、
●フラグを持たない
●引数の入力
●戻り値がある。

「エクスプレッション」とも違います。見た目の違いは。
●左辺、右辺がない。


----------------------------------------
(3)「命令構文」と「関数構文」の違い

オンラインヘルプの「関数構文」のところをもう一度見てみます。
ここに表があり、例としてabs関数があげられています。

abs関数とは以下のような物です。
abs:数値の絶対値を返す、制限関数の一つ。

(例)
abs(-1):値 1 を返します。
abs(1):値1を返します。
abs(-2.43):値2.43を返します。

「関数構文」の説明にある表には命令構文と関数構文の表記の違いがならべて書いてあります。
●命令構文: abs -50
●関数構文: abs(-50)

両者をスクリプトエディタ上で実行するとどちらも、

// Result: 50 //
と返してきてスクリプトエディタでは、違いがわかりません。


しかしながらこれを代入演算子を使ったエクスプレッション「$a=*****」で使うと違いが見えてきます。


①まず、「命令構文」で記述したもの。
{
int $a;
$a = abs -50;
print $a;
}

// Error: $a = abs -50; //
// Error: Invalid use of Maya object "abs". //
エラーになりました。
これは「命令構文」では、戻り値をスクリプトエディタにしか出力しないためです。
その戻り値をコマンド(エクスプレッション)内で使う事ができません。


②次に、「関数構文」で記述したもの。
{
int $a;
$a = abs(-50);
print $a;
}

50
値「50」がきちんと出力されました。
これは「関数構文」で表記されていれば戻り値をコマンド(エクスプレッション)内で使う事ができることを示してるといえるでしょう。


③次に「命令構文」を「` `」で囲んだもの
{
int $a;
$a = `abs -50`;
print $a;
}

50
値「50」がきちんと出力されました。
これは「命令構文」表記であっても「` `」でその戻り値をコマンド(エクスプレション)内で使う事が出来るようになることを示しています。
いわば「`コマンド構文`」で関数のような利用ができると考えて良いかもしれません。


何となく「関数構文」と、「命令構文」のはたらきの違いがわかってきたように思います。


前にも調べたように、構文とはただの表記上の違いです。
難しく感じるのは、それにより期待できる動作が異なってくることです。

●命令構文: ( )を使わない: 戻り値を使えない
●関数構文: ( )を使う:    戻り値を利用できる


----------------------------------------
(4)関数コール

オンラインヘルプ「関数構文」には
「関数構文はコンピュータ言語の標準的な関数コールに似ています。」
と書いてありました。

「関数コール」とは何でしょう。それについて調べてみます。


●関数呼び出し(function call)

IT用語辞典BINARY
関数呼び出しとは、プログラムから関数サブプログラムや関数ライブラリを呼び出すことである。

GNU Octave 2.1.x 日本語マニュアル 「10.2 関数の呼び出し
関数を使用するための方法は,関数呼び出し式を使うことです。この式は,関数名と,それに続くかっこでくくられた引数のリストから構成されます。
その引数は,関数が実行する計算に用いる生の対象物を与える式です。
1つ以上の引数があるとき,それらはカンマで区切ります。
もし引数がなければ,カッコを省略することができます。
sqrt (x^2 + y^2) # 1個の引数
ones (n, m) # 2個の引数
rand () # 引数なし

AjaxTower 「関数の定義と呼び出し
関数を呼び出すには次の書式を使います。
関数名(引数1, 引数2, ...);
関数を呼び出す時には関数名の後の「(」と「)」の間に引数を指定して呼び出します。


C言語講座 & ライブラリ関数 - 呼び出しと引数
関数を呼び出す時は、
関数名( 引数 );
です。


これは、簡単ですね。
関数呼び出しとは、決められた手順にしたがって関数を使う事。

そしてその決められた手順とは
関数名の後に( )を使用し、その中に引数を入れるということ。

関数名(引数)

これがC言語などのプログラミング言語での関数コール(呼び出し)の方法です。

Melの「関数構文」もこれと同じだと言うことです。
ようするに関数構文とは、
●関数名
●(
●引数(複数の場合は、「,」で区切る)
●)
●;
という順番で並べた物です。


ここで、オンラインヘルプにある「attributeExists」の例をみてみます。
このコマンドは、「指定したアトリビュートが特定のノードに存在するかどうかを確認する」ものです。

先ほどのabs関数もこの「attributeExists」もコマンド自体のヘルプページには( )付で「関数構文」の表記で説明されています。
このあたり関数なのかコマンドなのか境目が曖昧ですね。

「関数構文」のところでは、例として「命令構文」での表記と「関数構文」での表記を並べてあります。
attributeExists visibility mySphere;(命令構文)
attributeExists("visibility","mySphere");(関数構文)


このような説明では、本来「関数構文」であるものを、わざわざ「命令構文」で使うメリットは何か?
また、逆に「命令構文」表記のコマンドを「関数構文」の表記に入れ替えることができるのか?
という疑問は残ります。
それともこれはヘルプ上で、違いをわかりやすくするための便宜的な物なのでしょうか?

----------------------------------------
まとめ
----------------------------------------
●関数とは「関数名」「引数」「処理」「戻り値」をもつ

●関数構文とは関数名の後に引数を( )で囲む表記方法。
関数名( 引数 );

●引数には数字、文字列、変数が利用できる。

●その引数が文字列である場合は、" "で囲む。

●「関数構文」では戻り値をコマンド/エクスプレション内で利用できる。

●「命令構文」では戻り値はスクリプトエディタ上にしか出力されない。

●「命令構文」を「` `」で囲めばその戻り値を利用できる。
 

0 件のコメント:

コメントを投稿