Skip to content

「bound」の訳について #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
joemphilips opened this issue Jun 8, 2016 · 8 comments
Closed

「bound」の訳について #153

joemphilips opened this issue Jun 8, 2016 · 8 comments

Comments

@joemphilips
Copy link

現在トレイトのboundは「境界」と訳していますが、機能を考えると「制約・規約」といったほうが適切ではないでしょうか。トレイトがジェネリック型に「くっついている」ことのチェックという意味でのboundだと思います。

@yohhoy
Copy link
Contributor

yohhoy commented Jun 9, 2016

関連Issue #38

@joemphilips
Copy link
Author

あー失礼しました。議論済みの話題だったのですね。
ニュアンスよりも訳語を統一させることの方が大事なのでrust-by-example-jaでも「境界」と訳したいと思います

@yohhoy
Copy link
Contributor

yohhoy commented Jun 9, 2016

既にcloseされていますが、rust-lang-ja全体での訳語変更議論そのものは有意かと思います。(再openするか否かは @joemphilips さんに任せます)

@joemphilips
Copy link
Author

個人的には #38 の議論も踏まえて考えると、いっそのこと「トレイトバウンド」にしてしまうのが良いと思います。

少し待って、だれからもご意見がなければ(あるいは「境界」がベストという意見があれば)rust-by-example-jaではひとまず境界と訳しておきます

@joemphilips joemphilips reopened this Jun 9, 2016
@tatsuya6502
Copy link
Member

trait bounds という言葉は Rust 独自のもので、他の言語では使われていないようです。近いのは Scala の upper type bounds(上限境界)と lower type bounds(下限境界)でしょうか(参考)。bounds を「境界」と訳すこと自体は一般的だと思いますので、馴染みのない言葉ではありますが、いまのところ「トレイト境界」がベストな気がします。

他の言語での同種の機能と用語

C++

type constraints → 型制約

Haskell

class constraints → クラス制約

Scala

upper type bounds → 上限境界
lower type bounds → 下限境界

型システム入門(TaPL)の訳語集より

bound(s)

greatest lower bound → 下限
least upper bound → 上限
array-bounds checking → 境界検査(配列の)

bounded

bounded type operator → 有界型演算子
bounded existentials → 有界存在型

@joemphilips
Copy link
Author

ありがとうございます。
うーんなんだか余計に「制約」のほうが良いような気がしてきました。

Scalaは制約を加える対象がクラスの型パラメータであるため、頭のなかで継承関係図に線を引け、そのおかげで「境界」という訳がしっかり来るのですが、Rustは制限の対象がトレイト(つまりメソッドの型シグネチャ)であるため、境界線の形でイメージ出来ないことが違和感の原因だと思います。
array-bounds checkingも、「範囲」のイメージが強いため境界と訳しているのではないでしょうか。

Rustの場合はむしろC++の型制約に近く、しかも継承がないためなおさら「制約」という訳が適切なように思われます。

@tatsuya6502
Copy link
Member

tatsuya6502 commented Jun 10, 2016

bound には「境界」や「限界」というように、なんらかの領域の端という意味があります。「制約」とは訳しませんが、「(範囲を)限定するもの」という意味はあります。ですから「トレイト限定子」という訳は可能かもしれません。

http://dictionary.goo.ne.jp/ej/10521/meaning/m0u/

bound: [名詞] 1 ((通例 bounds)) 境界(線);区域,範囲,領域,限界,限度(limits);限定[制限,抑制]するもの

ただ、個人的には、bound の持つ、領域というニュアンスは残しておきたいです。単に「限定」だと、対象が1つなのか、ある領域(範囲)なのかはっきりせず、そのニュアンスは失われてしまいます。

なお、TRPL の用語集の章では、現時点では「境界」と訳しています。

境界(Bounds)とはある1つの型または トレイト における制約のことです。例えば、ある関数がとる引数に境界が設定されたとすると、その関数に渡される型は設定された制約に必ず従わなければなりません。


Scalaは制約を加える対象がクラスの型パラメータであるため、頭のなかで継承関係図に線を引け、そのおかげで「境界」という訳がしっかり来るのですが、Rustは制限の対象がトレイト(つまりメソッドの型シグネチャ)であるため、境界線の形でイメージ出来ないことが違和感の原因だと思います。

私は特に違和感は感じないです。

単に型パラメータを <T> とした時は「型の集合」の全体を表し、<T: PartialOrd> とすると <T> の部分集合を表すため、その2つの集合の間には境界線があります。私は、そういう意味の境界をイメージしてました。

継承関係があると範囲としてイメージしやすい、ということなら、トレイトの継承に着目するといいかもしれません。例えば、

  • f64 型は PartialOrd を実装しています
  • i32 型は Ord を実装しているので、トレイトの継承により、PartialOrd の実装も求められます

構造体 Vec<T>Vec::new() 関数は、trait bounds を持たないので、任意の型を取れます。また、Vec<T>partial_cmp() メソッドは、trait bound <T: PartialOrd> を持つので、f64 (PartialOrd) と i32 (Ord) の両方を受け付けます。

    // f64 は PartialOrd のみ実装
    let vec1 = vec![1.0, 2.0, 3.0];
    let vec2 = vec![2.0, 1.0, 3.0];
    let p_cmp12 = vec1.partial_cmp(&vec2);  // impl<T: PartialOrd> PartialOrd for Vec<T>

    // i32 は Ord と、その親トレイトである PartialOrd を実装
    let vec3 = vec![1, 2, 3];
    let vec4 = vec![2, 1, 3];
    let p_cmp34 = vec3.partial_cmp(&vec4);

一方で、Vec<T>cmp() メソッドや BTreeSet<T>BTreeSet::new() 関数は、trait bound が <T: Ord> なので、f64 を受け付けません。

    // vec1: Vec<f64>, vec2: Vec<f64>
    let cmp12 = vec1.cmp(&vec2); // impl<T: Ord> Ord for Vec<T>
    // => error: no method named `cmp` found for type `std::vec::Vec<_>` in the current scope
    //    note: the method `cmp` exists but the following trait bounds were not satisfied:
    //    `_ : std::cmp::Ord`, ...

    // vec3: Vec<i32>, vec4: Vec<i32>
    let cmp34 = vec3.cmp(&vec4); // => ok

    let set1: BTreeSet<f64> = BTreeSet::new();  // impl<T> BTreeSet<T> where T: Ord
    // => error: the trait bound `f64: std::cmp::Ord` is not satisfied [E0277]

    let set2: BTreeSet<i32> = BTreeSet::new();
    // => ok

トレイトの継承により、<T: PartialOrd> という trait bound は、PartialOrd を実装した型 f64 だけでなく、Ord を実装した型 i32 も対象に含むことになります。一方で、<T: Ord> という trait bound は、PartialOrd だけを実装した型 f64 は対象に含みません。これは、実現方法は異なりますが、結果的には、Scala の upper type bound と同じ機能といえないでしょうか。

@joemphilips
Copy link
Author

単に型パラメータを とした時は「型の集合」の全体を表し、<T: PartialOrd> とすると の部分集合を表すため、その2つの集合の間には境界線があります。私は、そういう意味の境界をイメージしてました。

この一言で腑に落ちました。
TRPLで境界と訳しているのが決定的だと思いますので、やはり境界と訳そうとおもいます。
どうもありがとうございます。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants