On Tuesday, 12 March 2013 at 16:28:14 UTC, Nick Sabalausky wrote:
"Happy accidents" is nothing more than another way of saying "Shit
fucked up, but by pure dumb luck there was no damage". It's an
absolutely *terrible* thing to encourage and design for. You may as well just go dynamic all the way, a la ActionScript 2 or Python - it's all the same "let random things happen by accident and blindly hope it
just happens to turn out correct" philosophy.

Design-by-accident is an anti-pattern.

To me more specific, the problem with duck typing is that it falsely
assumes that name+signature uniquely defines semantics (which is
clearly not a valid assumption). Avoiding accidental screwups under duck typing *is* feasible if there's only a few well-known duck types that are ever in play (ex: our entire list of available duck types is a handful of phobos-defined ranges and basically nothing else). But it does not scale: The likelihood of accidental fuckups is multiplied with each additional duck type in existence, with non-stdlib duck types
carrying a greater "accidental fuck up" weight.

I thought about this a bit more, and I agree with the fundamental content of what you said.

The crux of the matter is that we can't specify new semantics with code. We can only specify new semantics through documentation. And compilers don't read documentations.

But, I think a good way to alleviate this problem would be to allow programmers to specify that two different concepts are in fact the same exact concept. Then two unrelated libraries could be made interoperable with each other.

Example:

There are two unrelated libraries, LibA and LibB.

Library LibA defines:
1) concept ConceptA { ... }
2) void functionA(ConceptA A)(A a) { ... }

Library LibB defines:
1) concept ConceptB { ... }
2) void functionB(ConceptB B)(B b) { ... }

The two concepts, ConceptA and ConceptB, specify the same exact concept (this can be verified only by reading their respective documentations). If the end user now creates a type which implements ConceptA:

struct MyStruct implements ConceptA { ... }

...then the problem is that instances of MyStruct can't be passed to functionB. But, if the end-user has a way to say that ConceptA is a synonym to ConceptB, then he can make the two libraries interoperable with each other and with his own types. E.g:

concept ConceptA = ConceptB; // make them synonymous

struct MyStruct implements ConceptA { ... }

MyStruct ms;
functionB(ms); // OK

If ConceptA and ConceptB have happened to use different function names for doing the same conceptual thing, then the end-user should also be able to specify which function names are synonymous with each other.

Reply via email to