Tutoarial_4

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

Tutoarial_4 - (2010/08/22 (日) 08:55:05) の最新版との変更点

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

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

[[トップ>トップページ]] > [[チュートリアル和訳>Tutorial和訳]] > [[4 Everything is an object>Tutorial_4]] #co(){*4 Everything is an object Scala is a pure object-oriented language in the sense that everything is an object, including numbers or functions. It differs from Java in that respect, since Java distinguishes primitive types (such as boolean and int) from reference types, and does not enable one to manipulate functions as values.} *4 全てはオブジェクト Scala は純粋なオブジェクト指向ですが、それは数や関数も含めて&italic(){全て}がオブジェクトであるという意味においてです。この点において Java とは異なります。というのは Java ではプリミティブ型 (例えば boolean や int) と参照型とを区別しており、また関数を値として扱えないからです。 #co(){**4.1 Numbers are objects Since numbers are objects, they also have methods. And in fact, an arithmetic expression like the following:} **4.1 数はオブジェクト 数もオブジェクトなのでメソッドを持ちます。実際、下記のような式 1 + 2 * 3 / x #co(){consists exclusively of method calls, because it is equivalent to the following expression, as we saw in the previous section:} はメソッド呼び出しだけから成り立っています。それは前節で見たように下記の式と等価だからです。 (1).+(((2).*(3))./(x)) #co(){This alsomeans that +, *, etc. are valid identifiers in Scala.} これは、+, * なども Scala では有効な識別子だ、ということも意味しています。 #co(){The parentheses around the numbers in the second version are necessary because Scala's lexer uses a longest match rule for tokens. Therefore, it would break the following expression:} 数字の周りの括弧は必要です。というのは、Scala の字句解析はトークンに対して最長一致規則を使うからです。ですから、下記の式 1.+(2) #co(){into the tokens 1., +, and 2. The reason that this tokenization is chosen is because 1. is a longer valid match than 1. The token 1. is interpreted as the literal 1.0, making it a Double rather than an Int. Writing the expression as:} は、トークン 1.、+、2. に分解されます。このようにトークン化されるのは、1. が 1 よりも有効な長い一致となるからです。トークン 1. はリテラル 1.0 として解釈され、Int ではなく Double を形づくります。 (1).+(2) #co(){prevents 1 from being interpreted as a Double.} と式を書けば、1 が Double として解釈されるのを防げます。 #co(){**4.2 Functions are objects Perhaps more surprising for the Java programmer, functions are also objects in Scala. It is therefore possible to pass functions as arguments, to store them in variables, and to return them from other functions. This ability to manipulate functions as values is one of the cornerstone of a very interesting programming paradigm called functional programming.} **4.2 関数はオブジェクト 多分 Java プログラマがより驚くことは、関数もまた Scala ではオブジェクトだということでしょう。従って関数を引数として渡したり、変数に格納したり、他の関数からの戻り値にしたりできます。関数を値として扱うこの能力は、関数プログラミングと呼ばれる大変興味深いプログラミング・パラダイムの基礎の一部です。 #co(){As a very simple example of why it can be useful to use functions as values, let’s consider a timer function whose aim is to perform some action every second. How do we pass it the action to perform? Quite logically, as a function. This very simple kind of function passing should be familiar to many programmers: it is often used in user-interface code, to register call-back functions which get called when some event occurs.} なぜ関数を値として用いることが有用であるか、の非常に簡単な例として、1秒毎に何かアクションを行うタイマー関数について考えてみましょう。行うアクションをどのように渡せば良いでしょうか? 関数として、がきわめて論理的です。このように関数を渡す簡単な例は、多くのプログラマはよくご存知でしょう。ユーザインタフェイスのコードにおいて、何かイベントが起こった時に呼び出されるコールバック関数を登録する際によく使うからです。 #co(){In the following program, the timer function is called oncePerSecond, and it gets a call-back function as argument. The type of this function is written () => Unit and is the type of all functions which take no arguments and return nothing (the type Unit is similar to void in C/C++). The main function of this program simply calls this timer function with a call-back which prints a sentence on the terminal. In other words, this program endlessly prints the sentence “time flies like an arrow” every second.} 下記のプログラムで、タイマー関数は oncePerSecond と呼ばれ、コールバック関数を引数として取ります。この関数の型は () => Unit と書かれ、引数無しで戻り値無しである全ての関数の型です ( Unit 型は C/C++ の void に似ています) 。このプログラムの main 関数は単にこのタイマー関数を、端末に文章を表示するコールバック関数を付けて呼び出すだけです。別の言い方をすれば、このプログラムは1秒毎に "time flies like an arrow" という文章を表示し続けます。 object Timer { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def timeFlies() { println("time flies like an arrow...") } def main(args: Array[String]) { oncePerSecond(timeFlies) } } #co(){Note that in order to print the string, we used the predefined method println instead of using the one fromSystem.out.} 文字列を表示するために System.out のメソッドではなく、予め定義された println メソッドを使っている、ということに留意して下さい。 #co(){***4.2.1 Anonymous functions While this program is easy to understand, it can be refined a bit. First of all, notice that the function timeFlies is only defined in order to be passed later to the oncePerSecond function. Having to name that function, which is only used once, might seem unnecessary, and it would in fact be nice to be able to construct this function just as it is passed to oncePerSecond. This is possible in Scala using anonymous functions, which are exactly that: functions without a name. The revised version of our timer program using an anonymous function instead of timeFlies looks like that:} ***4.2.1 無名関数 このプログラムは理解しやすいですが、もう少し洗練できます。まずはじめに、関数 timeFlies は、後で onecePerSecond 関数に渡すためだけに定義されていることに留意して下さい。関数に名前を付けるのは、一度きりしか使わないなら不必要と思われます。実のところ oncePerSecond に渡すためだけにこの関数を作成できればよいでしょう。Scala では無名関数、その名の通り名前の無い関数、を使えば可能です。私たちのタイマープログラムを timeFlies の代わりに無名関数を使って書き直すと、このようになります。 object TimerAnonymous { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def main(args: Array[String]) { oncePerSecond(() => println("time flies like an arrow...")) } } #co(){The presence of an anonymous function in this example is revealed by the right arrow ‘=>’ which separates the function’s argument list from its body. In this example, the argument list is empty, as witnessed by the empty pair of parenthesis on the left of the arrow. The body of the function is the same as the one of timeFlies above.} この例で無名関数を使っていることは、関数の引数リストと本体を分離している右矢印 '=>' によって判ります。引数リストが空であることは、矢印の左側の空の括弧の組で判ります。関数の本体は上の timeFlies と同じです。 #center(){[[前ページ>>Tutorial_3]]  [[目次>>Tutorial和訳]]  [[次ページ>>Tutorial_5]]} ---- - 訳は関係ないですけど、「1 + 2 * 3 / x」と「1.+(2.*(3./(x)))」は等価ではないですよね。正しくは「(1).+( (2).*(3)./(x) )」かと。 -- 通りすがり (2010-04-09 17:51:46) #comment()
[[トップ>トップページ]] > [[チュートリアル和訳>Tutorial和訳]] > [[4 Everything is an object>Tutorial_4]] #co(){*4 Everything is an object Scala is a pure object-oriented language in the sense that everything is an object, including numbers or functions. It differs from Java in that respect, since Java distinguishes primitive types (such as boolean and int) from reference types, and does not enable one to manipulate functions as values.} *4 全てはオブジェクト Scala は純粋なオブジェクト指向ですが、それは数や関数も含めて&italic(){全て}がオブジェクトであるという意味においてです。この点において Java とは異なります。というのは Java ではプリミティブ型 (例えば boolean や int) と参照型とを区別しており、また関数を値として扱えないからです。 #co(){**4.1 Numbers are objects Since numbers are objects, they also have methods. And in fact, an arithmetic expression like the following:} **4.1 数はオブジェクト 数もオブジェクトなのでメソッドを持ちます。実際、下記のような式 1 + 2 * 3 / x #co(){consists exclusively of method calls, because it is equivalent to the following expression, as we saw in the previous section:} はメソッド呼び出しだけから成り立っています。それは前節で見たように下記の式と等価だからです。 (1).+(((2).*(3))./(x)) #co(){This alsomeans that +, *, etc. are valid identifiers in Scala.} これは、+, * なども Scala では有効な識別子だ、ということも意味しています。 #co(){The parentheses around the numbers in the second version are necessary because Scala's lexer uses a longest match rule for tokens. Therefore, it would break the following expression:} 数字の周りの括弧は必要です。というのは、Scala の字句解析はトークンに対して最長一致規則を使うからです。ですから、下記の式 1.+(2) #co(){into the tokens 1., +, and 2. The reason that this tokenization is chosen is because 1. is a longer valid match than 1. The token 1. is interpreted as the literal 1.0, making it a Double rather than an Int. Writing the expression as:} は、トークン 1.、+、2. に分解されます。このようにトークン化されるのは、1. が 1 よりも有効な長い一致となるからです。トークン 1. はリテラル 1.0 として解釈され、Int ではなく Double を形づくります。 (1).+(2) #co(){prevents 1 from being interpreted as a Double.} と式を書けば、1 が Double として解釈されるのを防げます。 #co(){**4.2 Functions are objects Perhaps more surprising for the Java programmer, functions are also objects in Scala. It is therefore possible to pass functions as arguments, to store them in variables, and to return them from other functions. This ability to manipulate functions as values is one of the cornerstone of a very interesting programming paradigm called functional programming.} **4.2 関数はオブジェクト 多分 Java プログラマがより驚くことは、関数もまた Scala ではオブジェクトだということでしょう。従って関数を引数として渡したり、変数に格納したり、他の関数からの戻り値にしたりできます。関数を値として扱うこの能力は、&italic(){関数プログラミング}と呼ばれる大変興味深いプログラミング・パラダイムの基礎の一部です。 #co(){As a very simple example of why it can be useful to use functions as values, let’s consider a timer function whose aim is to perform some action every second. How do we pass it the action to perform? Quite logically, as a function. This very simple kind of function passing should be familiar to many programmers: it is often used in user-interface code, to register call-back functions which get called when some event occurs.} なぜ関数を値として用いることが有用であるか、の非常に簡単な例として、1秒毎に何かアクションを行うタイマー関数について考えてみましょう。行うアクションをどのように渡せば良いでしょうか? 関数として、がきわめて論理的です。このように関数を渡す簡単な例は、多くのプログラマはよくご存知でしょう。ユーザインタフェイスのコードにおいて、何かイベントが起こった時に呼び出されるコールバック関数を登録する際によく使うからです。 #co(){In the following program, the timer function is called oncePerSecond, and it gets a call-back function as argument. The type of this function is written () => Unit and is the type of all functions which take no arguments and return nothing (the type Unit is similar to void in C/C++). The main function of this program simply calls this timer function with a call-back which prints a sentence on the terminal. In other words, this program endlessly prints the sentence “time flies like an arrow” every second.} 下記のプログラムで、タイマー関数は oncePerSecond と呼ばれ、コールバック関数を引数として取ります。この関数の型は () => Unit と書かれ、引数無しで戻り値無しである全ての関数の型です ( Unit 型は C/C++ の void に似ています) 。このプログラムの main 関数は単にこのタイマー関数を、端末に文章を表示するコールバック関数を付けて呼び出すだけです。別の言い方をすれば、このプログラムは1秒毎に "time flies like an arrow" という文章を表示し続けます。 object Timer { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def timeFlies() { println("time flies like an arrow...") } def main(args: Array[String]) { oncePerSecond(timeFlies) } } #co(){Note that in order to print the string, we used the predefined method println instead of using the one fromSystem.out.} 文字列を表示するために System.out のメソッドではなく、あらかじめ定義された println メソッドを使っている、ということに留意して下さい。 #co(){***4.2.1 Anonymous functions While this program is easy to understand, it can be refined a bit. First of all, notice that the function timeFlies is only defined in order to be passed later to the oncePerSecond function. Having to name that function, which is only used once, might seem unnecessary, and it would in fact be nice to be able to construct this function just as it is passed to oncePerSecond. This is possible in Scala using anonymous functions, which are exactly that: functions without a name. The revised version of our timer program using an anonymous function instead of timeFlies looks like that:} ***4.2.1 無名関数 このプログラムは理解しやすいですが、もう少し洗練できます。まずはじめに、関数 timeFlies は、後で onecePerSecond 関数に渡すためだけに定義されていることに留意して下さい。関数に名前を付けるのは、一度きりしか使わないなら不必要と思われます。実のところ oncePerSecond に渡すためだけにこの関数を作成できればよいでしょう。Scala では&italic(){無名関数}、その名の通り名前の無い関数、を使えば可能です。私たちのタイマープログラムを timeFlies の代わりに無名関数を使って書き直すと、このようになります。 object TimerAnonymous { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def main(args: Array[String]) { oncePerSecond(() => println("time flies like an arrow...")) } } #co(){The presence of an anonymous function in this example is revealed by the right arrow ‘=>’ which separates the function’s argument list from its body. In this example, the argument list is empty, as witnessed by the empty pair of parenthesis on the left of the arrow. The body of the function is the same as the one of timeFlies above.} この例で無名関数を使っていることは、関数の引数リストと本体を分離している右矢印 '=>' によって判ります。引数リストが空であることは、矢印の左側の空の括弧の組で判ります。関数の本体は上の timeFlies と同じです。 #center(){[[前ページ>Tutorial_3]]  [[目次>Tutorial和訳]]  [[次ページ>Tutorial_5]]} ---- - 訳は関係ないですけど、「1 + 2 * 3 / x」と「1.+(2.*(3./(x)))」は等価ではないですよね。正しくは「(1).+( (2).*(3)./(x) )」かと。 -- 通りすがり (2010-04-09 17:51:46) #comment()

表示オプション

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

下から選んでください:

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