C vs C++ vs Rust Part.2

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2021/12/15(水) 12:35:50.91ID:biBE4xC0
競え
※前スレ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
2デフォルトの名無しさん
垢版 |
2021/12/15(水) 12:36:12.51ID:biBE4xC0
たったぞ
3デフォルトの名無しさん
垢版 |
2021/12/15(水) 12:36:52.73ID:z10T13Tn
C vs は余計だった
2021/12/15(水) 13:56:40.08ID:e2FwtkWT
Cに原点回帰しようよ
2021/12/15(水) 13:57:35.77ID:Z/edc862
GoはC++というよりCっぽいよな
2021/12/15(水) 14:37:20.55ID:30tmY3QB
Goはモダン言語にアレルギー反応が出てしまうC老人のための言語
2021/12/15(水) 16:01:42.93ID:pLz5Pfsh
顔真っ赤な怒り心頭Rustオジサンがなぜかスレタイに無いGoを粘着でディスり続ける
2021/12/15(水) 16:09:17.23ID:IT6MYik3
言語仕様が優れてるとかなんとかはあるだろうけど
結局使いものになる言語は何かと言われればC/C++なんだよ
2021/12/15(水) 16:23:40.38ID:Il5L6NWm
Rustは流行りもの
C、C++は基本
2021/12/15(水) 17:32:42.49ID:sKDBKV7A
RustとC++が互いに馬鹿にし合うのをCが高みの見物するスレですか?
2021/12/15(水) 18:10:14.36ID:t4BO72er
CやC++なんて、UNIXかWindowsが成功してなきゃ流行ってたわけない
(そもそもUNIXがないなら、C言語も生まれてないけど)
結局は勝ち組プラットフォームにおんぶにだっこされてるだけよ

Rustも巨大企業に推されて採用されてるから、優れてる言語かどうかに関係なく流行る

流行は巨人が決めてる
2021/12/15(水) 18:23:30.40ID:EKKmEU1R
Rustンサーガ
パンツ一丁でオッサンが闘うヤツ
2021/12/15(水) 18:49:53.25ID:8Epoo61s
本当のプログラマはPascalを使う
2021/12/15(水) 19:02:30.51ID:mn4aHBsE
May the FORTH be with you.
2021/12/15(水) 19:10:44.73ID:WtUWAuhG
いまだに組み込みはCオンリーですが、「UNIXがないなら、C言語も生まれてない」は間違いに近い
https://ja.wikipedia.org/wiki/C言語#歴史
16デフォルトの名無しさん
垢版 |
2021/12/15(水) 19:15:49.17ID:A/sMbUcd
>>8
でもチーム開発するならRustの安全性は100%じゃないとしても十分魅力的だなぁと思う。
17デフォルトの名無しさん
垢版 |
2021/12/15(水) 19:21:40.26ID:A/sMbUcd
>>15
それ読んだら、
UNIXの *ために* C言語が作られたわけじゃないけど、UNIXが *なかったら * C言語も生まれてない、と読めるけど。
18デフォルトの名無しさん
垢版 |
2021/12/15(水) 19:59:26.95ID:pgpgQ+mf
>>9
C・・・ベーシックアイテム。
C++・・・おしゃれアイテム。
Rust・・・意識が高くなる壷。
19デフォルトの名無しさん
垢版 |
2021/12/15(水) 20:02:20.26ID:pgpgQ+mf
RustやRubyは、まず伝道師から始まるからな。
どういうわけか伝道師が大量発生する。
20デフォルトの名無しさん
垢版 |
2021/12/15(水) 20:03:30.36ID:pgpgQ+mf
C++使いがコード書いてる間、彼らは伝道する。
神の使いなのかもしれんな。
啓示があったんだろう。
2021/12/15(水) 20:08:47.10ID:KpHwa+U5
Rustは実用に主眼を置いた泥臭い言語なので
伝道師の言う美辞麗句は無視してよい
22デフォルトの名無しさん
垢版 |
2021/12/15(水) 21:48:54.34ID:A/sMbUcd
っつか、いくら伝道師わいたってRust自身がその敷居の高さで安易に手を出すやつを排除するからRubyみたいには使われないんじゃねーの?
2021/12/16(木) 11:27:59.15ID:iS9fah9V
プログラミング勉強のため素数列を返すイテレータ関数を作ってみました
今回トレイト境界は0と1とoverflow防止足し算と比較演算子のみとなりました

use itertools::{unfold, Unfold};
fn prime<T>() -> Unfold<T, impl FnMut(&mut T) -> Option<T>>
 where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
 unfold(T::one(), |a| {
  unfold(*a, |b| { if let Some(c) = b.checked_add(&T::one()) { *b = c; Some(c) } else { None } }).map(|b| { *a = b; b })
  .find(|b| !unfold(T::one(), |c| { if let Some(d) = c.checked_add(&T::one()) { *c = d; if d < *b { Some(d) } else { None } } else { None }})
  .find(|c| unfold(T::zero(), |d| { if let Some(e) = d.checked_add(c) { *d = e; if e <= *b { Some(e) } else { None } } else { None } }).any(|d| d == *b)).is_some())
 })
}

型指定で『i8』(符号付き8bit整数)を与えて実行してみます

fn main() {
 for p in prime::<i8>() {
  print!("{} ", p);
 }
}

出力結果
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127

i8型は127が上限値(2^7-1)なので上手く動作してるようです
コードが少し長くなってしまったので冗長なところや改善点など教えていただけると幸いです
2021/12/16(木) 14:51:19.13ID:fwM+9qOy
クソコード過ぎでこんなの誰も見ないよ
2021/12/16(木) 15:20:11.27ID:iS9fah9V
>>24
良いコードをご教授していただけませんか?
普通にループは使わずに足し算と比較のみで素数をその型の上限まで返すイテレータ関数です
言語はCでもC++でもRustでも構いませんのでよろしくお願いします
2021/12/16(木) 15:29:32.29ID:Hlz92r+j
Playgroundでu16に変えたらTLEした
27デフォルトの名無しさん
垢版 |
2021/12/16(木) 15:30:55.42ID:OBc86cw8
>>25
>>23ですらループ使ってるじゃん
馬鹿そう
2021/12/16(木) 15:38:05.88ID:iS9fah9V
>>27
どこにループが有りますか?
勉強不足でわからないので教えてください
2021/12/16(木) 15:59:44.48ID:V9bBAe8M
Rustのコードはなに見てもきたねぇな
2021/12/16(木) 16:08:39.90ID:iS9fah9V
>>29
それは私がプログラミング勉強中だからだと思います
あるいはCやC++ならば「ループを使わずに足し算と比較のみで素数をその型の上限まで返すイテレータ関数」を
綺麗にプログラミングできますか?
綺麗なコードをご教示していただけるとうれしいです
2021/12/16(木) 17:08:55.09ID:3qs6QL/g
>>23
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=3e0c372e78ce024307bd58c1f03df55e

.find(..).is_some() は .any() と書ける (これはclippyが指摘してくれる)
if let Some(x) = expr { .. } else { None } は let x = expr?; .. とした方がネストが浅くなる
類似の処理は名前をつけて関数に括りだした方がわかりやすい
2021/12/16(木) 17:33:56.80ID:3qs6QL/g
>>23
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=6d5f63ffe7c46236a0957017db33a0b9
もう少し改善できた
スレ汚しすまん
2021/12/16(木) 17:35:37.19ID:M/ZR00Mb
>>31のコード見た後に>>23見るとゲロ吐きそうになるな
34デフォルトの名無しさん
垢版 |
2021/12/16(木) 18:18:18.75ID:OBc86cw8
>>28
例えばfindはtry_foldを呼び出してるがこのメソッドはwhileを使って実装されている
どこかにループあるとわかりそうなもんなんやけどな
35デフォルトの名無しさん
垢版 |
2021/12/16(木) 18:19:05.42ID:OBc86cw8
rustのコードはc/c++以上に見苦しい
こんな言語を業界全体でプッシュしてるのは異常だよ
2021/12/16(木) 18:37:24.71ID:3qs6QL/g
>>35
どの業界の話だよ
2021/12/16(木) 18:55:01.30ID:7LXHVZ3Z
日本のC++業界だよ
2021/12/16(木) 19:06:28.01ID:0UZhzBxa
なんでこいつRustの本スレでやらないんだろ、ほんまキモイ
2021/12/16(木) 19:15:09.93ID:bRADTu+t
本スレで自己満足やられて本気でウザかったからここでいいよ
40デフォルトの名無しさん
垢版 |
2021/12/16(木) 19:40:56.05ID:OBc86cw8
だからここはガイジ隔離用のスレなんやで
2021/12/16(木) 20:00:41.75ID:iS9fah9V
>>31
色々とありがとうございます
返り型がOptionだから?を使うとif letを消せるとは気付いていませんでしたw
あとそのコードを見ると渡す値を変えないならmapよりinspectを使うといいのですね
さらにご指摘くださったfindとis_someを合わせてanyにしたり否定!と合わせてallへ変えたり
まだ類似部分の別関数への分離までは進められていないのですがようやくここまで来ました

fn prime<T>() -> Unfold<T, impl FnMut(&mut T) -> Option<T>>
 where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
 unfold(T::one(), |a| {
  unfold(*a, |b| {
   *b = b.checked_add(&T::one())?;
   Some(*b)})
  .inspect(|b| *a = *b )
  .find(|b| unfold(T::one(), |c| {
   *c = c.checked_add(&T::one())?;
   (*c < *b).then(|| *c)})
  .all(|c| unfold(T::zero(), |d| {
   *d = d.checked_add(&c)?;
   (*d <= *b).then(|| *d)})
  .all(|d| d != *b)))
 })
}

>>34
どうもありがとうございます
調べて勉強します
2021/12/16(木) 20:07:32.48ID:22XvzF/H
字面だけみるとPerlとどっこいの汚さだな
2021/12/16(木) 20:20:38.68ID:aj4Oe3UU
>>35 >>42
これ全く同じ機能をC++だと美しく書けるんかいな?
前スレでもRustの動くコードは出ていたがC++の動くコードは全く出てこなかったよな
だから既にC++プログラマーは絶滅していてRust派とアンチRust派(数学100点マン等)だと思ってた
2021/12/16(木) 20:25:07.71ID:IyRKg3i2
unfold使ったこと無いから間違ってたら教えてほしいんだけど
これO(n^4)?
2021/12/16(木) 20:34:01.51ID:V9bBAe8M
ゲロのようだ
46デフォルトの名無しさん
垢版 |
2021/12/16(木) 20:37:46.92ID:Y2CVy/MB
さわやかな新宿の朝って感じですね。
ゲロの臭いでもらいゲロしそう。
2021/12/16(木) 20:54:48.37ID:iS9fah9V
>>44
違うと思います
まずunfold自体はループするものではなくこれだけです
struct Unfold<S, F> { s: S, f: F }
fn unfold<S, F, R>(s: S, f: F) -> Unfold<S, F> where F: FnMut(&mut S) -> Option<R> {
 Unfold { s, f }
}
impl<S, F, R> Iterator for Unfold<S, F> where F: FnMut(&mut S) -> Option<R> {
 type Item = R;
 fn next(&mut self) -> Option<Self::Item> {
  (self.f)(&mut self.s)
 }
}

次に今回のコードで使われているunfoldについてですが
一番外側のunfoldは上述の構造体を返すだけになります
次のunfoldは素数でない数をスキップするだけで残り2つがO(n^2)となるでしょうか
どの言語で書いても足し算のみ使用だとこれは避けられないかと思います

あとコードが汚いとおっしゃる方は同条件で綺麗なコードを示してくださるとありがたいです
CでもC++でもRustでも構いません
48デフォルトの名無しさん
垢版 |
2021/12/16(木) 22:36:01.50ID:22XvzF/H
そもそも
「ループを使わずに足し算と比較のみで素数をその型の上限まで返すイテレータ関数」
というのはどこからでてきたもんなんだ?
この条件になにか意味があるの?
2021/12/16(木) 23:05:37.82ID:iS9fah9V
>>48
まず素数なら列になるのでイテレータにするのはいいですよね
用いる型によって上限値が異なるから上限まで返すのも自然ですよね
足し算と比較は必要最低限として不可欠だと思います
どうしてもならばループは使ってもいいですよ
だから今回は可能ならばループを直接使わずに高階関数イテレータ使用でという話だけです
つまりそんな難しい話をしているわけではないと思います
他の言語のコードが出てこないのは難しいからなのでしょうか?
2021/12/16(木) 23:20:42.17ID:22XvzF/H
Rustのことは知らんのだけどsome, any, map, findって実質ループじゃないの?
Rubyっぽい構文も見られるけどブロックを毎度呼び出してもらってるだけだからループじゃないとかいうわけ?
2021/12/16(木) 23:59:30.49ID:iS9fah9V
>>50
登場していたSomeは値付きenumなのでデータの型です
mapは変換するだけなのでそれ自体にループ要素はないです
一方でfindなどはループを内包している高階関数になりますね
だから>>49にて「今回は可能ならばループを直接使わずに高階関数イテレータ使用」と書いたのです

宿題となっていた類似部分を別関数へ切り出しが出来ました
これでわかりやすくなったでしょうか?

fn prime<T>() -> Unfold<T, impl FnMut(&mut T) -> Option<T>>
 where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
 unfold(T::one(), |a| {
  inc(*a, T::one(), |x| x > T::zero()) // 無条件に+1していき次の素数を探す
  .inspect(|b| *a = *b) // unfoldのため値更新
  .find(|b| inc(T::one(), T::one(), |x| x < *b) // 自分より小さい数で+1していき約数を見つける
   .all(|c| inc(T::zero(), c, |x| x <= *b) // その約数の候補を自分以下で足し算していく
     .all(|d| d != *b)))}) // 自分が倍数になっていなければOK
}

fn inc<T>(s: T, a: T, f: impl Fn(T) -> bool) -> Unfold<T, impl FnMut(&mut T) -> Option<T>>
 where T: Copy + num::Zero + num::One + num::CheckedAdd + std::cmp::PartialOrd,
{
 unfold(s, move |x| { *x = x.checked_add(&a)?; f(*x).then(|| *x) })
}
2021/12/17(金) 00:00:59.02ID:vT0QTAiv
>>49
人に読ませるためのコードを書いたことがないのかな?
アルゴリズム的にどうとかRustの書き方的にどうとか言う以前の問題
2021/12/17(金) 00:18:54.26ID:IfdsKAW/
>>51
めっちゃ理解しやすくなったな
まるで宣言型論理プログラミングっぽい雰囲気だ
説明の日本語はこう書くとよい

//素数とは自分未満で次を満たす約数を見つけること
.find(|b| inc(T::one(), T::one(), |x| x < *b)
 // 条件は約数の倍数すべて(自分以下)が
 .all(|c| inc(T::zero(), c, |x| x <= *b)
  // 自分と一致しないこと
  .all(|d| d != *b)))})
2021/12/17(金) 00:54:27.00ID:BYm5EDTZ
恥ずかしい自演
2021/12/17(金) 01:40:56.99ID:IfdsKAW/
ん?
あと変数名をわかりやすく変えたほうがいいぞ
2021/12/17(金) 02:46:20.43ID:/GCsHBLw
本スレでクソコード連投してた奴だな
素数列挙をジェネリックにしてうれしがるセンスが厨二病っぽい
2021/12/17(金) 05:16:05.83ID:Ph9FgRES
計算量悪くね?
58デフォルトの名無しさん
垢版 |
2021/12/17(金) 07:30:23.20ID:1kSORKuu
>>17
DEC PDP-11で動かすUNIXを書くためにC言語が生まれたと思ったが?
C言語の方が後なら、最初のUNIXは何の言語で書いてあったの?
2021/12/17(金) 07:58:24.35ID:iDAFjWCW
アセンブリ言語
2021/12/17(金) 08:05:48.36ID:Fp+PkeDU
>>58
Wikipediaにすら「当初はアセンブリ言語のみで開発されたが、1973年にほぼ全体をC言語で書き直した。」と書かれているんだけど。
■ このスレッドは過去ログ倉庫に格納されています