C++でmap, filterを使うために方言に馴染もう
C++20からついにmap, filterが導入されます。
for (int i : ints | std::views::filter(even) | std::views::transform(square)) {
std::cout << i << ' ';
}
しかし、C++は昔にmapという用語を辞書型に割り振ってしまったために命名がいびつになってしまっているように感じます。
ここではC++の方言をまとめて利用の抵抗感を低減することを目標として記事を書きました。
概要
一般については私の感覚なので個人差があります。
一般 | C++ | 備考 |
---|---|---|
map | transform | |
flat_map / flatten | join | |
filter_map | transform_maybe | HaskellはmapMaybe |
slide(2) | adjacent | |
fold | accumulate | foldに名前変更される予定 |
range | iota |
filterとC++11時点で対応していたと思われるものはcopy_ifですが引き継がれなかったので気にしなくても良いです。
map
C++ではmapの代わりにtransformという用語を割り当てています。
ただ、私の経験上transformを使っている人をほとんど見たことがありません。
C++11からstd::transformというアルゴリズムが提供されています。
mapを使わないということがプログラミングにおいてあり得ないので命名が悪いと言わざるを得ません。
しかし、今更はるか昔の命名の悪さに文句を言っても始まらないのでC++はmapの代わりにtransformという方言を使うということを広く認識してもらうことが大事なのかなと思っています。
slide
tupleを返すかiterableな物を返すかで名前がまた違う言語もある。好きな方で受け取れる言語もある。
C++はtupleとiterableは受け取り方を明示する必要のある言語なのでtuple版はslide_as_tupleになるかもしれない。
adjacentはslide(2)のtuple版
言語 | 関数名 |
---|---|
Python | pairwise |
Kotlin | windowed, zipWithNext |
Scala | sliding |
D | slide |
Haskell | divvy |
Clojure | partition |
Rust | std::slice::Windows |
fold / reduce
C++17でreduceが追加され、C++23にてaccumulateがfoldに改名されるとC++にはfoldとreduceの両方が存在することになります。
reduceはfoldの並列実行版として区別すれば良さそうです。
関数名 | 言語 |
---|---|
fold | Rust, Haskell |
reduce | Kotlin, Python, Java, Swift |
初期値の有無で使い分け | Scala |
range
iotaも方言がきつくて使われていない関数の1つ。
C++ではrangeの代わりにiotaを使います。
言語 | 関数名 |
---|---|
Python | range |
Java | range |
多数の言語 | a..b |
参考
Discussion