October 20, 2022
On Thursday, 20 October 2022 at 15:54:45 UTC, Ali Çehreli wrote:
> On 10/20/22 07:09, jmh530 wrote:
>
> > TIL that this works...I thought it would only work for
> global/static
> > variables.
>
> Similar nested function examples appear at the following point during one of my presentations:
>
>   https://www.youtube.com/watch?v=dRORNQIB2wA&t=2419s
>
> Ali

I suppose I just don't make much use of nested functions. Might consider making more useof them, when needed.
October 20, 2022
On 10/20/22 18:49, H. S. Teoh wrote:
> On Thu, Oct 20, 2022 at 03:25:36PM +0000, Don Allen via Digitalmars-d wrote:
>> Where I do think D would do well by emulating Rust is in the area of helpful
>> compiler warnings: noting unused variables, constants and imported symbols,
>> pointing out unnecessary parentheses, etc.
> [...]
> 
> It would be good to file these as enhancement requests to bugzilla, so
> that they don't get lost in the dusts of forum history.
> 
> 
> T
> 

Such warnings don't carry over well to D though, because template expansion is untyped. Therefore, by default the compiler will check whether the _generated code_ has any of those issues, which is usually just an annoyance. Lots of false positives. I also don't think people should be encouraged to remove unnecessary parentheses, otherwise they will start to also omit necessary ones.
October 20, 2022

On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:

>

[...]

Thanks for the write-up.
I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.

October 20, 2022

On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:

>

On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:

>

[...]

Thanks for the write-up.
I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.

Kool-aid does strange things to the human mind :-)

October 20, 2022

On 10/20/22 4:33 PM, Don Allen wrote:

>

On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:

>

On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:

>

[...]

Thanks for the write-up.
I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.

Kool-aid does strange things to the human mind :-)

I would caution against judgment of Rust based on a newcomer's perspective, though I think it's probably a fair assessment of the ease of learning of Rust.

I will note that you are not using closures in your D code, but nested functions. Is there not a way to do that in Rust?

Many people discount D because their attempts to make it do the things in the way they are used to result in horrible performance, or weird problems.

-Steve

October 20, 2022
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.

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);
}
```
October 21, 2022

On Thursday, 20 October 2022 at 21:28:19 UTC, Steven Schveighoffer wrote:

>

On 10/20/22 4:33 PM, Don Allen wrote:

>

On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:

>

On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:

>

[...]

Thanks for the write-up.
I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.

Kool-aid does strange things to the human mind :-)

I would caution against judgment of Rust based on a newcomer's perspective, though I think it's probably a fair assessment of the ease of learning of Rust.

I've written about 10,000 lines of Rust over several years, revised many times in consultation with a couple of people in the Rust community who were particularly helpful. I've been writing code professionally and otherwise for longer than most of you, since I'm now 80 (first line of code in 1960 -- IBM 1620 assembly language). I understand Rust pretty well at this point, so I don't think the "newcomer" description applies.

The language is more difficult to master than other I've used (a lot). And if you insist on never writing "unsafe", there are things that are simply impossible to do that are routine in more traditional languages.

But, much like Haskell, once you satisfy the compiler, your program will be correct, modulo
logic errors or doing something stupid in an "unsafe" block. You won't ever see a segfault due to de-referencing an uninitialized pointer and things of that ilk.

>

I will note that you are not using closures in your D code, but nested functions. Is there not a way to do that in Rust?

No. Nested functions don't see their enclosing environment in Rust.

>

Many people discount D because their attempts to make it do the things in the way they are used to result in horrible performance, or weird problems.

I did run into that in D, mostly in the area of needing to be aware of preventing the GC from snatching strings I'd passed to C code (sqlite) (you and I shared that adventure last year). This came about in my case because I was porting C code to D, which is mostly very easy, but I missed this gotcha.

>

-Steve

October 21, 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.


October 21, 2022
On 21/10/2022 05:36, Don Allen via Digitalmars-d wrote:
> As I said in my original post, this kind of code is very common in Scheme.
>

Right, I walked that path before, even shiny R7RS, and I'm glad I went to speech therapy for my lisp.

> where multiple closures refer to several of them and the closures are called in multiple places
>

National Spaghetti Day is coming up on January 4th. ;)

In all seriousness, though, I'm not here to invalidate your experiences with Rust. While I've been using D for quite a bit now, I get to experience some pretty uncomfortable cognitive dissonance doing so. I still love it, but D often times offers a slightly less performant and reliable way to tackle a certain set of hard problems. Even if I never get to experience Rust professionally, I'm still quite happy that it set a new baseline for safe languages to come and evolve to.
October 21, 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.

Regarding that example code above, the burrow checker will be happy if you reorder it slightly:

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);
}

You don't need to reorder, just use references

fn main() {
    let mut foo = 5;
    let bar = |val: &mut i32| {
        *val = 17;
    };
    let baz = |val: &mut i32| {
        *val = 42;
    };
    bar(&mut foo);
    println!("{}", &mut foo);
    baz(&mut foo);
    println!("{}", &mut foo);

}