3 ms·
C++ should copy D's elegance: import std.stdio; string[9] vec = [ "the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"
by WalterBright 3mo ago
C++ should copy D's elegance:
import std.stdio;
string[9] vec = [
"the", "quick", "brown", "fox",
"jumped", "over", "the", "lazy", "dog"
];
void main()
{
foreach (i, s; vec)
writeln(i, ": ", s);
}
- WalterBright 3mo agoAlthough D is a strongly typed language, it is very good at type inference. The `s` is inferred as `string`, and `i` as `size_t`.
- deleted 3mo ago[deleted]
- entrope 3mo agoGo is similar: package main import "fmt" var vec = []string{"the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"} func main() { for i, s := range vec { fmt.Printf("%d: %s\n", i, s) } } Using `fmt.Println(i, ":", s)` inserts spaces on both sides of the colon, so the output is not quite right. I find Go's `range` syntax easier to read than D's `(i, s; vec)` -- although generator functions that work with `range` have unaesthetic return types.
- WalterBright 3mo agoD has several usages for `foreach` depending on the number and type of its arguments. In this case, it sees that `vec` is an array, and so constructs a loop over the array. If `vec` was a range, the loop will be constructed as a loop over the array. It's nice because it makes the syntax for arrays and ranges interchangeable, making for easy refactoring.
- entrope 3mo agoGo is similar: `for/range` has always worked on arrays, slices, maps, strings and channels, and they extended it to integers in version 1.22 and to user-defined generators in version 1.23. It generates one or two outputs depending on the type of the RHS, but one can assign the index value to _ to ignore it. Among standard types, only channels and integers generate one output; containers (including strings) give an index or key and a value.
- xigoi 3mo agoI find Go’s version worse in that it does not allow you to elide the index (which is not needed most of the time). You have to write `for _, s := range vec`, as `for s := range vec` makes s the index.
- WalterBright 3mo agoTo clarify, foreach (s; vec) works if you don't need the index. To be able to modify s in place: foreach (ref s; vec) s = "replacement";
- xigoi 3mo agoI was talking about Go. I know you don’t need the index in D.
- hdjrudni 3mo agoI don't like that semi-colon. AFAICT `i, s;` is not an independent statement. `i, s: vec` would have been fine, but `;` ?!?! madness.
- acehreli 3mo agoWell, others might have said `i, s:` is not an independent label.
- pjmlp 3mo agoC++23 example, import std; using namespace std; int main() { vector vec = { "the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog" }; for (auto&& [i, it] : vec | std::views::enumerate) println ("{}:{}", ++i, it); } As I keep mentioning, the features being copied, slowly erode D's relevance.
- deleted 3mo ago[deleted]
- WalterBright 3mo agoIf you prefer writing: for (auto&& [i, it] : vec | std::views::enumerate) println ("{}:{}", ++i, it); instead of: foreach (i, s; vec) writeln(i, ": ", s); well, what can I say?
- acehreli 3mo agoWe may first need to go over what "elegant" means I guess. :)
- pjmlp 3mo agoThere is elegant when writing code by hand, and when reviewing code by AI agents.
- pjmlp 3mo agoI prefer to use the option with better market share. I am not counting characters, especially when AI completes typing for me.