Rust part33 (229レス)
Rust part33 http://mevius.5ch.net/test/read.cgi/tech/1755247770/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
33: デフォルトの名無しさん [sage] 2025/08/24(日) 06:23:07.67 ID:yIg8YRK3 分野によって用語の意味にブレがあるからそういうのを厳密に考えてもあんまり意味ない。 狭義の多値は継続 (continuation) に複数の値が渡ることをいうのでたぶん >>28 はその意味で言ってて、その意味ではタプルは多値ではない。 単なる言語ユーザの目線ではタプルにまとめて受け渡すことと複数の値を受け渡すことには何も違いはないから同一視しても何も困らないよ。 形式論理とかの世界の話。 http://mevius.5ch.net/test/read.cgi/tech/1755247770/33
34: デフォルトの名無しさん [sage] 2025/08/24(日) 06:51:31.37 ID:Q1fxgDlW 重要なことはオーバーヘッドの有無 タプルをオブジェクトの一種として扱う言語はオブジェクトを用意してそのアドレス単値のみを渡すため間接アクセスのオーバーヘッドが生じる タプルを多値として扱うRustは多値として渡せるためオーバーヘッドが生じない もちろんRustではタプルをBoxに入れることでアドレス単値のみ返すことも可能でオブジェクト方式の言語は常にそれをしていることになる http://mevius.5ch.net/test/read.cgi/tech/1755247770/34
35: デフォルトの名無しさん [sage] 2025/08/24(日) 07:38:29.67 ID:yIg8YRK3 アーキテクチャによって ABI は違うかもしれないけど一般的な実装としては 関数の返却値が大きい時は呼出し側でメモリを確保してそれを隠れた引数として渡すようなメカニズムになってる。 返却値はスタックを介さない。 これは C++ でも同じ。 http://mevius.5ch.net/test/read.cgi/tech/1755247770/35
36: デフォルトの名無しさん [sage] 2025/08/24(日) 07:52:38.38 ID:lHuVCVKu >>35 ほぼ合っているが一部だけ違う 間違ってる部分は「スタックを介さない」 正解は「スタックを介す」ことで高速に引き渡す サイズの大きな値を返す場合 具体的には呼び出し元でスタックポインタを増減することでスタックフレームを拡大してその確保領域のアドレスを隠れた引数としてレジスタ渡しする 呼び出された関数側ではその確保領域に直接書き込んで値を返す ヒープ領域を確保して受け渡す方式と比べるとメモリ領域確保のコストがない点とスタック上でそのままメモリキャッシュに乗る点で有利 http://mevius.5ch.net/test/read.cgi/tech/1755247770/36
37: デフォルトの名無しさん [sage] 2025/08/24(日) 07:56:09.24 ID:lHuVCVKu ちなみにRustでx64アーキテクチャの時 16バイトまでならレジスタ渡しになり上記スタック領域は使われないため更に速い http://mevius.5ch.net/test/read.cgi/tech/1755247770/37
38: デフォルトの名無しさん [sage] 2025/08/24(日) 08:16:24.05 ID:lHuVCVKu ごめん、肝心なところ書き間違えてる ✕ 16バイトまでならレジスタ渡し ○ 16バイトまでならレジスタ返し http://mevius.5ch.net/test/read.cgi/tech/1755247770/38
39: デフォルトの名無しさん [sage] 2025/08/24(日) 10:58:20.04 ID:lOj53x5G 言語が多値返却をサポートしてるかどうかというのは文法としてサポートしてるかどうかという意味 文法的にはサポートしてないけど「〇〇使えば多値返却できる」のは当たり前 一般的なプログラミング言語で「Functions can use 〇〇 to return multiple values」の〇〇に当てはまるものがない言語は無いので意味がない 文法的にサポートしているかどうかと内部実装がどの程度最適化されるのかはまた別の話 http://mevius.5ch.net/test/read.cgi/tech/1755247770/39
40: デフォルトの名無しさん [sage] 2025/08/24(日) 11:01:04.53 ID:o5OQy7cK 多値が返せるか?の意味なんて、ユーザ的には戻り値の分割代入ができるか?ってだけだし ダラダラ言わずに返せますで終わりでよくね http://mevius.5ch.net/test/read.cgi/tech/1755247770/40
41: デフォルトの名無しさん [] 2025/08/24(日) 11:17:14.32 ID:DLpoJrbF Rustは多値を返す機能があるだけでなく その実装も本当に多値を返すため効率よく実行も速いことが特徴 http://mevius.5ch.net/test/read.cgi/tech/1755247770/41
42: デフォルトの名無しさん [sage] 2025/08/24(日) 11:34:24.43 ID:yIg8YRK3 >>40 仕様を読むときは言語の理屈や用語をわかってないとちゃんと読めない。 複数の要素をひとつにまとめたもの (タプルや構造体) をひとつ返すというのと複数の値を返せるというのは違うことなんだが、 Rust では同一視することにしたというならそれはそれで同一視しているという理屈をわかってないといけない。 http://mevius.5ch.net/test/read.cgi/tech/1755247770/42
43: デフォルトの名無しさん [] 2025/08/24(日) 11:46:57.61 ID:s620v8qa >>42 それは屁理屈 プログラマとしては多値を返せる機能があればよいわけで、 それがタプルという形で実現されていようが困ることは何一つない 逆に、タプルをサポートしていればそれだけで十分であり、 タプルでない多値をサポートするメリットが何もない http://mevius.5ch.net/test/read.cgi/tech/1755247770/43
44: デフォルトの名無しさん [sage] 2025/08/24(日) 11:50:38.02 ID:yIg8YRK3 >>43 実際に (複数の要素をタプルなどにまとめるのではなく) 多値をサポートしてる言語はあるわけだが、ディスってんの? 言語の理屈の構成の仕方の話であって言語としてのメリットの話なんかしてない。 http://mevius.5ch.net/test/read.cgi/tech/1755247770/44
45: デフォルトの名無しさん [sage] 2025/08/24(日) 11:58:39.52 ID:sGVh/967 多値をサポートしてる言語の例としてGoが上で挙げられているけどさ Goはタプルがなくてみんな困っている タプルがある言語では多値がなくて困った話は聞かれない 機能として『タプル ⊃ 多値』 だからだよ http://mevius.5ch.net/test/read.cgi/tech/1755247770/45
46: デフォルトの名無しさん [sage] 2025/08/24(日) 12:05:10.36 ID:DXAve6fe Goでタプルがなくて辛いという話は聞いたことがないな 最適化の観点抜きで機能的に他でカバーできるから不要と言ってしまうと、 例えばオブジェクトは全部ヒープに置いてスマポの所有権移動だけにしてしまえば複雑なムーブは不要となり遥かにシンプルになる それはそれで一つの考え方だが、Rustはそういう言語ではないと思っているのだろう? http://mevius.5ch.net/test/read.cgi/tech/1755247770/46
47: デフォルトの名無しさん [sage] 2025/08/24(日) 12:08:19.32 ID:veJK4T2Q 返却された値がスタック上でどう扱われるかというのは言語仕様でなく最適化の問題だから、そこはRustではなくLLVMの話 言語仕様としては「Rustではタプルを簡単に作れる」「タプルの中身を別々の変数に束縛できる」というだけ 多値返却の目的からすればこれで十分だし、多くの言語はこれに相当する Goは本当に多値返却という仕様で、これはタプルを返すのとは違う そもそもタプルが言語仕様になくて、関数の返り値でだけ多値を返せるという変わった仕様 だから、2つの戻り値を返す関数を1変数で受け取ることができなかったりする (Rustでいえば「戻り値を分解せず1つのタプル変数 t で受け取る -> t.0, t.1 のようにアクセスする」という書き方がGoではできない) だから言語仕様としての話をしたいのか、「関数から複数の戻り値を返す」という目的の話をしたいのかで話は変わる 後者については、最近の多くの言語ではサポートしてるし、そんなに話がズレることもない 前者の意味でなら、Rustは多値返却の構文を持つ言語とは違う http://mevius.5ch.net/test/read.cgi/tech/1755247770/47
48: デフォルトの名無しさん [sage] 2025/08/24(日) 12:16:23.06 ID:aQdKZ7zp Goの多値とRustのタプルは同じ どちらも実装は多値として返すため多値レジスタ返しが可能ならばそうするため効率が最も優れている 関数定義もほぼ同じ func foo() (type1, type2) {… fn foo() -> (type1, type2) {… http://mevius.5ch.net/test/read.cgi/tech/1755247770/48
49: デフォルトの名無しさん [sage] 2025/08/24(日) 12:16:31.50 ID:tCu5AZNy バカなやつほど抽象度の区別ができない バカなやつほどオレオレ定義で用語を使う バカなやつほど主語を書かない 本当に相手にする価値があるか考えよう 改善の見込みがないバカなら何を書いても時間の無駄でしかない http://mevius.5ch.net/test/read.cgi/tech/1755247770/49
50: デフォルトの名無しさん [sage] 2025/08/24(日) 12:26:32.12 ID:95hjiUrq 多値を抽象化して機能を強化したものがタプルだもんね だから多値でできることは全てタプルでもできるんだよ タプルを持つ言語は機能の低い多値を別途持つ必要がない http://mevius.5ch.net/test/read.cgi/tech/1755247770/50
51: デフォルトの名無しさん [sage] 2025/08/24(日) 12:50:55.19 ID:veJK4T2Q 「タプルがあれば十分」は殆どのケースでは同意するけど、Goに限ってはそうする理由があるんだよ エラーを多値で返す仕様かつ、エラー処理を明示的に書かせる思想の言語だから value, err := foo() のように err がコード上に表れるようにする必要があって、これはタプルだとまずい t := foo() と書けてしまうと「タプルの2要素目がエラー」というのが見えなくなる これは割とGo特有の事情で、Result型や例外を使う言語だとタプルでも困らない 言語仕様というのは他の部分も含めた全体的なデザインとして考えるものだから、「Rustではタプルで困らない」が正しくても、他の言語含めて全てそうだとは言えない http://mevius.5ch.net/test/read.cgi/tech/1755247770/51
52: デフォルトの名無しさん [sage] 2025/08/24(日) 12:56:30.01 ID:9a3ehhoR >>49 >バカなやつほど抽象度の区別ができない >バカなやつほどオレオレ定義で用語を使う >バカなやつほど主語を書かない 汚コーダーの特徴が濃縮されてるね 3番目は「書かない」というより「書けない」だと思う http://mevius.5ch.net/test/read.cgi/tech/1755247770/52
53: デフォルトの名無しさん [sage] 2025/08/24(日) 13:02:12.19 ID:LAWD3p/v 原始的な剥き出しの多値を扱う必要のない言語においては、タプル多値があれば多値をサポートしているという結論でいいんじゃないかな http://mevius.5ch.net/test/read.cgi/tech/1755247770/53
54: デフォルトの名無しさん [sage] 2025/08/24(日) 13:07:02.23 ID:vekMbO+E Rustはnamed tupleもanonymous structもなくunnamed tupleで位置でアクセスするか事前に定義した型で名前でアクセスするかしかないから利便性ではモダンな他言語に一段劣る http://mevius.5ch.net/test/read.cgi/tech/1755247770/54
55: デフォルトの名無しさん [sage] 2025/08/24(日) 13:18:17.18 ID:kBf9AmUd >>54 これ便利だと思う? # まずnamedtuple関数をインポートします from collections import namedtuple # 次にNamed Tupleを定義します Point = namedtuple('Point', ['x', 'y']) # そしてインスタンスを作ります p = Point(10, 20) # 名前でアクセスできるようになります print(p.x) # Output: 10 print(p.y) # Output: 20 http://mevius.5ch.net/test/read.cgi/tech/1755247770/55
56: デフォルトの名無しさん [sage] 2025/08/24(日) 13:28:22.18 ID:fUN48E4b >>51 いや、エラーに限らずt.0とか普通に可読性最悪だからね 多値をタプルとして実装するなら、即時の分割代入を必須とするか、もしくはC#のようにpositionalなタプルと互換性のあるnamed tupleとするか、どちらかは必須 http://mevius.5ch.net/test/read.cgi/tech/1755247770/56
57: デフォルトの名無しさん [sage] 2025/08/24(日) 13:41:09.97 ID:uDNIRrgr 必要となるまでは1つのまとまりとして一括して扱えたほうが有利 必要になったところでパターンマッチングさせて個別に用いる http://mevius.5ch.net/test/read.cgi/tech/1755247770/57
58: デフォルトの名無しさん [sage] 2025/08/24(日) 13:49:22.14 ID:+tDfyqBW Rustは必要なところではパターンマッチングできるから不便なことはないよな http://mevius.5ch.net/test/read.cgi/tech/1755247770/58
59: デフォルトの名無しさん [sage] 2025/08/24(日) 13:56:11.80 ID:fUN48E4b 取得から消費までのコード上の距離が離れるほど人間の短期記憶の負担になり可読性が低下する 複おじは特に頭悪いから実感してるんじゃない? http://mevius.5ch.net/test/read.cgi/tech/1755247770/59
60: デフォルトの名無しさん [sage] 2025/08/24(日) 14:11:41.28 ID:0UxuBUhy let (unko, chinko) = unkochinko とか突然出てきてunkochinkoの宣言が離れてたら、合ってるのか不安を感じてつい宣言までスクロールしちゃうわ 離れた場所での位置依存は普通に可読性最悪 http://mevius.5ch.net/test/read.cgi/tech/1755247770/60
61: デフォルトの名無しさん [sage] 2025/08/24(日) 14:14:05.68 ID:ieA/MpG4 >>56 ジェネリックに意味を持たない局面もあるからそこでt.0を使うのは適してる 意味がある局面なら例えばfor (index, name) in ...や|(index, name)| ...のように使われるから名前でアクセスできる http://mevius.5ch.net/test/read.cgi/tech/1755247770/61
62: デフォルトの名無しさん [] 2025/08/24(日) 14:15:37.70 ID:veJK4T2Q >>56 C#も分割代入しない書き方はできるじゃん その場合の可読性はPythonもC++もC#もそう変わらないかと (t[0], get<0>(t), t.Item1) 意味のある名前を付けたいなら、それはRustでもstructを定義すれば済む話だし C#の匿名クラスの便利さもまあ分かるけど、あれば嬉しいくらいで、個人的には必須とまでは思わない http://mevius.5ch.net/test/read.cgi/tech/1755247770/62
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 167 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.006s