新しいものを表示

ある意味null安全に近い話なのかも?><;(オレンジは、内容が不正であることのフラグとして(手抜きで)null許容型を使うこともたまにある><;)

orange さんがブースト

C++ も (iostream 辺りは歴史的事情か例外のパフォーマンスの事情かアレな感じだけど)、基本的に「不正な状態のオブジェクトを作らず、 ctor で例外を投げろ」という感じになっているし、「正しいものしか存在できない」という感じの世界を作りたさが感じられる

orange さんがブースト

理想的には型チェックが通った時点で、表明されていたあらゆる制約が満たされていることを確認したいわけで、「URL として妥当であるか」というのは「Url 型のオブジェクトとして存在できるか」と一致してほしい

なんでこんな謎方式にしたいかと言うと、宣言時に例外が出ると後始末がぐちゃってするのが嫌で、それを回避できるならチェックするのは分けたいし、毎回チェックする手間が増えてもって感覚がある><;

orange さんがブースト

Url 型のオブジェクトが出現したその瞬間から死ぬまで、ずっと Url は URL として valid な値しか持てないでほしい (型を妥当な値の集合として考えれば) ので、 new からの url.Check() で例外を飛ばすのは、ちょっと型の意味が弱すぎるかなぁという気持ちがしますね

xだねっぽさ oだめっぽさ
ダメっぽい><;

さっきのURLの処理みたいなの、オレンジの好みの架空言語ならば・・・><;
ReadOnly StringUTF8 url_string = "example .com";
Url url = new Url( url_string );

url.Check();
//不正な文字列なら例外

bool urlDanepposa = url.IsInvalidURL;
//不正かどうかのプロパティ

bool urlDaijoubupposa = url.IsValidated;
//ポジティブとネガティブもどっちも要るよね!><;

orange さんがブースト

C でもブロックを明示すれば同じことはできるので、よーするに Rust ではブロックを暗黙に作ってくれるというだけのようなもの (あと Rust ではブロックも式であり値に評価されるので、この解釈とは相性が良い)

スレッドを表示

ある意味スタックっぽい挙動?><;

orange さんがブースト

let foo = 1;
let foo = "foo";
bar(foo);

というのは、実際には

{
let foo = 1;
{
let foo = "foo";
{
bar(foo);
}
}
}

のようなことをやっているわけで、 shadow された変数が消えるわけでもないし破棄されるわけでもないし上書きされるわけでもない、あくまで shadow されて「名前で」参照できなくなるだけ

スレッドを表示
orange さんがブースト

あと Rust の shadowing は redeclaration ではないと思います

orange さんがブースト
orange さんがブースト

monad の do 記法を以て再宣言可能とするのは大嘘では????

Pascalなんて途中で宣言がそもそもできない>< Pascalすばらしい><(そこはちょっとめんどくさいと思ってました><;)

同一スコープ内での同名変数の再宣言とシャドウイング|Rustでは再宣言が可能 qiita.com/aimof/items/01911a18

"別の言語ではどうなるか? その2:再宣言できる言語"

"Haskellでは、再宣言可能です。ちなみにHaskellの変数(と呼ぶのが適切かはわかりませんが)はimmutable(不変)です。"
めっちゃくちゃ変化してるじゃん?><;

右辺で型が自明じゃない記述にしか見えないし、そもそもシャドーイング?で何がうれしいのかさっぱりわからないかも・・・><

orange さんがブースト

ただ、この方式だと lifetime あたりの問題があって、たとえば

let name = read_line(); // 所有権ありの文字列
let name = name.trim(); // 旧 name の一部を borrow しているスライス

みたいなことができない (旧 name の生存期間が新 name の生存期間以上でなければならない) ので、万能ではない

スレッドを表示
orange さんがブースト

たとえば

let age = read_line();
let age = age.parse::<u32>().expect("Invalid age");

みたいにすれば、あるべき型の age にしかアクセスできなくなるので、 age_str と age_int が共存するよりも望ましいと考えることができる

スレッドを表示
orange さんがブースト

あと、シャドーイングをすると、たとえばこの例だと「2回目の束縛以降で、不正でありうる文字列型の URL データにアクセスできなくなる」という利点がある (URL でなく文字列として取り出したければ、明示的にそういう操作を行うべき)

スレッドを表示
orange さんがブースト

たとえば

let url = "example.com/"; // ここで文字列
let url = Url::parse(url).expect("Invalid URL"); // ここで Url 型

みたいなシャドーイングしたい場合があって、これもまあ賛否分かれるかもしれないけど、あくまで変数の意味を扱ってロジックを書きたいならこれもアリだと思いますね

古いものを表示
:realtek:

思考の /dev/null