It's one of the few places that C++ is more explicit than Rust. I wonder if there's a reason Rust went a different way? I'm mainly a C++ programmer so I'm genuinely curious.
It's one of the few places that C++ is more explicit than Rust. I wonder if there's a reason Rust went a different way? I'm mainly a C++ programmer so I'm genuinely curious.
Yes there is a difference at the call site between taking a reference to an owned thing and taking potential ownership of the thing.
However inside the function block it is noise. Nothing inside the code is semantically different between the two forms, both do work on preexisting data.
Certainly the second version could have a change where it does something with respect to the fact it is a smart pointers, changing what used to be a grabbed pointer to a weak pointer to be more explicit about lifetimes for instance.
However that code change would be just as explicit as long as there aren't any methods on the smart pointer in the auto deref world.
There are lots of things wrong with C and C++ that Zig and Rust fixes, but I never thought of this one being problematic in any way. It's as easy to type, the difference is obvious, and it's easy to see from a glance what's going on.
To the extent that this is a problem, it's a problem with references as a language feature in general, not with the arrow syntax.
That's true but I think the bigger motivation is avoiding ambiguity than seeing when an indirection is happening. (You also can't see whether a method is virtual, i.e. indirecting via the vtable, from the call site.) In C++ references don't have any standalone methods or operators so there's no ambiguity from using methods via a reference just using a dot.
Incidentally, the authors of Go were asked why they didn’t use a postfix dereference when Sethi noted[1] back in 1981 that C syntax would have been simpler that way, was quoted in Ritchie’s 1993 retrospective[2] on that point, and even their own blog post on declaration syntax pointed out that possibility[3], but IIRC the answer amounted to “but then we wouldn’t have gotten those sweet, sweet C-bandwagon popularity points”.
(I also cannot help calling out “Language X” here: One nice approach that nevertheless basically forces implicit dereferencing is that of Algon-68, where all values are constant values; the way to declare a mutable variable is to declare a pointer—a constant value—to a mutable cell; and the way to make the whole thing bearable is to have the compiler infer the minimum possible amount of dereferencing in an expression from the types of the values involved. Then of course it becomes impossible to infer the types, so the ML family goes with the inconvenient dereferencing, and you end up not really using a lot of mutability in ML.)
[1] https://dx.doi.org/10.1002/spe.4380110606
Rust and Go have the pointer have the unified syntax, but I thought in zig it does differentiate between the pointer itself and the value it points to.
Rust and Go:
ptr.method_on_ptr() ptr.method_from_underlying_val()
Zig:
ptr.method_on_ptr() ptr.*.method_from_underlying_val()