When you need to print / log a value from the middle of your call chain you have to take the chain apart. So just write it out to start with. It's not any less efficient.
When you need to print / log a value from the middle of your call chain you have to take the chain apart. So just write it out to start with. It's not any less efficient.
In IntelliJ you can breakpoint on an expression that uses chaining, hold down the alt key and then click on the expression you want to evaluate. It turns into a hyperlink and can be viewed easily.
But more abstractly speaking: are chained calls, from the POV of a human that didn't write it, or wrote it two months ago, more readable than a number of statements on multiple lines?
Debuggers are great but they're not always practical, for instance for debugging remote targets with limited connectivity. Actually in some situations you may end up having to buy expensive licenses for closed source software to run a debugger on certain hardware (although that might not be a concern for Go).
I'm also of the opinion that firing the debugger as soon as something unexpected happens instead of taking 10 seconds to reason about your code might lead you to miss a more general problem with your architecture as you focus solely on the symptoms, but that's of course a lot more subjective and your experience may vary. Personally I generally tend to use debuggers as a last recourse when I really can't make sense of what's going on through "static" analysis.
Saying that debuggers are for noobs and that they shouldn't be used is idiotic but arguing that not using them is doing it wrong and being stuck at the age of 80x25 terminals isn't much better. Wisdom is to use the right tool for the right job.
fn print(self) -> Self { println!("{:?}", self); self }
You can do it nicely, so all you need is to add one `derive` to a type declaration, and then you will be able to insert .print() into the chain.
It is like print in lisps, might be really handy for the debug printing.
Naming intermediates can sometimes make things clearer, but also it can make things less clear. Often there is no good name, or the good name is just as long as the code that made it.
As to derive for each type, I already use `#[derive(Debug)]` for most of my types, to be able to print them with {:?} in format/println!. Though you are right in the sense, that it would be great to make such a method a part of Debug trait. But I personally have never needed it, so maybe complications of Debug trait would be the over-engineering you speak about.
From other hand I do not like variables. Variables are complications of code, and complications like this make it impossible to grasp code on the first sight. There are a lot of cases when you need a variable, and it is not apparent on the first sight which case is it. You need to stop and think. I do not like to think just to find that there was no reason to think. Intelligence is a constrained resource, you need to use it wisely.