In short: You're right - Go will still evaluate argument expressions. In hindsight, I should've made that more obvious, not calling this out initially was an expert blind spot on my part, not an intent to mislead.
If we consider this example:
func risky() error {
return fmt.Errorf("unexpected error")
}
func risky2() error{
return fmt.Errorf("also an error")
}
func main() {
fmt.Printf("something failed: %v", risky())
dlg.Printf("something failed: %v", risky2())
}
And look at the disassembly: 0x10009f354 d503201f NOOP ; Dead code of dlg.Printf
0x10009f358 b0000000 ADRP 4096(PC), R0 ; Load "also an error" string address
0x10009f35c 9124ec00 ADD $2363, R0, R0 ; Calculate exact string address
0x10009f360 d28001a1 MOVD $13, R1 ; Set string length=13 (R1)
0x10009f364 aa1f03e2 MOVD ZR, R2 ; Clear R2
0x10009f368 aa1f03e3 MOVD ZR, R3 ; Clear R3
0x10009f36c aa0303e4 MOVD R3, R4 ; Clear R4
0x10009f370 97ffd890 CALL fmt.Errorf(SB) ; Call fmt.Errorf
What disappears is the logging work (formatting, interface/slice plumbing, I/O) and the call itself.
Go cannot eliminate calls to functions inside of Printf because they could produce side-effects.
Eliminating functions calls like this would be very expensive to do and would clashes with Go's focus on fast compilation times.I'll add a section to the README that explains this. Thanks for pointing it out.