Earlier quoted context omitted.
Named parameters in C# make refactoring far less error-prone too. Consider a method that accepts two int parameters: “DeleteUser(int tenantId, int userId)” - if a call-site was DeleteUser(1,2) and you swapped the parameter arguments you’d be in trouble. Having “DeleteUser(tenantId: 1, userId: 2)” makes code not only safer, but also far more self-documenting.
In theory, those two types shouldn’t be ints, but rather separate int wrapping types TenantId and UserId so that they can’t be mixed up at all
Builder Pattern in Rust
51–60 of 93 posts
Re: Builder Pattern in Rust
#52Earlier quoted context omitted.
This pattern is fairly good but doesn't support required arguments.
I haven't filed an RFC yet, but I have a plan that I'm optimistic can land sometime that would let you write: struct User { id: Id, email: EMail, name: String = String::new(), age: u16 = 0, } let user = User { id, email, .. }; // valid let user = User { id, .. }; // complain about email missing It would leverage `const` expressions, so it would desugar effectively to the same as if you had written: const DEFAULT_USER…
Re: Builder Pattern in Rust
#53Earlier quoted context omitted.
Named parameters in C# make refactoring far less error-prone too. Consider a method that accepts two int parameters: “DeleteUser(int tenantId, int userId)” - if a call-site was DeleteUser(1,2) and you swapped the parameter arguments you’d be in trouble. Having “DeleteUser(tenantId: 1, userId: 2)” makes code not only safer, but also far more self-documenting.
At the risk of being pedantic, I would use separate types there for the id's to avoid this kind of issue, but in general I agree with your point
I've always wondered: what if languages had no guaranteed argument order, but let you skip explicit naming if all parameters were different types? What kind of idioms would that create? Would it mean more newtypes? Would that be cumbersome?
Re: Builder Pattern in Rust
#54Earlier quoted context omitted.
In theory, those two types shouldn’t be ints, but rather separate int wrapping types TenantId and UserId so that they can’t be mixed up at all
Unfortunately hardly any ORMs support that (especially not EF, argh), and writing custom value-types is a painful experience given C# (still) doesn't support strict typedefs nor mixins.
Re: Builder Pattern in Rust
#55> Since we do not have default arguments in Rust, in order to initialize such structure we would have to list all fields: I'm surprised the article doesn't mention Default: https://doc.rust-lang.org/std/default/trait.Default.html It can be combined with the rest pattern to yield something very similar to the solution the author is after. https://stackoverflow.com/questions/19650265/is-there-a-fast...
More details about this and what else is lacking in Rust compared to Kotlin:
https://medium.com/@cedricbeust/what-rust-could-learn-from-k...
Re: Builder Pattern in Rust
#56I appreciate the tradeoffs that led to the builder pattern becoming commonplace, but it's probably my least favorite part of Rust. Compared to optional named parameters it just feels clunky, verbose and kind of Java-esque.
In Rust, you need to come up with a new function for each combination of parameters you want.
Re: Builder Pattern in Rust
#57Currently this is the only thing slightly bothering me when writing Rust code, everything else is an absolute blast and I'm loving every second of it. Hopefully an industry wide best-practice will develop soon on how to deal with the problems outlined in the article. Does anybody know what a Phantom Builder is? The article teases it but doesn't say anything.
Stab in the dark but I would guess that it's using a phantom type parameter to record the state of the builder with regard to its required parameters. This lets you keep the required parameters out of the builder's own constructor, but make the final `build` function only available if the builder is in the right state -- according to the phantom type.
Re: Builder Pattern in Rust
#58> Since we do not have default arguments in Rust, in order to initialize such structure we would have to list all fields: I'm surprised the article doesn't mention Default: https://doc.rust-lang.org/std/default/trait.Default.html It can be combined with the rest pattern to yield something very similar to the solution the author is after. https://stackoverflow.com/questions/19650265/is-there-a-fast...
Default only assigns parameters to their default value based on their type (e.g. "0" for u8), it's not an actual implementation of actual default parameters. More details about this and what else is lacking in Rust compared to Kotlin: https://medium.com/@cedricbeust/what-rust-could-learn-from-k...
Re: Builder Pattern in Rust
#59> Since we do not have default arguments in Rust, in order to initialize such structure we would have to list all fields: I'm surprised the article doesn't mention Default: https://doc.rust-lang.org/std/default/trait.Default.html It can be combined with the rest pattern to yield something very similar to the solution the author is after. https://stackoverflow.com/questions/19650265/is-there-a-fast...
Default only assigns parameters to their default value based on their type (e.g. "0" for u8), it's not an actual implementation of actual default parameters. More details about this and what else is lacking in Rust compared to Kotlin: https://medium.com/@cedricbeust/what-rust-could-learn-from-k...