On Wed, 31 Dec 2025 23:05:21 -0500
Joel Fernandes <[email protected]> wrote:

> Hi John,
> 
> On 12/31/2025 9:52 PM, John Hubbard wrote:
> [..]
> >>> But this really is fake chaining, because there are no Results involved.
> >>> It's not buying us anything except a bit of indirection and cognitive
> >>> load for the reader.  
> >>
> >> Chaining is not really only about error propagation. Builder pattern can 
> >> be used
> >> for other cases too, like passing a setter chained expression to a function
> >> argument for better clarity, I was planning to do that for the sequencer 
> >> for
> >> instance since there's a lot of parameters passed to it.  
> > 
> > Let's see if that has any use for this.
> > 
> > So far, though, in the code base that we have today, there is absolutely
> > zero benefit. The diffs here prove it.
> >   
> 
> From your patch diff, I see the lines of code increased. But that's not even 
> the
> main issue I have with it (though IMO the chaining is more readable..).
> 
> >> But in this case, I am actually absolutely opposed against this, it makes 
> >> the
> >> API hard to use because now how do you differentiate between an IO 
> >> function call
> >> versus something that just mutates memory? Is set() an IO or write()?  
> > 
> > That's a completely separate, pre-existing issue with the API.  
> 
> Nope. With chaining we clearly know that the final operation is a write().
> 
> For instance, you cannot do:
>   reg.set_foo()
>      .write()
>      .set_bar()
> 
> That wont compile. You cannot intermingle write() with set_XX() because 
> write()
> doesn't return anything that can be chained with. The builder pattern is 
> typically:
>   obj.set_something()
>      .set_something()
>      .do_some_action()
> 
> The 'set' can also be 'with' from what I've seen, whatever. The point is the
> last thing is the action. IMO very readable and simple. I know that the 
> write()
> will be what ends up doing the I/O. It is one entity that culminates in the 
> write().
> 
> >   
> >>
> >>       reg.set_foo(x);   // no IO
> >>       reg.set_sec(y);
> >>       reg.write(bar);   // IO.
> >>
> >> So no thank you, I quite dislike it. :)
> >>
> >> Instead with chaining, we can just rely on the last part of the chain 
> >> concluding
> >> in a write() with the intermediaries just mutating memory.  
> > 
> > Same as above, just a more happy-happy chaining interface, but the same
> > function calls must be made in the same order.  
> 
> No, you cannot place write() anywhere except at the end of the chain - the 
> type
> system enforces this since write() returns ().

One thing that probably should be added though is `#[must_use]`
annotations on these set functions; this would ensure that if someone
writes

        reg.set_foo();

the compiler would complain that the return value is not used.

Best,
Gary


Reply via email to