Had to add a comment. Rainer, that was a brilliantly conceived and delivered talk. One of the clearest on Rust I have heard so far. Keep up the good work!
Mr Stropek you are one of the best exposer i“ve ever heard on the topic. This talk was invaluable for me! Thanks a lot. Rust, give this man more talks please. And ty you too.
Great talk, I just have a meme 32:23 Rainer: You can use disjoint closures in real-world examples. Also Rainer: *Literally uses disjoint closures in a fairy tale example*
Wow, I never thought about FnOnce like case in closure context before. I guess Rust force you to think about all these details and subtle differences. Thanks for the awesome presentation.
The way you have explained, is quite useful. Coming from the Scala world, I am trying to map my understanding between two languages (and their philosophies). This presentation supplements that very well. Thank you.
Great talk. Lambdas are one of the few things where I prefer the C++ version. In C++ it's clearer what's being captured and what kind of capture it's using for each variable.
A small correction at 4:46 you said the line "let f: fn add(i32, i32) -> i32 = add;" declares "f" as a function pointer. "f" is actually a function item which is a zero sized type that statically represents a specific function. If you made it mutable and later assigned it to "fn sub(i32, i32) -> i32" this would fail to compile
Great talk about rust closures. I have a question irrevalent to Rust. How did you annotate certain area of code in vscode during desktop recording? Is it a featue of your live broadcast software?
Thank you very much for this clear explanations. Though I am not very strong in Rust (kind of post-beginner), I was able to follow it. I just have to make me a refresher on concepts like dyn keyword with Traits. But for sure, I can find many videos/blogs explaining this concept. Very good video.
I'm confused by the use of the term closure for all the examples around the 7 minute mark. They seem to be just lambdas or anonymous functions, and they don't close over any values from the environment. They don't use arguments from the surrounding scope, so why are they closures?
Wow, needing to box the closure which allocates on the heap when you reference an external variable seems heavy! C++ lambda capture by reference seems much more lightweight in comparison
Yeh, that seems odd. I would have thought you could just pass it as 'dyn Fn" without the box. I can't imagine anyone would want to pay that cost for invocation of the kind of trivial to semi-trivial code often done in lambas/closures. I would also take exception to his claim that Rust is very explicit. There's a huge amount of magical syntactical sugar in Rust.
@@trolledwoods377 ok, that's good. But these need to be properly taught. This video is not doing that. It's confusing experienced in programming, but new to Rust.
@@jhbonarius I suppose the reason Box is used here instead of bare references is that Box takes ownership of the values it wraps, while references do not, so with references, lifetime annotations would sometimes be necessary and would make the code more difficult to understand.
I was also surprised to see this, so I tested it. It is possible to pass by reference. ``` fn main() { fn add(x: i64, y: i64) -> i64 { x + y } fn calc_and_print(x: i64, y: i64, calcfn: &dyn Fn(i64, i64) -> i64) { let result = calcfn(x, y); println!("{}", result); } calc_and_print(1, 2, &add); calc_and_print(1, 2, &|x, y| x + y); let z = 5; calc_and_print(1, 2, &|x, y| x + y + z); } ```
"You can remove the parentheses and make it even nicer" ...i wish everybody thought like that I had a discussion with my tech lead (C#) and proposed thing like that. He hated it. He still seems to have problems with moving from VB to C#, and would even prefer to use "end function" and such over parentheses...
Great Explanation, however I'd like to leave a comment: at ruclips.net/video/bgZa9VRBhYU/видео.html you do not actually need to do boxing, accept `&dyn Fn(i32, i32) -> i32` instead. In such a case, explicit lifetimes can also be dropped.
Had to add a comment. Rainer, that was a brilliantly conceived and delivered talk. One of the clearest on Rust I have heard so far. Keep up the good work!
Mr Stropek you are one of the best exposer i“ve ever heard on the topic. This talk was invaluable for me! Thanks a lot.
Rust, give this man more talks please. And ty you too.
that was just perfect recap, glad you introduced the 2021 features too !
Yes, this is essentially how the syntax is done in Ruby! A language famous for being extremely difficult yet still deterministic to parse.
Great talk, I just have a meme 32:23
Rainer: You can use disjoint closures in real-world examples.
Also Rainer: *Literally uses disjoint closures in a fairy tale example*
Wow, I never thought about FnOnce like case in closure context before. I guess Rust force you to think about all these details and subtle differences. Thanks for the awesome presentation.
the presentation skill is impressive. thank you, sir!
The way you have explained, is quite useful. Coming from the Scala world, I am trying to map my understanding between two languages (and their philosophies). This presentation supplements that very well. Thank you.
Great talk. Lambdas are one of the few things where I prefer the C++ version. In C++ it's clearer what's being captured and what kind of capture it's using for each variable.
A small correction at 4:46 you said the line "let f: fn add(i32, i32) -> i32 = add;" declares "f" as a function pointer. "f" is actually a function item which is a zero sized type that statically represents a specific function. If you made it mutable and later assigned it to "fn sub(i32, i32) -> i32" this would fail to compile
Yeah I knew there was something off about "function pointer", thanks
This was very well done. I really appreciate this talk; I definitely learned something.
Great, your explanation is so clear.... thanks.
Great talk about rust closures. I have a question irrevalent to Rust. How did you annotate certain area of code in vscode during desktop recording? Is it a featue of your live broadcast software?
Thank you very much for this clear explanations. Though I am not very strong in Rust (kind of post-beginner), I was able to follow it. I just have to make me a refresher on concepts like dyn keyword with Traits. But for sure, I can find many videos/blogs explaining this concept.
Very good video.
It's that C# guy!!!
I'm confused by the use of the term closure for all the examples around the 7 minute mark. They seem to be just lambdas or anonymous functions, and they don't close over any values from the environment. They don't use arguments from the surrounding scope, so why are they closures?
Greats concise explanations.
great talk, thank you
Wow, needing to box the closure which allocates on the heap when you reference an external variable seems heavy! C++ lambda capture by reference seems much more lightweight in comparison
Yeh, that seems odd. I would have thought you could just pass it as 'dyn Fn" without the box. I can't imagine anyone would want to pay that cost for invocation of the kind of trivial to semi-trivial code often done in lambas/closures.
I would also take exception to his claim that Rust is very explicit. There's a huge amount of magical syntactical sugar in Rust.
You don't need to, you can use &dyn Fn, &mut dyn FnMut, make the closure a generic of the fy ction instead etc... There are lots of options
@@trolledwoods377 ok, that's good. But these need to be properly taught. This video is not doing that. It's confusing experienced in programming, but new to Rust.
@@jhbonarius I suppose the reason Box is used here instead of bare references is that Box takes ownership of the values it wraps, while references do not, so with references, lifetime annotations would sometimes be necessary and would make the code more difficult to understand.
I was also surprised to see this, so I tested it. It is possible to pass by reference.
```
fn main() {
fn add(x: i64, y: i64) -> i64 {
x + y
}
fn calc_and_print(x: i64, y: i64, calcfn: &dyn Fn(i64, i64) -> i64) {
let result = calcfn(x, y);
println!("{}", result);
}
calc_and_print(1, 2, &add);
calc_and_print(1, 2, &|x, y| x + y);
let z = 5;
calc_and_print(1, 2, &|x, y| x + y + z);
}
```
"You can remove the parentheses and make it even nicer"
...i wish everybody thought like that
I had a discussion with my tech lead (C#) and proposed thing like that. He hated it. He still seems to have problems with moving from VB to C#, and would even prefer to use "end function" and such over parentheses...
Thanks
font size too small :(
Great Explanation, however I'd like to leave a comment: at ruclips.net/video/bgZa9VRBhYU/видео.html you do not actually need to do boxing, accept `&dyn Fn(i32, i32) -> i32` instead. In such a case, explicit lifetimes can also be dropped.