Example4.2

「Example4.2」の編集履歴(バックアップ)一覧はこちら

Example4.2」(2011/02/24 (木) 08:30:24) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

#co(){ 4.2 Parameters Using def, one can also define functions with parameters. For example: } ** 4.2 引数 def を使って、引数を持った関数を定義できます。たとえば scala> def square(x: Double) = x * x square: (Double)Double scala> square(2) unnamed0: Double = 4.0 scala> square(5 + 3) unnamed1: Double = 64.0 scala> square(square(4)) unnamed2: Double = 256.0 scala> def sumOfSquares(x: Double, y: Double) = square(x) + square(y) sumOfSquares: (Double,Double)Double scala> sumOfSquares(3, 2 + 2) unnamed3: Double = 25.0 #co(){ Function parameters follow the function name and are always enclosed in parentheses. Every parameter comes with a type, which is indicated following the parameter name and a colon. At the present time, we only need basic numeric types such as the type scala.Double of double precision numbers. Scala defines type aliases for some standard types, so we can write numeric types as in Java. For instance double is a type alias of scala.Double and int is a type alias for scala.Int. } 関数の引数は関数名の後に置かれ、常に括弧で囲まれます。各引数は型を伴い、型は引数名とコロンに続いて示されます。現時点では、倍精度数の scala.Double 型のような基本的な数値型だけを必要とします。Scala では、いくつかの標準的な型について&bold(){型エイリアス}が定義されていて、数値型は Java と同じように書けます。たとえば double は scala.Double の型エイリアスであり、int は scala.Int の型エイリアスです。 #co(){ Functions with parameters are evaluated analogously to operators in expressions. First, the arguments of the function are evaluated (in left-to-right order). Then, the function application is replaced by the function's right hand side, and at the same time all formal parameters of the function are replaced by their corresponding actual arguments. } 引数をもつ関数は、式の演算子と同じように評価されます。はじめに関数の実引数が (左から右の順序で) 評価されます。つぎに関数適用が関数の右辺で置き換えられ、同時に関数のすべての仮引数が対応する実引数で置き換えられます。 &b(){Example 4.2.1 } sumOfSquares(3, 2+2) → sumOfSquares(3, 4) → square(3) + square(4) → 3 * 3 + square(4) → 9 + square(4) → 9 + 4 * 4 → 9 + 16 → 25 #co(){ The example shows that the interpreter reduces function arguments to values before rewriting the function application. One could instead have chosen to apply the function to unreduced arguments. This would have yielded the following reduction sequence: } この例は、インタプリタが関数適用の前に、関数の引数を値に簡約することを示しています。この代わりに、簡約されていない引数に関数適用することも選択できます。それは次の簡約列をもたらします。 sumOfSquares(3, 2+2) → square(3) + square(2+2) → 3 * 3 + square(2+2) → 9 + square(2+2) → 9 + (2+2) * (2+2) → 9 + 4 * (2+2) → 9 + 4 * 4 → 9 + 16 → 25 #co(){ The second evaluation order is known as call-by-name, whereas the first one is known as call-by-value. For expressions that use only pure functions and that therefore can be reduced with the substitution model, both schemes yield the same final values. Call-by-value has the advantage that it avoids repeated evaluation of arguments. Call-by-name has the advantage that it avoids evaluation of arguments when the parameter is not used at all by the function. Call-by-value is usually more efficient than call-by-name, but a call-by-value evaluation might loop where a call-by-name evaluation would terminate. Consider: } 二つ目の評価順序は&bold(){名前渡し}(call-by-name)として、はじめの例は&bold(){値渡し}(call-by-value)として知られています。純粋な関数だけを使用する式や、したがって、置き換えモデルで簡約可能な式では、どちらの枠組みでも同じ値となります。 値渡しには、引数評価を繰り返さないという利点があります。名前渡しには、引数が関数で全く使用されない時に引数評価を避けるという利点があります。ふつう、値渡しは名前渡しより効率的ですが、値渡し評価は、名前渡し評価なら終了する箇所でループするかもしれません。次を考えてみましょう。 scala> def loop: Int = loop loop: Int scala> def first(x: Int, y: Int) = x first: (Int,Int)Int #co(){ Then first(1, loop) reduces with call-by-name to 1, whereas the same term reduces with call-by-value repeatedly to itself, hence evaluation does not terminate. } すると、first(1, loop) は名前渡しでは 1 に簡約されますが、値渡しでは繰り返し自分自身へと簡約され、したがって評価は終了しません。 first(1, loop) → first(1, loop) → first(1, loop) → ... #co(){ Scala uses call-by-value by default, but it switches to call-by-name evaluation if the parameter type is preceded by =>. } Scala はデフォルトでは値渡しを使いますが、引数型の前に => が置かれた場合は名前渡し評価へと切り替えます。 &b(){Example 4.2.2 } scala> def constOne(x: Int, y: => Int) = 1 constOne: (Int,=> Int)Int scala> constOne(1, loop) unnamed0: Int = 1 scala> constOne(loop, 2) // 無限ループとなる ^C // Ctrl-C で実行を停止 #center(){[[前ページ>Example4.1]] [[ 4 章>ExampleChap4]] [[目次>ScalaByExample和訳]] [[次ページ>Example4.3]]} ---- - 「~すべての正式な関数の仮引数が~」は、単に「関数のすべての仮引数が~」で良いのではないでしょうか。あと、「実際の引数」は実引数とするのがより一般的かと思います。 -- みずしま (2008-04-15 21:23:31) - ご指摘どうもありがとうございます>みずしまさん。修正致しました。 -- tmiya (2008-04-16 21:54:28) #comment
#co(){ 4.2 Parameters Using def, one can also define functions with parameters. For example: } #setmenu2(ex-r-menu) ** 4.2 パラメータ def を使って、パラメータを持った関数を定義できます。たとえば scala> def square(x: Double) = x * x square: (Double)Double scala> square(2) unnamed0: Double = 4.0 scala> square(5 + 3) unnamed1: Double = 64.0 scala> square(square(4)) unnamed2: Double = 256.0 scala> def sumOfSquares(x: Double, y: Double) = square(x) + square(y) sumOfSquares: (Double,Double)Double scala> sumOfSquares(3, 2 + 2) unnamed3: Double = 25.0 #co(){ Function parameters follow the function name and are always enclosed in parentheses. Every parameter comes with a type, which is indicated following the parameter name and a colon. At the present time, we only need basic numeric types such as the type scala.Double of double precision numbers. Scala defines type aliases for some standard types, so we can write numeric types as in Java. For instance double is a type alias of scala.Double and int is a type alias for scala.Int. } 関数のパラメータは関数名の後に置かれ、常に括弧で囲まれます。各パラメータは型を伴い、型はパラメータ名とコロンに続いて示されます。現時点では、倍精度数の scala.Double 型のような基本的な数値型だけを必要とします。Scala では、いくつかの標準的な型について&bold(){型エイリアス}が定義されていて、数値型は Java と同じように書けます。たとえば double は scala.Double の型エイリアスであり、int は scala.Int の型エイリアスです。 #co(){ Functions with parameters are evaluated analogously to operators in expressions. First, the arguments of the function are evaluated (in left-to-right order). Then, the function application is replaced by the function's right hand side, and at the same time all formal parameters of the function are replaced by their corresponding actual arguments. } パラメータをもつ関数は、式の演算子と同じように評価されます。はじめに関数の引数が (左から右の順序で) 評価されます。つぎに関数適用が関数の右辺で置き換えられ、同時に関数のすべての形式上のパラメータが対応する実際の引数で置き換えられます。 &b(){Example 4.2.1 } sumOfSquares(3, 2+2) → sumOfSquares(3, 4) → square(3) + square(4) → 3 * 3 + square(4) → 9 + square(4) → 9 + 4 * 4 → 9 + 16 → 25 #co(){ The example shows that the interpreter reduces function arguments to values before rewriting the function application. One could instead have chosen to apply the function to unreduced arguments. This would have yielded the following reduction sequence: } この例は、インタプリタが関数適用の前に、関数の引数を値に簡約することを示しています。この代わりに、簡約されていない引数に関数適用することも選択できます。それは次の簡約列をもたらします。 sumOfSquares(3, 2+2) → square(3) + square(2+2) → 3 * 3 + square(2+2) → 9 + square(2+2) → 9 + (2+2) * (2+2) → 9 + 4 * (2+2) → 9 + 4 * 4 → 9 + 16 → 25 #co(){ The second evaluation order is known as call-by-name, whereas the first one is known as call-by-value. For expressions that use only pure functions and that therefore can be reduced with the substitution model, both schemes yield the same final values. Call-by-value has the advantage that it avoids repeated evaluation of arguments. Call-by-name has the advantage that it avoids evaluation of arguments when the parameter is not used at all by the function. Call-by-value is usually more efficient than call-by-name, but a call-by-value evaluation might loop where a call-by-name evaluation would terminate. Consider: } 二つ目の評価順序は&bold(){名前渡し}(call-by-name)として、はじめの例は&bold(){値渡し}(call-by-value)として知られています。純粋な関数だけを使用する式や、したがって、置き換えモデルで簡約可能な式では、どちらの枠組みでも同じ値となります。 値渡しには、引数評価を繰り返さないという利点があります。名前渡しには、パラメータが関数で全く使用されない時に引数の評価を避けるという利点があります。ふつう、値渡しは名前渡しより効率的ですが、値渡し評価は、名前渡し評価なら終了する箇所でループするかもしれません。次を考えてみましょう。 scala> def loop: Int = loop loop: Int scala> def first(x: Int, y: Int) = x first: (Int,Int)Int #co(){ Then first(1, loop) reduces with call-by-name to 1, whereas the same term reduces with call-by-value repeatedly to itself, hence evaluation does not terminate. } すると、first(1, loop) は名前渡しでは 1 に簡約されますが、値渡しでは繰り返し自分自身へと簡約され、したがって評価は終了しません。 first(1, loop) → first(1, loop) → first(1, loop) → ... #co(){ Scala uses call-by-value by default, but it switches to call-by-name evaluation if the parameter type is preceded by =>. } Scala はデフォルトでは値渡しを使いますが、パラメータ型の前に => が置かれた場合は名前渡し評価へと切り替えます。 &b(){Example 4.2.2 } scala> def constOne(x: Int, y: => Int) = 1 constOne: (Int,=> Int)Int scala> constOne(1, loop) unnamed0: Int = 1 scala> constOne(loop, 2) // 無限ループとなる ^C // Ctrl-C で実行を停止 #center(){[[前ページ>Example4.1]] [[ 4 章>ExampleChap4]] [[目次>ScalaByExample和訳]] [[次ページ>Example4.3]]} ---- - 「~すべての正式な関数の仮引数が~」は、単に「関数のすべての仮引数が~」で良いのではないでしょうか。あと、「実際の引数」は実引数とするのがより一般的かと思います。 -- みずしま (2008-04-15 21:23:31) - ご指摘どうもありがとうございます>みずしまさん。修正致しました。 -- tmiya (2008-04-16 21:54:28) #comment

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。