There’s syntactic difference between the two. “&mut self” is a mutable REFERENCE to self, essentially just a pointer, a few bytes to be put on the stack. However “mut self” would copy the entire struct and would probably require a new heap allocation (it would be a lot slower)
@@carmelid well explained and in general you're right. It's probably a better idea to go for the &mut self approach. However, it's worth noting that moves won't cause heap allocation, and for a simple case like this, they're likely to be eliminated completely in release mode when all the setters are inlined by the compiler.
very true, in the simple example the compiler will probably even optimize the stack-copy away as you are saying. That is why I added the carefully placed “probably” in there :)
@@felixst-gelais6722 sure, at least when talking about “mut self”, but is that always true for other struts, “mut Template” in this case? Won’t that cause a copy(given a sufficiently complex struct of course)? 🤔
Love this kind of videos! Short, direct to the point, very easy to understand and with lots of applications in a real world. Thanks so much for sharing!
Nice video Chris. I think one of the complaints people usually have about builders is all the extra boilerplate. It's really good if building a library and want to expose a safe and ergonomic API though. IIRC, there are a few crates out there that help cut back on the boilerplate for builders, lowering the cost somewhat. Maybe a good follow up if any of them look good -- I haven't tried any of them out yet.
setters would be an individual function per field with no intermediate type, and are a fairly uncommon "design pattern" in Rust in general. In Rust people tend to allow access to the fields themselves, or disallow access. the builder api is the whole thing; An intermediary struct that is typed to allow for more optional fields and a series of functions to help you build up that struct, then a finalizer to return the type you wanted to construct in the first place.
@@tsalVlog In terms of functional code, the builder pattern ONLY exists 'because' you want to construct a read-only object. C code from the 1980s had that functionality BTW. When you execute your functional program it will STILL BE JSP at the CPU level. High level languages are for the programmer, not the CPU. There are hundreds of them. Some come into fashion, some go out. Some come in different guises, some get reborn. As Shirley said "It's all just a little but of history repeating." Hopefully we get better each time. ;)
At the end of the day, the ALL end up as ASM. In the case of most highlevel OOP and Functional languages that involves optimising out 95% of the code during compilation.
Well actually... ever heard of a string builder? XD But yea, builder patterns are meant for u to write more code to better express what you want to happen. If you dont care about developper ergonomics at all, you might as well go write some assembly
is that really necessary to have "&mut self" in arguments and "&mut Template" as output? Couldn't it simply be "mut self" and "mut Template"?
There’s syntactic difference between the two. “&mut self” is a mutable REFERENCE to self, essentially just a pointer, a few bytes to be put on the stack.
However “mut self” would copy the entire struct and would probably require a new heap allocation (it would be a lot slower)
@@carmelid well explained and in general you're right. It's probably a better idea to go for the &mut self approach. However, it's worth noting that moves won't cause heap allocation, and for a simple case like this, they're likely to be eliminated completely in release mode when all the setters are inlined by the compiler.
very true, in the simple example the compiler will probably even optimize the stack-copy away as you are saying.
That is why I added the carefully placed “probably” in there :)
@@carmelid in rust when its not referenced, its owned. So it doesn't have to copy any memory, it can just update the memory thats already there
@@felixst-gelais6722 sure, at least when talking about “mut self”, but is that always true for other struts, “mut Template” in this case? Won’t that cause a copy(given a sufficiently complex struct of course)? 🤔
Love this kind of videos! Short, direct to the point, very easy to understand and with lots of applications in a real world. Thanks so much for sharing!
Just wanted to add that adding documentation too a builder pattern is great.
I see that your read comments carefully ;)
Thank you so much for that video!
Nice video Chris. I think one of the complaints people usually have about builders is all the extra boilerplate. It's really good if building a library and want to expose a safe and ergonomic API though. IIRC, there are a few crates out there that help cut back on the boilerplate for builders, lowering the cost somewhat. Maybe a good follow up if any of them look good -- I haven't tried any of them out yet.
Your videos are amazing. Keep on going. More stuff like this plz... i learn a lot from it and you explain it so perfect... thx 4 that
dude this as awesome!! i hope you keep making these videos like this!
Is there a more functional way to use this pattern?
How do you show and hide inlay hints so quickly?😮
I have it set to toggle on or off using control-i using an extension.
Can you make a video about how to implement wgpu renderer?
There's a whole series on working with wgpu here: ua-cam.com/play/PLWtPciJ1UMuBs_3G-jFrMJnM5ZMKgl37H.html
Fundamentally, what's the difference between using setters or a builder?
setters would be an individual function per field with no intermediate type, and are a fairly uncommon "design pattern" in Rust in general. In Rust people tend to allow access to the fields themselves, or disallow access.
the builder api is the whole thing; An intermediary struct that is typed to allow for more optional fields and a series of functions to help you build up that struct, then a finalizer to return the type you wanted to construct in the first place.
Nice thumbnail :)
I have no idea what I'm looking at in the thumbnail, but it is beautiful :)
At some point people will call "concatenate" a builder pattern. Usually the builder pattern creates more code than it removes.
there is value in functional code, even if you refuse to use it yourself.
@@tsalVlog In terms of functional code, the builder pattern ONLY exists 'because' you want to construct a read-only object.
C code from the 1980s had that functionality BTW.
When you execute your functional program it will STILL BE JSP at the CPU level.
High level languages are for the programmer, not the CPU.
There are hundreds of them. Some come into fashion, some go out. Some come in different guises, some get reborn.
As Shirley said "It's all just a little but of history repeating."
Hopefully we get better each time. ;)
At the end of the day, the ALL end up as ASM. In the case of most highlevel OOP and Functional languages that involves optimising out 95% of the code during compilation.
You are programming a language, not a CPU.
BTW my day job is a Java engineer working with the Apache Hadoop/Spark framework. and Scala, so... don't...
Well actually... ever heard of a string builder? XD
But yea, builder patterns are meant for u to write more code to better express what you want to happen. If you dont care about developper ergonomics at all, you might as well go write some assembly