タグ

ブックマーク / qnighy.hatenablog.com (8)

  • Rust パターンマッチの変数束縛とコンストラクタ/定数の区別 - 簡潔なQ

    パターンマッチを持つ言語では、変数束縛とコンストラクタ/定数が構文上曖昧である場合がある。Rustでは以下の規則に従っている。 以下のように、構文的にパスであるとわかる場合は、常にコンストラクタ/定数とみなす。 :: を含んでいる場合。 (::A, self::A, <T as Trait>::X など) {} を後続する場合。 (A {} など) () を後続する場合。 (A() など) ../.../..= などの一部である場合。 (FOO_MIN .. FOO_MAX など) ! を後続する場合。 (your_macro_expanding_to_a_pattern!() など) 反駁不可文脈では常に変数束縛とみなす。反駁不可文脈かどうかは以下のように定義される。 match, if let, while let のパターンは反駁可能でもよい。 let, for, 関数の引数部のパタ

    Rust パターンマッチの変数束縛とコンストラクタ/定数の区別 - 簡潔なQ
    yhara
    yhara 2021/05/29
  • Rustの型推論の概略 - 簡潔なQ

    概要: Rustの型推論の大枠を説明する。 なお、筆者もRustの型推論の動作を詳細に把握しているわけではない。 短くまとめると Rustの型推論はHindley-Milner型推論ベースである。したがって後方の式や文の内容から手前の型が推論されることもある。しかし以下に挙げるようなRust独自の特徴をもつ。 型推論は原則として関数定義の中で閉じており、関数の引数型や戻り値型は推論されない。これは、関数を抽象化の境界とするための意図的なものである。この意味で「局所的」というのであれば間違いではない。 ただし、let多相を含む型推論を避ける意図もあるかもしれない。 関数呼び出しや一部の演算子などは、その部分の制約を立てる段階で、型の一部分が判明している必要がある。この動作は推論順序の影響を受ける。 トレイトによりオーバーロード可能になっている関数や演算子は、射影型を使っている場合、ボトムアッ

    Rustの型推論の概略 - 簡潔なQ
  • Rustのthread local gensym/internパターン - 簡潔なQ

    概要: Rustでgensymおよびinternを行う方法を説明する。 gensymとinternとは何か gensymパターンは、「まだ使われていない整数」を返す fresh() 関数を実装するというパターンである。型推論などで一時変数を作成するなどの用途で用いられる。 internパターンは、文字列などの複雑なデータに対し、データの同値性に基づいて整数を振ることで簡単に比較等できるようにするというパターンである。 Rustによるthread local gensym gensymは以下のように実現される。 スレッドローカル変数に、今まで払出した整数の最大値を記録する。 必要に応じてこの変数をインクリメントする。 このとき生成されたIDは他スレッドと共有できないため、 !Send をつける。 use std::cell::Cell; // u32を包む #[derive(Debug, C

    Rustのthread local gensym/internパターン - 簡潔なQ
    yhara
    yhara 2017/03/26
  • Rustマクロの衛生性はどのように実現されているか(1/2) 識別子に関する衛生性 - 簡潔なQ

    概要: Rustマクロは2つの意味で衛生的である。その衛生性の説明とともに、それを実現するためのコンパイラの仕組みを説明する。 Rustマクロの2つの衛生性 Rustマクロ (ja) は次の2つの意味で衛生的(hygienic; 健全ともいう)である。 マクロ内で導入される変数名と、マクロ呼び出し側の変数名が衝突しない。(Lispマクロの意味での衛生性) 構文の優先順位の違いによる非直感的な挙動が発生しない。 この記事では、識別子に関する衛生性を説明する。(構文の優先度に関する衛生性については次記事を参照) 識別子に関する衛生性とは 次のようなプログラムが直感的な動作をするのが、識別子に関する衛生性である。 macro_rules! copy_swap { ($x:expr, $y:expr) => {{ let t = $x; $x = $y; $y = t; }}; } fn main

    Rustマクロの衛生性はどのように実現されているか(1/2) 識別子に関する衛生性 - 簡潔なQ
  • Rustで型の多相再帰はできない - 簡潔なQ

    OCamlやHaskellに比べると、Rustは多相再帰ができない場合がほとんどである。以下にその詳細を説明する。 多相再帰 異なる型引数による再帰呼び出しを多相再帰 (polymorphic recursion) という。多相再帰はPurely Functinoal Data Structuresで紹介されているようなデータ構造でよく出てくる。例えば、完全二分木はOCamlとHaskellではそれぞれ以下のように書ける。 type 'a sep = Nil | Cons of ('a * 'a) sep data Sep a = Nil | Cons (Sep (a, a)) これがlistの定義と異なることがわかるだろうか。listでは 'a list の定義に 'a list という形の型のみを用いる。ここでは 'a sep の定義に ('a * 'a) sep を用いている。これが

    Rustで型の多相再帰はできない - 簡潔なQ
  • クロージャを boxせずに 返したい: Rustのconservative_impl_traitとimplementation leak - 簡潔なQ

    概要: 「クロージャを boxせずに 返したい」という欲求は人類の四大欲求のひとつと言われている。 conservative_impl_trait という機能を使うことでこれをスパッと解決できるが、これは単なる構文糖衣にとどまらずRustの型システムにい込むこともあってかまだ安定版入りしていない。なぜこの機能が必要で、なぜこの機能が問題かを説明する。 クロージャをboxせずに返したい話 Rustではクロージャに異なる型がつく OCamlやHaskellのような言語では、外の環境を引き継ぐ無名関数 (クロージャ) を次のように作ることができるのであった。 let mult_curry x = fun y -> x * y この関数は x を受け取り、「y を受けとってx * yを返す関数」を返す。この「y を受けとって x * y を返す関数」は、 y というデータを引き連れている。そして

    クロージャを boxせずに 返したい: Rustのconservative_impl_traitとimplementation leak - 簡潔なQ
    yhara
    yhara 2017/03/13
    impl Traitというもののはなし
  • スパコンをオリンピック論で擁護してみた - 簡潔なQ

    仕「世界一である必要はあるのか。二位では駄目なのか」 俺「オリンピックで金メダルが要らないとでも言うのか」 仕「オリンピックは参加することに意義があるのだ」 あ…れ…?

    スパコンをオリンピック論で擁護してみた - 簡潔なQ
    yhara
    yhara 2009/11/23
  • プログラマの諸君、クリスマスを廃止なんてしちゃだめだよ - 簡潔なQ

    君にはPerl6という最愛の恋人がいるだろ?

    プログラマの諸君、クリスマスを廃止なんてしちゃだめだよ - 簡潔なQ
    yhara
    yhara 2009/11/23
  • 1