A D vs. Rust example
Don Allen
donaldcallen at gmail.com
Fri Oct 21 03:36:39 UTC 2022
On Thursday, 20 October 2022 at 22:41:34 UTC, rassoc wrote:
> On 20/10/2022 15:37, Don Allen via Digitalmars-d wrote:
>> Rust has closures. Great. So here's an example of an attempt
>> to do something along the lines described above with a single
>> mutable variable:
>>
>> ````
>> fn main() {
>> let mut foo = 5;
>> let mut bar = || {
>> foo = 17;
>> };
>> let mut baz = || {
>> foo = 42;
>> };
>> bar();
>> println!("{}", &mut foo);
>> baz();
>> println!("{}", &mut foo);
>>
>> }
>> ````
>
> To be honest, these kind of access patterns are smelly and
> there almost always exists a more elegant alternative.
"smelly" and "elegant" are in the nose and eye of the beholder.
As I said in my original post, this kind of code is very common
in Scheme.
>
> Regarding that example code above, the burrow checker will be
> happy if you reorder it slightly:
>
> ```rust
> fn main() {
> let mut foo = 5;
> let mut bar = || {
> foo = 17;
> };
> bar();
> println!("{}", &mut foo);
> // just moved this down here
> let mut baz = || {
> foo = 42;
> };
> baz();
> println!("{}", &mut foo);
> }
> ```
Except the re-ordering you suggest is not possible in the actual
code from which this example was derived. In the real code, the
mutable variables are sqlite statements where multiple closures
refer to several of them and the closures are called in multiple
places.
You are taking advantage of this simple derived case, where each
closure is called in only one place, and also the fact that
mutable references are dropped after their last use, to arrange
for only one mutable reference to foo active at any time, which
is what the borrow checker wants.
In the real code, because the closures refer to multiple mutable
variables and there are multiple call sites to each closure, it
isn't possible to segregate the closures and their call sites to
satisfy the borrow checker, but use of interior mutability does
work.
More information about the Digitalmars-d
mailing list