The problem with that dictionary solution is that it relies on throwing an error at runtime. There’s no information provided to the compiler to catch it sooner. Which means that you’ll only find out if you forgot a case (or a key the dictionary) if you write a unit test that tests for exhaustiveness. But rather than write a unit tests, wouldn’t it be better to find out at compilation that a mistake was made?
So I would recommend that you give the article another read and then try out the samples I provided in the article in a REPL. It’s probably not apparent the advantages without seeing how quickly the error pops up in a TypeScript playground. You’ll find that they allow you to discover bugs much faster (since you don’t have to run the code).
You're trying to get things checked at compile time, but I'm not sure if the compiler is really suited to check the app logic (the compilers' job is to check syntax and such).
wouldn’t it be better to find out at compilation that a mistake was made?
Not really, I trust my tests more than the compiler, cuz the app logic might break one day (one way or another), and the beauty of tests is to get that logic checked everytime you go into the building stage.
I completely disagree here, ideally the compiler would check all your app logic too, the more you can get checked by the compiler, the less tests you need to maintain. Languages like Haskell are popular just because the compiler can help you a lot.
I trust my tests more than the compiler
Tests can never show the absence of bugs, only the presence. Having a type system cut the possible inputs down to (in this case) a finite amount of values is far more valuable than testing the 4 values you mention in your unit tests.
@Cubicle
The problem with that dictionary solution is that it relies on throwing an error at runtime
Not with TypeScript, the following code will throw a compiler error if you change the TrafficLight type, without adding something to the object:
Great work Yan. Yes, your type would require each key to be present. It’s another thing I love about TypeScript. There are so many ways to express concepts. :)
But, as for Python (or any similar lang), I'm not sure this would be the case since this even goes against the Python moto: "let the exceptions fly and catch them later".
So, defensive programming model might be different from a lang to another.
Interesting. I tried to find an article about Python and “letting the exceptions fly” but I couldn’t find anything.
One should always choose the best tool for the job. Sometimes that might be throwing/catching an error, and other times it might mean preventing it with the type system. Why limit yourself to one tool?
“When all you have is a hammer, every problem starts to look like a nail.”
The problem with that dictionary solution is that it relies on throwing an error at runtime. There’s no information provided to the compiler to catch it sooner. Which means that you’ll only find out if you forgot a case (or a key the dictionary) if you write a unit test that tests for exhaustiveness. But rather than write a unit tests, wouldn’t it be better to find out at compilation that a mistake was made?
So I would recommend that you give the article another read and then try out the samples I provided in the article in a REPL. It’s probably not apparent the advantages without seeing how quickly the error pops up in a TypeScript playground. You’ll find that they allow you to discover bugs much faster (since you don’t have to run the code).
Ah, now I get your point...
You're trying to get things checked at compile time, but I'm not sure if the compiler is really suited to check the app logic (the compilers' job is to check syntax and such).
Not really, I trust my tests more than the compiler, cuz the app logic might break one day (one way or another), and the beauty of tests is to get that logic checked everytime you go into the building stage.
@yaser
I completely disagree here, ideally the compiler would check all your app logic too, the more you can get checked by the compiler, the less tests you need to maintain. Languages like Haskell are popular just because the compiler can help you a lot.
Tests can never show the absence of bugs, only the presence. Having a type system cut the possible inputs down to (in this case) a finite amount of values is far more valuable than testing the 4 values you mention in your unit tests.
@Cubicle
Not with TypeScript, the following code will throw a compiler error if you change the
TrafficLight
type, without adding something to the object:Great work Yan. Yes, your type would require each key to be present. It’s another thing I love about TypeScript. There are so many ways to express concepts. :)
I agree with you in this TypeScript scenario.
But, as for Python (or any similar lang), I'm not sure this would be the case since this even goes against the Python moto: "let the exceptions fly and catch them later".
So, defensive programming model might be different from a lang to another.
Interesting. I tried to find an article about Python and “letting the exceptions fly” but I couldn’t find anything.
One should always choose the best tool for the job. Sometimes that might be throwing/catching an error, and other times it might mean preventing it with the type system. Why limit yourself to one tool?
“When all you have is a hammer, every problem starts to look like a nail.”
I think the last time I heard it about was in a video or so, but the correct idiom is "Easier to ask for forgiveness than permission"
This video explains it in a nice way: youtube.com/watch?v=x3v9zMX1s4s
And this article summarizes things: devblogs.microsoft.com/python/idio...
I can totally relate after I saw how TypeScript goes (I never used it before, just the old normal JS).