Deref polymorphism is a known anti pattern. https://rust-unofficial.github.io/patterns/anti_patterns/der...
Mistakes with Rust smart pointers: when Deref goes wrong
31–40 of 64 posts
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#32Earlier quoted context omitted.
I've always liked that feature of C and C++. There's a lot of people that really hate it and in new languages they unify it to be just a dot. Zig does this as well, for instance. I always liked that the distinction was very explicit: use a.b() if you're calling b() on the object itself, use a->b() if you're de-referencing a first. There are lots of things wrong with C and C++ that Zig and Rust fixes, but I never thou…
I'm among the people who would have liked to eliminate even this special case and have a convenient postfix derefence for this. So instead of a->b() you'd have a*.b(), and if you need to dereference again, write a**.b() and so on. But as you said, lots of people really seem to hate this kind of thing. Zig is almost there with its dereference syntax, but still kept the magic dereferencing 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
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#33Re: Mistakes with Rust smart pointers: when Deref goes wrong
#34In case the author happens to see this thread – there seems to be a missing less-than sign: str::from_utf8( as Deref>::deref(&self.0)) Thanks for the article! ^_^
You're welcome :) I finally found out what was going wrong here. All angle brackets and other characters were being escaped in other parts of the document, even in blocks. Except when it came to code blocks inside blocks. For context, I use Zola and Cloudflare pages. It turns out there is a bug[^0] in Zola 1.40.0 which reads: > Fix code blocks content not being escaped when not using syntax highlighting I presume tha…
You can change this under Settings > Builds & deployments > Build system version. Cheers!
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#35Earlier quoted context omitted.
Not disagreeing with you but what's interesting is that C++ doesn't hide in this particular situation. Smart pointers implement operator-> and operator* but then ptr.foo() is still always the foo() method of the pointer type (and won't compile if it doesn't have it) - you need ptr->foo() or (*ptr).foo() to get the method of the pointed-to type. It's one of the few places that C++ is more explicit than Rust. I wonder…
One of the downsides of the C++ approach is that it makes it more cumbersome to make changes in your code. If you for instance make a trivial change where you change a variable from a stack-allocated object accessed directly via .foo() into a heap-allocated one accessed via ->foo(), you have to either manually change all .foo()s into ->foo()s or do some sort of weird work-around, such as making a separate variable th…
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#36Earlier quoted context omitted.
Not disagreeing with you but what's interesting is that C++ doesn't hide in this particular situation. Smart pointers implement operator-> and operator* but then ptr.foo() is still always the foo() method of the pointer type (and won't compile if it doesn't have it) - you need ptr->foo() or (*ptr).foo() to get the method of the pointed-to type. It's one of the few places that C++ is more explicit than Rust. I wonder…
I've always liked that feature of C and C++. There's a lot of people that really hate it and in new languages they unify it to be just a dot. Zig does this as well, for instance. I always liked that the distinction was very explicit: use a.b() if you're calling b() on the object itself, use a->b() if you're de-referencing a first. There are lots of things wrong with C and C++ that Zig and Rust fixes, but I never thou…
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()
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#37Earlier quoted context omitted.
I've always liked that feature of C and C++. There's a lot of people that really hate it and in new languages they unify it to be just a dot. Zig does this as well, for instance. I always liked that the distinction was very explicit: use a.b() if you're calling b() on the object itself, use a->b() if you're de-referencing a first. There are lots of things wrong with C and C++ that Zig and Rust fixes, but I never thou…
I'm mostly indifferent to it because it doesn't really harm readability, and it's not hard to know when to use it, but I can seem why it might be more strongly disliked. You can't entirely rely on it to know a dereference is happening because references (e.g. `int&`) aren't subject to the `->` requirement. It's also annoying if you find that you can refactor `func(T*)` to `func(T&)` and now you have to replace all `-…
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.
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#38Earlier quoted context omitted.
One of the downsides of the C++ approach is that it makes it more cumbersome to make changes in your code. If you for instance make a trivial change where you change a variable from a stack-allocated object accessed directly via .foo() into a heap-allocated one accessed via ->foo(), you have to either manually change all .foo()s into ->foo()s or do some sort of weird work-around, such as making a separate variable th…
those changes in access are semantically different, so i prefer being forced to change code when semantics change
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.
Re: Mistakes with Rust smart pointers: when Deref goes wrong
#39Earlier quoted context omitted.
You're welcome :) I finally found out what was going wrong here. All angle brackets and other characters were being escaped in other parts of the document, even in blocks. Except when it came to code blocks inside blocks. For context, I use Zola and Cloudflare pages. It turns out there is a bug[^0] in Zola 1.40.0 which reads: > Fix code blocks content not being escaped when not using syntax highlighting I presume tha…
I'm using Zola and Cloudflare Pages, and it is currently possibly to use ZOLA_VERSION=0.17.1. I thought I had opted into the Pages v2 beta (I remember joining a Discord for this purpose a while ago), but on the actual page the setting is at v1. You can change this under Settings > Builds & deployments > Build system version. Cheers!
Apparently you can now ZOLA_VERSION to _any_ version you desire in v1 and the build system will install it on demand. I didn't realize that part had changed.
On the other hand, v2 doesn't even have Zola; my builds failed with a "failed to find zola command".
I guess we're now set for life, and will never have to wait for Cloudflare to update the image in order to bump the version. Less headaches for everyone.
Source: https://developers.cloudflare.com/pages/platform/language-su...