On 3/12/14 2:59 PM, Daniel Micay wrote:
Traits aren't really any simpler than this. Templates don't produce nice
errors and require the type checker to redo work on each instantiation,
but I don't think the implementation/specification is more complex.
Templates are more complex because of what happens on substitution
failure (enabling all of the `static_assert` tricks), as well as
(partial) template specialization. Furthermore, traits are limited to
affecting what methods are called (notwithstanding a couple of our
"kinds"), while templates have a much less constrained notion of what
things substitutions affect. The latter is what allows all of the
template metaprogramming tricks that are simply impossible in Rust (for
a reason).
preprocessor
Macros are more complex than a text-based preprocessor. I understand how
`cpp` works but the macro implementation (hygiene algorithm, etc.) is
something I would need to read about quite a bit.
I guess it's more complexity, but I'm not about to apologize for not
using cpp. They lead to far less complexity in code. #include and
#define (for include guards) are not necessary in Rust the same way they
are in C++.
implicit numeric coercions
We do have generic literals...
Not generic literals in the sense that is usually meant: it only means
that integer and float literals can be assigned to any type. What Rust
has is much simpler than arbitrary automatic promotions and demotions of
non-literal values.
implicit pointer coercions
We have these. & and &mut coerce to * and *mut, sometimes. There's
sometimes automatic coercion to slices too.
What I meant was rules around cv-qualification. I guess &mut coerces to
&, but that's quite necessary.
Anyway, some of the unsafe pointer stuff may be going away.
overloadable coercions
Auto-dereference/auto-reference can do pretty surprising things and I
don't really understand the algorithm involved. Overloadable coercions
are explicitly specified and the rules are pretty simple.
The algorithm in Rust is really simple: you dereference all the way
down, then try one reference (immutable or mutable), then stop. Go has
essentially the same algorithm and people like its simplicity.
Without something like autoderef/autoref, methods become so inconvenient
to use as to be a non-starter. Note that C++ has autoref on the `this`
pointer, because, well, you have to have it.
argument-dependent lookup
This is quite similar to looking up a method based on the in-scope traits.
Not at all! Argument-dependent lookup searches namespaces that were not
imported at the call site.
Take the example from Wikipedia. Rust has nothing like this for
unqualified function calls:
namespace NS {
class A {};
void f( A *&, int ) {}
}
int main() {
NS::A *a;
f( a, 0 ); //calls NS::f
}
non-type template parameters
This is a proposed feature for Rust, and it seems likely that we'll get
associated constants. Integer type parameters are pretty much just sugar
for that.
In Rust's implementation, they might be. Not in C++, where they're a
thing separate from associated constants (which C++ *also* has).
volatile
Rust has this via intrinsics.
It isn't a qualification on pointers in the type system. Simpler.
constexpr
We do have syntax extensions, and CTFE is an often proposed feature. I
don't know how likely it is that we'll get it.
CTFE in Rust would not have the ad-hoc set of rules specifying what you
can and can't do like C++ does. It would just be a conservative
extension of the macro system.
runtime type information
We have std::reflect, a type_id intrinsic and the venerable TyDesc.
True. I want to get rid of most if not all of those.
capture clauses
We need something like this for unboxed closures unless we change the
current semantics from an implicit non-first-class by-ref capture.
No, it would just work the same way proc works.
`->` syntax
Auto-dereference is more complex.
Not if you consider that autoderef is a replacement for both `->` *and*
the implicit coercions in C++. Two birds with one stone, with no extra
syntax.
multiple inheritance
We do have multiple trait inheritance... and AFAIK supertraits are
intended to work with trait objects.
Multiple inheritance is implemented with a subtle
pointers-to-multiple-vtables scheme in C++ that many projects avoid
because of its complexity. It necessitates virtual inheritance as a
separate thing from normal inheritance. Trait objects are much simpler
to implement, because we just pack the vtable next to the object.
Supertrait makes this scheme no more complex.
pointer-to-member-functions
We'll have this too AFAIK. How will first-class methods mix with single
inheritance?
No, we won't have it. Under UFCS, first-class methods would just work
the same way: they don't bind the this pointer.
the subtle rules around "const", the `mutable` keyword
Rust's support for mutability is better, but it's better in part because
it's a more sophisticated system. `const` is dead simple when compared
to inherited-mutability-but-sometimes-not-really (& &mut, non-Freeze
types like Cell/RefCell, etc.).
Isn't `mutable` pretty much the definition of
"const-but-sometimes-not-really"? At least the only place it arises in
Rust is in the compiler-checked automatic kind derivation (going away
per Niko's proposal), and in `& &mut` which is a corner case that arises
because we want the rules to be sound.
the implicit `this` pointer and the `enable_shared_from_this` that you
need, `const` member functions
We have the complexity of `self` being special and allowing certain
pointer sigil qualifications.
self isn't going to be special with UFCS, except syntactically.
Without single inheritance, how do you solve the problems outlined in
this thread?
I don't think Rust needs to support every kind of object system
efficiently at a language level. I would only want it to pick a good one
and support that (like trait objects) rather than trying to make the
compiler directly support any foreign object system efficiently.
In my opinion, supporting another object system would be good for Servo
(or another browser engine) and bad for the language elsewhere... I can
see why having an efficient DOM is important, but it doesn't make me not
hate this feature.
If we had a good way to encode it, then we wouldn't need the feature. I
agree that it should not be commonly used in most Rust code. (Maybe we
should permanently feature-gate it.)
I don't think making COM/gobject incredibly efficient is a valid use
case because both are terrible legacy technologies and both are already
slow.
COM in particular is not going anywhere. We will need it for Windows
support. Microsoft is very committed to it for Direct3D, for example,
and Direct3D is extremely important for many of the use cases that Rust
wants to target (i.e. games).
Patrick
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev