Skip to content

Commit

Permalink
Call by name finished
Browse files Browse the repository at this point in the history
  • Loading branch information
appigram committed Aug 29, 2012
1 parent ce73d5e commit 3430b4e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 47 deletions.
79 changes: 33 additions & 46 deletions effectivescala-ru.mo
Expand Up @@ -713,68 +713,64 @@ Case классы представляют собой АТД(алгебраич

.LP является <code>Option[InputStream]</code> которая может принимать значение <code>None</code>, в этом случае <code>getResourceAsStream</code> должен возвратить <code>null</code>.

### パターンマッチ
### Сопоставление с образцом

パターンマッチ (`x match { ...`) は、Scalaで書かれたコード内に広く使われている。パターンマッチは条件の実行および分解(destructuring)、ひとつの構成物へのキャストを合成する。うまく使うことで明快さと安全さの両方をより高めてくれる。
Сопоставление с образцом (`x match { ...`) широко распространено в хорошо написанном Scala коде: оно осуществляет условное выполнение, разбор конструкций, и все это в одной конструкции. При его использовании также повышается четкость и безопасность.

型ごとの処理を実装するためにパターンマッチを使う。
Используйте сопоставление с образцом для реализации переключения типов:

obj match {
case str: String => ...
case addr: SocketAddress => ...

パターンマッチは、分解とあわせて利用された時(たとえば、ケースクラスをマッチングするとき)に最大限に役立つ
次の例のように書くべきではなく、
Сопоставление с образцом лучше всего работает в сочетании с разбором конструкций (например, работе с Case классами), вместо

animal match {
case dog: Dog => "dog (%s)".format(dog.breed)
case _ => animal.species
}

.LP 以下のように書く
.LP лучше написать

animal match {
case Dog(breed) => "dog (%s)".format(breed)
case other => other.species
}


ただ、2つのコンストラクタ(`apply`) を利用する場合のみ、[カスタム抽出子] (http://www.scala-lang.org/node/112) を書く。
さもなければ不自然になる可能性がある。

Используйте [custom extractors](http://www.scala-lang.org/node/112), но только с дополнительным конструктором (`apply`), в противном случае их использования может быть неуместным.

デフォルト値がもっと意味を持つものであるとき、条件実行にパターンマッチを使わないようにする。
コレクションライブラリは通常`Option`を返すメソッドを提供する。次の例は避けよ。
Не используйте сопоставление с образцом для вычисления условий, когда имеет смысл использовать стандартные значения. Библиотеки коллекций обычно предоставляет методы, которые возвращают `Option`; избегайте

val x = list match {
case head :: _ => head
case Nil => default
}

.LP なぜなら
.LP потому что

val x = list.headOption getOrElse default

.LP の方がより短く、目的が伝わりやすいからだ。
.LP так короче и болешь соответствует цели

### 部分関数
### Частичные функции

Scala は 部分関数(`PartialFunction`) を定義するための構文上の簡略的記法を提供する。
Scala предоставляет синтаксический сахар для определения `PartialFunction`:

val pf: PartialFunction[Int, String] = {
case i if i%2 == 0 => "even"
}

.LP また、これらは <code>orElse</code> と組み合わせられる。
.LP и они могут использоваться вместе с <code>orElse</code>

val tf: (Int => String) = pf orElse { case _ => "odd"}

tf(1) == "odd"
tf(2) == "even"

部分関数は多くの場面で起こり得るものであり,`PartialFunction` で効率的に符号化される。
メソッドの引数として利用する例:
Частичные функции исопльзуются во многих ситуациях и эффективно
кодируются с помощью `PartialFunction`, например, в качестве аргументов
методов

trait Publisher[T] {
def subscribe(f: PartialFunction[T, Unit])
Expand All @@ -787,75 +783,66 @@ Scala は 部分関数(`PartialFunction`) を定義するための構文上の
/* ignore the rest */
}

.LP また状況によっては <code>Option</code> を返すような呼び出しがあるかもしれないが、
.LP или в ситуациях, которые могли бы способствовать возврату <code>Option</code>

// Attempt to classify the the throwable for logging.
type Classifier = Throwable => Option[java.util.logging.Level]

.LP これも、<code>PartialFunction</code>を使って表現する方がよいだろう。
.LP может быть лучше выражено с помощью <code>PartialFunction</code>

type Classifier = PartialFunction[Throwable, java.util.Logging.Level]

.LP それはより優れた構成可能性(composability)につながるからだ。
.LP так как это более компактно:

val classifier1: Classifier
val classifier2: Classifier

val classifier = classifier1 orElse classifier2 orElse { _ => java.util.Logging.Level.FINEST }


### Destructuring bindings
### Ликвидация привязок (Destructuring bindings)

Destructuring bindによる値代入は、パターンマッチに関連している。
それらは同じメカニズムを利用しているが、(例外の可能性を許容しないために)正確にひとつの選択肢があるときだけ適用できる。
Destructuring bindは特にタプルやケースクラスで有用である。
Ликвидация привязок тесно связана с сопоставлением с образцом; используется тот же механизм, но применяется, когда есть только один вариант (чтобы не сгенерировать исключение). Ликвидация привязок особенна полезны для кортежей и Case классов.

val tuple = ('a', 1)
val (char, digit) = tuple

val tweet = Tweet("just tweeting", Time.now)
val Tweet(text, timestamp) = tweet

(訳注: Destructuring bindは、「構造化代入」や「分配束縛」等の訳がある。詳細については、[こちらの議論](https://github.com/scalajp/effectivescala/issues/4)を参照してほしい。)

### 遅延評価
### Ленивые вычисления

Scala のフィールドは、`val` が `lazy` プレフィックスと共に使われた時は *必要になったときに* 計算されるようになる。
なぜなら、(フィールドを `private[this]` にしない限りは)フィールドとメソッドは Scala では等価だからである。
Поля в Scala вычисляется *по необходимости*, когда `val` имеет префикс
`lazy`. Поэтому поля и методы в Scala эквиваленты (поля как бы `private[this]`)

lazy val field = computation()

.LP は、(概して) 簡略的記法で、
.LP это примерное сокращение для

var _theField = None
def field = if (_theField.isDefined) _theField.get else {
_theField = Some(computation())
_theField.get
}

.LP すなわち、結果を演算し記憶する。この目的のために遅延フィールドを使うようにし、しかし、遅延さが意味を持って(by semantics)要求されるときには遅延評価を使うことを避ける。
このような場合には、コストモデルを明確にし、副作用をより正確に制御するために明示的であることがよりよい。
.LP то есть, результаты вычисляются и запоминаются. Используйте ленивые поля для этого, но избегайте использования ленивых вычислений, когда ленивые вычисления требуются по смыслу. В этих случаях лучше производить вычисления явно, поскольку можно точно произвести оценку, и побочные эффекты могут контролироваться более точно.

遅延フィールドはスレッドセーフである。
Ленивые поля являются потокобезопасными.

### 名前呼び出し
### Передача по имени

メソッドの引数は名前によって特定されるかもしれない、その意味するところは
パラメータは値に紐付くのではなくて、繰り返し実行されうる *演算* に対して紐付くということである。
この機能は気をつけて適用されなければならない。値渡しの文脈を期待している呼び出し側は驚くであろう。
この機能は構文的に自然な DSL を構築するためにある。-- 新しい制御構造は特に、かなりネイティブな言語機能に見えるように作ることができる
Параметры методов могут быть переданы по имени, то есть параметр принимает не значение, а *вычисление*, которое может повторяться. Это
функция должна применяться с осторожностью; вызывающая функция может ожидать передачу по значению, но в ответ будет удивлена. Способ применения этой особенности - это построение обычных синтаксических DSL - например, могут быть сделаны новые конструкции управления, чтобы выглядеть так же, как и родные особенности языка.

名前呼び出しは、そのような制御構造のためだけに使うことだ。そこでは、渡されてくるものは、
思いも寄らない演算結果より"ブロック"であるということが、呼び出し側に明らかである。
名前呼び出しは、最後の引数リストの最後の位置にある引数にだけ使うことだ。
名前呼び出しを使うときは、呼び出し側にその引数が名前呼び出しであることが明確に伝わるようにメソッドには名称をつけることを確実におこなう。
Используйте передачу по имени управляющих конструкций, когда для вызывающей функции очевидно, что передается в это "блок", а не
результат каких-то неожиданных вычислений. Используйте передачу по имени в крайней позиции последнего списка аргументов. При использовании передачи по имени, убедитесь, что метод назван очевидным образом для вызывающей функуции, которая передает аргумент.

値を複数回演算させたいとき、また特にその演算が副作用を持つとき、陽関数(explicit functions)を使う。
Если вы хотите, чтобы значения вычислялись несколько раз, и, особенно, когда вычисление имеет побочные эффекты, используйте явные функции:


class SSLConnector(mkEngine: () => SSLEngine)

.LP 目的は明らかに残しつつ、呼び出し元が驚くことがなくなる。
.LP ваше намерение остается очевидным и для вызывающей функции это не будет сюрпризом

### `flatMap`

Expand Down
2 changes: 1 addition & 1 deletion effectivescala.mo
Expand Up @@ -1050,7 +1050,7 @@ are `private[this]`)
_theField.get
}

.LP i.e., it computes a results and memoizes it. Use lazy fields for this purpose, but avoid using lazyness when lazyness is required by semantics. In these cases it's better to be explicit since it makes the cost model explicit, and side effects can be controlled more precisely.
.LP i.e., it computes a results and memorizes it. Use lazy fields for this purpose, but avoid using lazyness when lazyness is required by semantics. In these cases it's better to be explicit since it makes the cost model explicit, and side effects can be controlled more precisely.

Lazy fields are thread safe.

Expand Down

0 comments on commit 3430b4e

Please sign in to comment.