What would baking them into the language add that a library solution couldn't? I'm not keeping track of Rust very closely these days, but it supports arithmetic operator overloading and the Copy trait. What's missing?
I agree that this needs to be standardized for vector-ey crates to be able to talk to each other seamlessly. Otherwise we'll end up with a rerun of the C++ strings fiasco, with char* and wchar_t* and std::string and std::wstring and BSTR and _bstr_t and CString and CComBSTR and QString and GString and...
OOP often involves overhead. If someone defined a really clean vector type/object in a library that let me write expressions the natural way, that could be added to the language I suppose. And that's what I want.
Rust, C and C++ all possess ways (it's the even default/only way in C and Rust, and almost so in C++) to write types like this that don't involve the typical pointer-soup/dynamic-call overhead of typical OOP.
People can and do write vector in libraries right now, usually using existing compiler support that gives them guarantees about SIMD.
What I find odd about your reply, is that you downgrade C++, yet its really the only language that has sufficient operator overloading to do what the poster was requesting (transparent support without OO overhead).
AKA, its completely possible, and there are quite a number of C++ libraries that make vectors look like native types complete with long lists of global operator overloads for interaction with other base types. Generally these libraries are just thin wrappers around inline assembly or intel intrinsics for SSE/AVX and generally don't bring any form of OO syntax into the picture.
That said, even with C++ the libraries tend to fall down a bit when it comes to individual element operation/masking because the closest method is generally using array syntax for the elements which limits the operations to a single element in the vector at a time. Which means you end up with OO method calling syntax for element masking (or creative solutions with operator() )
I didn't denigrate C++, I'm specifically talking about the behaviour of the data types/mention of OOP which is orthogonal to the surface syntax like using symbolic operators instead of textual names. It is factual that the default data declaration in C++ has a little of the "pointer soup" due to methods and `this`. This can often get inlined away and so is usually irrelevant (hence "almost so"), but the poster did emphasise their desire for pass-by-value. This can be avoided by e.g. using friends more than methods, but this isn't the default way a lot of people write C++.
(Also, Rust has pretty transparent support in the same manner also without OO overhead, but differs slightly because methods can and often do use pass-by-value. This is the distinction I was drawing.)
You could also wrap a reference to a plain old struct and operate on it using a class. That's often how I write C++ when I need to be explicit about how the data is structured. Not everything in C++ requires an OO approach.
OP was specifically recommending operator overloading on a plain old struct, which can be done without declaring a class. Indeed, operator overloads can be declared as global functions in C++. The this pointer doesn't enter in to it at all in that case.
I think you're also missing my point. Techniques like what you describe are exactly what I was referring when I said "C++ possess[es] ways" and "using friends rather than methods", although you don't even need a wrapper for a reference (which is actually a pointer, and so also part of what I mean by "pointer soup"!) for this sort of code: just the struct works fine (although a `class` does too, the only difference is the `struct` keyword has different privacy defaults).
The only "downgrade" I made was saying that it is only "almost" the default in C++, versus the other two where they are completely the default.
To be clear, like C and Rust, C++ has great semantic attributes for this sort of thing:
- classes/structs that don't require allocation/pointers
- precise control over pass-by-value (for everything except the `this` pointer of methods)
- pervasive static dispatch of methods/functions (including operators, which can be considered to be method/function with an unusual name and call syntax)
The only downside, and the reason I said "almost" (which is what the C++ETF (C++ Evangelism Task Force) seems to be up in arms about), is methods are what most people reach for by default and so the `this` pointer comes into play. But as you point out, and as I implied in my original comment, this isn't required, just the default.
I agree that this needs to be standardized for vector-ey crates to be able to talk to each other seamlessly. Otherwise we'll end up with a rerun of the C++ strings fiasco, with char* and wchar_t* and std::string and std::wstring and BSTR and _bstr_t and CString and CComBSTR and QString and GString and...