I had a hard time getting your examples into a state that worked.
Even after that, I don't see how what you are doing improves over a switch. It actually looks less readable to me, with no gain in functionality at all.
Your example is actually working, in that you've initialised a field type of an empty string which isn't a valid enum value.
I agree this is slightly less readable than the native switch, but it means the compiler can tell you when parts of your code try handling all enum values but don't, in fact, handle them all.
For the default switch you'll only find out at runtime, which isn't very useful when developing.
Does that make sense? The compiler warning in the article is probably the best example of what I mean here.
You're right, which is why we don't need types, I guess?
I'm being facetious, but if you're using a statically typed language you've already bought into types helping you across your codebase being worthwhile.
Equally, this situation is one where the testing point doesn't work. Your tests for the existing functionality won't, obviously, be testing the new functionality you're creating.
So they won't be able to catch that one part of your codebase doesn't support the new feature, while this solution can help you with that!
Let's say you have a gun at home. This doesn't mean you have to shoot it every time the door bell rings.
>Your tests for the existing functionality won't, obviously, be testing the new functionality you're creating.
Well... duh, that's why write test in the first place. To test new functionality. In fact some people prefer writing test before the functionality in question.
>this solution can help you with that!
While making the codebase (subjectively) less readable at least. This maybe a viable option for a pet project but I wouldn't be happy to have it for a code review with the only reason being "now you don't have to test it" (you will have to test it anyway most likely)
You are presenting it as an exclusive "or" question, when in fact you just do both.
You add a variant, and the compiler will lead you to all of the places where you need to handle that variant.
Or you remove a variant, and the compiler will tell you about all of the places where your made assumptions about such a variant existing are now invalid, including the tests that you wrote when you implemented the variant in the first place.
Welcome to compiler driven development.
Of course it helps when sum types and pattern matching are a first class feature of your language.
I think we're cross talking. One of the primary advantages of this approach is that when you add a new value to that switch, your compiler will tell you about all the parts of the codebase that need updating to handle it.
Then you can use the compiler errors to help you write the tests for the new feature.
You might say you'd prefer to just search the codebase for parts you need to update, and you're ok with forgetting the odd thing and finding out when it's broken after shipping. That's ok, but I'd prefer to have the compiler help me do this rather than doing the work myself.
That's irrelevant to the task at hand. The linter can't tell you if your type switch can handle every `interface{}` that might be passed into it some day.
Even after that, I don't see how what you are doing improves over a switch. It actually looks less readable to me, with no gain in functionality at all.
https://gotipplay.golang.org/p/xpuAIC5xdL_7