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

Reply via email to