Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2016-11-12

Google翻訳を試してみた

精度が上がったと話題のGoogle翻訳で僕が書いた日本語を訳してみて、その英文を見て意味が分かるかどうか、英文に違和感があるかないかを検証する。

What is Moyamoya?

まあわかる。

The purpose of this book is to solve the "Moyamoya on programming".

引用符の閉じ位置とかtheとかに違和感があるけど、まあわかる。

Everyone is learning programming, "What is object-oriented? I do not know like I understood ..." You may have felt moaiyoya such as.

これは書き直しが必要そう。元の日本語が「わかったようなわからないような…」という文字列を含む複雑な構造だから訳せないんだな。

In this book I would like to help solve such mooyamoya and refresh it.

and以降は削った方がいいかもな。

Moyamoya is not understood, I do not understand well, I can not understand well.

Moyamoya is a mental state such as "I do not understand well" or "I can not understand well."かな。

So what is understanding?

うん通じそう。こういうケースって冠詞いらないんですかね?

Makoto Nagao wrote in "What is" Understanding "" Understanding the sentence is to reconstruct the written content in the reader ".

引用符が乱れてるけど、まあ理解できる。

Moyamoya is a state in which the knowledge input to the brain by sentences etc. does not connect with other knowledge that he owned, fluffy floating.

割と訳しにくい原文だと思うんだけど、理解できる訳になっている。日本人etc.使いすぎって英会話の先生によく言われるけどこの文章でも「by sentences etc. 」はいらない気がする。

Even in this state, you may be able to spit the knowledge as it is like a parrot as it is.

「as it is like a parrot as it is」が微妙。先のas it isは「与えられた知識を与えられた形のまま吐き出すことしかできない」なのでas it was givenかなと思うし、like a parrot as it isのas it isが必要なのかどうかよくわからん。あえて訳出するにしても「まるであなたがオウムであるかのように」だからitじゃなくてyouだろう。

あと日本人的な曖昧表現が気になる。英語で書くなら「Even in this state, you can spit ...」と言い切った方がすっきりしそう。

However, we can not connect it with another knowledge.

文脈上、このweはyouの間違い。


もうちょっと技術的な話を試してみよう。

First, it is a concept of "implementing general functions in superclasses and implementing specialized functions in subclasses"? This is a design policy that superclass is generalization of subclass and subclass is specialization of superclass. This design policy matches the idea of ​​"class = classification".

いや、なぜ疑問形……。そこを直せばだいたい意味は取れそう。

The second one is the idea of ​​"extracting the intersection of multiple classes as its superclass?" This is a design policy of "extracting common parts" that is similar to mathematical factorization rather than generalization / specialization. This design policy matches the idea of ​​"sharing common parts of processing" already familiar with how to make functions.

こちらも疑問形。原文を確認したら"「複数のクラスの共通部分をそのスーパークラスとして抽出すればいいのではないか?」という考え方です"とか書いてたからそのせいだな。あとさっきはconceptでこっちはideaだな。


-----

実験をしての所感

It is not satisfactory quality as it is, but probably it can be passed as it is. Since you can see what you want to say in most places without referring to the original text, the labor of the work of correcting the translations made in Google Translate will be much less. Perhaps in this state you could also outsource "to correct sentences to be naturally" to people in English-speaking countries who do not understand Japanese.

そのままで満足できるクオリティではないけど、たぶんそのままでも通じる。原文を参照しなくても大部分の箇所で何を言いたいのかがわかるので、Google翻訳で作った下訳を修正していく作業の手間がだいぶ減る。たぶんこの状態なら日本語の分からない英語圏の人に「文章を自然になるように直して」って外注することもできそう。

2010-09-19

レバレッジメモ: Scalaスケーラブルプログラミング

言語も伽藍とバザールのように成長する--Steele "Growing a language" 1999

トレイト=インターフェイスに似ているがメソッド実装やフィールドを持つ、ミックスイン合成出来る

JavaのStringにtoIntがないことに気づいたときに、暗黙の型変換を参照してRichStringに変換し、そのtoIntを呼ぶ

アラン・ケイ「私は型に反対しているわけではない。『完全な苦痛』にはならないような型システムを見たことがないので動的な片付けを支持しているのである」2003 Dr. Alan Kay on the Meaning of "Object-Oriented Programming"

ダイクストラ「テストが証明できるのはエラーの存在であって、エラーの不在ではない」 1970 http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD249.PDF

「ことなる応用分野への拡張性を持った言語」というアイデア1966 The next 700 Programming Languages http://www.thecorememory.com/Next_700.pdf

(arg: String) => println(arg)をprintlnって書けるのを「関数の部分適用」と呼ぶのは気持が悪いなぁ。 P.51

末尾がコロンである演算子は右オペランドのメソッドである

コンパニオンオブジェクト 4.3

タプルとリストの両方があって両方イミュータブル。Haskellのタプルとリストだと思えばだいたいあってる

フィールドとメソッドを総称してメンバーと呼ぶ。メンバーはデフォルトでpublic

varとvalがある。valは再代入不可。

Scalaのクラスは静的メンバ(static)を持てない。そのかわりにシングルトンオブジェクトがある。classキーワードの代わりにobjectキーワードを使う。シングルトンオブジェクトがクラスと同じ名前の時にコンパニオンオブジェクト、コンパニオンクラスと呼ぶ。同じ名前のクラスがないシングルトンオブジェクトはスタンドアロンオブジェクト。

import文で任意のオブジェクトからメンバーをインポート出来る。

すべてのメソッドが演算子になれる。s.indexOf('o')をs indexOf 'o'と書ける。

論理演算子もメソッド→じゃあショートサーキットはどうやってる?→実は全てのメソッドで名前渡しが可能(9.5)→なんだって!!

===各引用ごとにページ数を書くのは面倒なのでここでP.100===

イミュータブルなオブジェクトのトレードオフ P.105

長所:複雑な状態変化をしないので動作を推定しやすい、他のコードに渡す際に破壊を避けてコピーをとる必要がない、スレッドが同時アクセスしても壊れない、安全にハッシュのキーにできる

短所:大規模なオブジェクトのコピーが必要になることがある

P108 クラスパラメータはコンストラクタ内からしかアクセス出来ない?→クラスパラメータをフィールドに代入して解決→え、なんのためのクラスパラメータ… 10.6のパラメータフィールドで解決される??

def this(n: Int) = this(n, 1)で「2番目の引数に1を入れてコンストラクタを呼ぶ」っていう補助コンストラクタができる。基本コンストラクタだけがスーパークラスのコンストラクタを呼び出せる。これはJavaより若干制限が強い。see sec.10

演算子メソッドを使えばコードは簡潔になる、しかし読みやすくなるかどうかはクライアントプログラマが個々の演算子の意味を理解して覚えられるかどうかによる P.120

Scalaでは関数リテラルとの相性が悪いbreakとcontinueを取り除いている。末尾再帰や、whileの条件にtoExit的変数を入れたりループの後半をifで囲ったりすることでbreakやcontinueがなくても同等なコードが書けるという説明がされている。まあ、そりゃそうだけどね。どう相性がわるいのか知りたいけどどこに書いてあるのかわからない。

Scalaはネストしたスコープの内側で外側の変数をシャドーするような変数を定義できる。

「一人前の存在としての関数」(first-class functions)!

「(x: Int) => x > 0」は「_ > 0」とも書ける。「_ + _」は1引数の2倍になる関数ではなく2引数の足し算をする関数

Javaの内部クラスは外側のスコープで書き換えられる可能性のある変数にはアクセス出来ない。Scalaのクロージャは直感的に言えば変数事態を掴んで「閉じた」ものである。

Scalaは末尾再帰をジャンプに変換するので、末尾再帰の関数が失敗した時のスタックトレースにはいくつもの関数が出てこない。紛らわしい時は-g:notailcallsオプションでOFFにする。末尾再帰の最適化は文字通り自分自身を呼ぶ再帰の時にしか使えない。相互再帰や他の関数の呼び出しは最適化されない。

def foo(f: () => Boolean) = ...で定義される関数は foo(() => x > 0)と呼べる。これをdef foo(f: => Boolean)にするとfoo(x > 0)と呼べるようになる。foo(v: Boolean)との違いは評価のタイミング。これが名前渡しパラメータ。

単純なオブジェクトとは何か、単純なオブジェクトからより面白いオブジェクトを作るにはどうすればいいか、コンビネータ(合成演算)はどう組み合わされるか、最も一般的なコンビネータは何か?これらに答えられるならライブラリ設計は軌道にのっていると言えるだろう。P.173

サブクラスとサブ型の違い: 型引数を取らないクラス・トレイトに関してはサブクラスとサブ型は同じ。型引数を持つ場合それが共変(たとえばListはList[+A]なのでList[Cat] <: List[Animal])ならサブ型

パラメータフィールド:要するにclass Foo(val arg: Type)って書き方でフィールドもつくれる。class Foo(override val x)とかprivateなどの修飾も付けられる。

親クラスのコンストラクタは基本コンストラクタからしか呼べない。class Foo(...args...) extends SuperClass(...args for superclass...)

具象メンバのオーバライドにはoverride修飾が必須

Scalaスケーラブルプログラミングのレバレッジメモ


呼び出されるメソッドの定義は変数の型ではなく実行時のオブジェクトのクラスによって決まる。動的束縛。

継承を使う前にis-a関係かどうかを考えろ(Mayers, "Effective C++" 1991)、また、スーパークラス型としてサブクラス型を使いたいかどうかを考えろ(Eckel, "Thinking in Java" 1998)

最下位(bottom)の型: Null, Nothing。Nullは全ての参照クラス(AnyRefクラスを継承するクラス)の小クラス。Nothingは全ての小クラス。たとえばerrorの返り値など。失敗しうるIntを返す関数の型をMaybe Intとかにしない。Intを返して、エラー時には例外機構でNothingをIntとして使う前に別の処理に飛ばされる。

P.204 トレイト トレイトはクラスみたいなもの。違いはsuperの指すものが何か。traitのsuper呼出はそれがクラスにミックスインされたあとで線形化によって決まる。そのためtraitのabstractメソッドの中ではsuper.a_methodにアクセスすることができる。これはa_methodの具体的な定義を提供するクラスのあとでmixinしなければならないことを表明している。

このことによりtraitという形で表現された「変更の差分」を積み重ねることができる(僕は差分を積み重ねるコーディングスタイルがよいものかどうかは疑問だが)

Scalaのimportはどこにでも書ける。オブジェクトもインポートできる。インポートされたメンバの名前を変えられる。

クラスとコンパニオンオブジェクトは相互にprivate無視。これを使ってstaticメンバの代わりにする。

ケースクラス。

abstract class Expr
case class Var(name: String) extends Expr
case class Number(...) extends Expr
case ...

パターンマッチに使う。

ScalaもJavaも消去モデル(erasure model)のジェネリックプログラミングなので与えられたMapオブジェクトがMap<Int, Int>なのかどうかを知る方法は存在しない。

sealedクラスにすると同じファイルで定義されているサブクラス以外にはサブクラスを作ることができなくなる。

型パラメータとサブ型の組み合わせは面白い問題をはらんでいる。S <: T (SがTが期待されている箇所で型安全に使用できる)の時、Foo[S] <: Foo[T]ならFooは共変(covariant)といいFoo[+T]と表現する。Foo[-T]もありこれは反変(contravariant)。T <: Sの時にFoo[S] <: Foo[T]という意味。非変(nonvariant)はそれらの関係が成り立たないことで、デフォルトではこれ。Javaの配列は共変である。Object[]には任意のFooBar[]が入る。これはString[]にObject[]を介してIntegerを入れられてしまうということで、実行時エラーを引き起こす。ゴスリン曰く配列をジェネリックに扱う方法が欲しかった(P.358)しかし今ではJavaにもジェネリクスの機能が入っているので配列の共変は必要ではない。互換性のために残されている。

下限境界。def append[U >: T](x: U)などという書き方ができる。TかTのスーパクラスであるものを引数に取るという意味。上限境界もある。[T <: Ordered[T]]

lazy val x = ...;で遅延評価

暗黙の型変化。x + yがないときにconvert(x) + yが可能ではないか調べる。に通りの方法があるときはコンパイルエラー。型変換は1回しかしない。書かれているとおりで動く場合には変換しない。

むう、駄目だ、さすがに一気に読むのは脳が疲れた。まだ共変・反変の話と暗黙の型変換が残ってるんだけど、続きは今度。(追記した)

2010-07-23

レバレッジメモ: レガシーコード改善ガイド

レガシーコード := テストがないコード

テストを作成するためには対象とするクラスから他のクラスへの影響を把握する必要がある。依存関係を排除しておけばニセのクラスを突っ込んで影響を直接観察できる。

テストをするたびに本番コードを編集するわけには行かない、なのでコードを編集せずにテストに不都合な挙動を変えられる場所が必要である。これをseamという。どのseamも、その挙動を変更するenabling pointを持っている。

日本語で「接合部」っていうとくっつけることに意識が向きがちだけど「そこで切り離せる」というほうが重要なのだな。

既存のレガシーコードに機能追加をする方法

1: スプラウトメソッド

テストされてない既存のコードに書き足すのではなく、新しいメソッドを作ってそれを呼び出すようにし、その新しいメソッドにテストを書く

2: ラップメソッド

テストされていない既存のメソッドの前か後ろに処理を付け足す場合、テストされていないメソッドの名前を変えて、元の名前で古いメソッドと新しく追加する機能の入ったメソッドを呼び出すようにし、その新しいメソッドをテストする。

TDD

  • 1: 失敗するテストを書く
  • 2: コンパイルが通るようにする
  • 3: テストを通過させる。この時既存のコードをなるべく変更しない。「これはFooメソッドとほとんど同じで一部だけ違うから抽象化しよう」と考えずにFooメソッドをコピペして作る。抽象化はリファクタリングなのでテストに通ってから。
  • 4: コードをきれいにする
  • 5: 1に戻る

Liscovの置換原則

サブクラスYのオブジェクトはいつでもスーパークラスXのオブジェクトとして使えなければならない。さもないとユーザがあるX型の変数に入っているオブジェクトが実際にはY型であることを意識しなければいけないようになってしまう。

Nullを渡す

Javaのような実行時のnullに対するアクセスを察知できる言語なら、テスト用に作るのが面倒なオブジェクトが必要なときに単にnullを渡せばいい。必要なものは必要になったときに例外で教えてくれる。

影響の調査の仕方

影響スケッチを描く

変数と戻り値が変わる可能性のあるメソッドをまるで囲む。影響を矢印で書く。

よく設計されていればこれはシンプルになるはず。

_

依存性の排除によってカプセル化が壊れるケースがある。たとえばprivateを外すとクラスの中だけ調査していれば依存性を把握できたのが、パッケージ全体を見なければいけなくなったりする。依存性の排除はテストを書きやすくするための手段であり、目的ではない。同様にカプセル化も依存性をおいやすくするための手段であり目的ではない。著者はテストを優先する。

_

サードパーティのライブラリを直接呼んでいる部分はseamにできたはずのところ。サードパーティライブラリに密結合なせいでテストが出来ないとか本末転倒。ラッパーなどを使って疎結合にする。

後半の具体例は斜め読みできないから今度じっくり読もう。

2008-03-07

class precedence list

http://gauche.sourceforge.jp/doc/gauche-refj_141.html

勉強中。余計なことに手を出してしまった気がする。

Gauche ではデフォルトで C3 線形化と呼ばれているアルゴリズムを使います。このアルゴリズムは局所的な順位、単調性、拡張順位グラフと整合性のとれたものです。ここでは詳細に立ち入りませんが、一般的なルールとして、 CPL 中のスーパークラスの順序は、つねにそのクラスの直接スーパークラスの順序、それぞれのスーパークラスの CPL の順序、および、各スーパークラスの直接スーパークラスの順序、などと整合性をもちます。正確な説明についてはDylanを参照してください。

ああっ。詳細に立ち入ってくれていない><

ぼ、ぼくも詳細に立ち入るのやめようかな。

それぞれのCPLがスーパークラスを指定する順序やスーパークラス達のCPLと同じ順になっている(「片方でAがBより先にあるのに別のではBがAより先にある」ということがおこらない)ってことだけ解説すればいいかなぁ。

Pythonの新しいクラスの継承がC3線形化なのですけど、どう説明すればいいかなぁとか。

単純に「昔は深さ優先だったのが幅優先になっただけ」という理解は間違いだと言うことには言及すべきだろうしなぁ。

やっぱり説明しないわけにはいかない。ついつい「筆者の理解が正しければ」って書きたくなってしまうが、基本的に全ての言及は間違っている可能性があるわけだから無意味だよな。ここに書いておいて識者から「それは違う」とつっこまれたら修正することにしよう。