Gokcehan-
My understanding is that C++, due to its policy of SFINAE [1], usually
provides error feedback after the template has been fully instantiated
and the fully instantiated version fails to compile. This can lead to
hard to debug compile-time failures.
Good compilers can help with dissecting the output you get in this case,
but it is still a real pain to decode in my experience, especially when
you have nests of template code written in terms of other template
code. Since the template parameters do not have bounds, it is not
possible for a compiler to provide any error feedback given a template
definition alone (with no client code), and its difficult for the
compiler to provide good error feedback that is described solely in
terms of the definition: you are doomed to thinking about the
intermingling of the definition with the particular instantiation.
Requiring explicit bounds means that the compiler can provide good error
messages at the point where the parameterized class is *defined* (even
in the absence of client code!) rather than delaying to the point where
the parmeterized class is fully instantiated. This provides me with
more confidence that the parametric code I write is actually going to
compose properly with other implementations of the trait-bounds in terms
of which I have written my code.
That advantage alone is enough to justify this choice for *me*. There
may be other justifications that I am overlooking.
(It may also be the case that I'm ignorant of what the best C++ tools
today do, though I'm pretty sure that these drawbacks are consequences
of core C++ design.)
Cheers,
-Felix
[1] SFINAE:
http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
On 17/09/2013 13:34, Gokcehan Kara wrote:
Hello,
I have met rust a few days ago and let me pay my respects first for
making such a powerful language. I really hope to succeed making some
contribution in the upcoming days.
I was reading the tutorial
(http://static.rust-lang.org/doc/tutorial.html) specifically the
section 16.3 and I was wondering if there's a rationale behind making
generic bounds explicit. For example in C++ I can do:
// clang++ asd.cc -std=c++11 -Weverything -Wno-c++98-compat -g &&
./a.out
#include <iostream>
#include <vector>
using namespace std;
class Klass {
public:
void print() { cout << "printing the thing" << endl; }
};
template <typename T> void print_all(vector<T> &things) {
for (auto thing : things) {
thing.print();
}
}
int main() {
vector<Klass> v1;
v1.push_back(Klass());
v1.push_back(Klass());
v1.push_back(Klass());
print_all(v1); // no errors
vector<int> v2;
v2.push_back(1);
v2.push_back(2);
v2.push_back(3);
print_all(v2); // /tmp/asd.cc:18:10: error: member reference
base type 'int'
// is not a structure or union/tmp/asd.cc:37:3:
note: in
// instantiation of function template specialization
// 'draw_all<int>' requested here
return 0;
}
and it gives me the necessary error at compile time. To my limited
knowledge, this is also statically dispatched so should not cause any
overhead.
I haven't used Haskell much but I know a little bit of Scala. In Scala
you need to be explicit because generics are compiled once to run with
different types. As far as I understand, rust compiles different
copies for each type (monomorphizing?) just like C++ so it might be
possible to be implicit in rust as well.
Having said that, I'm not sure if being explicit is necessarily a bad
thing. It sure looks good for documenting and I haven't thought of any
cases where it falls short except maybe when a function of the same
name is implemented in different traits.
Am I failing to see the obvious?
Thanks in advance,
Gokcehan
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
--
irc: pnkfelix on irc.mozilla.org
email: {fklock, pnkfelix}@mozilla.com
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev