What's the Big-O on determining whether N functions are
a/ identical,
b/ similar but expressing potentially unique behavior,
c/ subtly varied.
identical, assuming x and y have the same type:
func (t *T) fX() bool {
return t.x == t.z
}
func (t *T) fY() bool {
return t.y == t.z
}
similar but expressing potentially unique behavior:
func (t *T) fA() bool {
return t.A == 0
}
func (t *T) fB() bool {
return t.B == false
}
func (t *T) fC() bool {
return t.C == 0.0
}
subtly varied:
func (t *T) fU() bool {
return t.U == 0
}
func (t *T) fV() bool {
return t.V < E
}
Sure. For 2-3 functions this is easy enough. But if when you need to handle
each of bool, int8, uint8, int16, uint16, float32, int32, uint32, float64,
int64, and uint64 you have 11 functions to compare. What if you have to
repeat them for 5 structs? What if you have to also handle pointer-to cases?
Some years ago, I had the "pleasure" of reducing over 30,nnn lines of C
'specializations' of AVL trees with somewhere over 5nn lines of macro and
7nn lines of instantiation. And then 6 months later replacing the ~1500
remaining lines with ~320 lines of a templated C++ class.
The macro version found 17 cases where a c&p error, typo or unmaintained
correlation was resulting in undefined behavior that was causing flakiness;
the C++ version version ended up giving a 30% performance gain (if the C
version used 130 cycles, the C++ version might use only 100).
In a more recent codebase, cognitive load and code-as-documentation had
resulted in a decoupling of rationale for why a particular cast was taking
place. It was entirely reasonable for other engineers to simply see it as
part of the interface.
The reality was that the original engineer had been forced to specify a
type for the sake of specifying a type to describe an operation (store
value). They'd committed a type-choice based on the last state of the code
during their testing, which was based on a log api.
It then became the type used by every clone of the same function required
to support varied types (there were 16 put and 16 get functions).
This cast was mostly harmless, but it had used up about 200 engineer hours
just in the last 6 months because the side-effect was "flaky" (actually
deterministic, it just depended on the exact numbers given).
https://play.golang.org/p/p8_dUOLOpsT
So, instead of a bunch of unique functions or a collection of type
switches, you can simply write as close to:
dst.value = dst.value.cast(src.value)
or
if dst.value.(type) == src.value.(type) { dst.value = src.value } else
{ panic("you're nuts") }
as possible. Now both the compiler and the human reader can tell what you
actually meant rather than reverse engineering it from dozens of lines of
code.
-Oliver
On Wednesday, December 23, 2020 at 10:16:00 PM UTC-8 Martin Hanson wrote:
> I have been arguing passionately against adding generics to Go because
> I truly believe that it is going against the simplicity of Go and the
> philosophy behind the design of Go.
>
> I believe that the resilience of Go against unnecessary change is of
> vital importance. The experience provided by Ken Thompson, Rob Pike and
> Robert Griesemer in designing Go the way they did speaks for itself.
>
> I feel and believe it is of imperative importance to avoid adding things
> to Go that doesn't present a true and real life day-to-day problem
> and so far none of the examples the pro-generics camp has provided has
> been more than minor theoretical examples that do not present any real
> life problems.
>
> I therefore propose that the pro-generics camp provide real examples of
> problems they have faced that was such a big issue that it justifies
> adding generics to Go.
>
> If all we're presented are these small theoretical examples of sorting
> lists, etc., then clearly this is nothing but hype that needs to go
> away.
>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/640b06ac-dabe-4845-b50d-cc3429d48fe5n%40googlegroups.com.