6 ms·
>But, again, they will catch your runtime errors if your behaviour is covered. If your behaviour isn't covered, then you're just shifting the problem to the pro
by ninetyninenine 2y ago
>But, again, they will catch your runtime errors if your behaviour is covered. If your behaviour isn't covered, then you're just shifting the problem to the program doing the wrong thing instead of crashing. That is not a win. It might even be worse! So, this doesn't matter in practice. Your purely academic view of the world doesn't work with the discussion taking place, I'm afraid.
So you're saying write tests that cover every possible behavior. Makes sense right? It's like saying write code without any bugs. Simple! You're not getting it. You can go run around telling people to write tests that eliminates 100% of bugs and that if you think that will eliminate all bugs from the world, well you're just not experienced.
>Go on. To continue with the original example, I have a function that tries to write to a file. If that fails, the caller is to try to write to a file on a different device. If the caller does anything else the program is broken with serious consequences and should not be shipped to production. Express that expectation using sum types. Hell, express it using any type construct available in popular languages. Good luck!
You can do this on rust. Literally it's the core of the rust sum type system. Good luck? Have you done basic programming with rust? Here's some psuedo code:
match getFile(fileName) {
Some(file) => do someghing
Error => match getFile2(fileName2) {
Some(file) => do something
Error => exit()
}
}
The above is psuedo code. The thing with the match operator is that the program DOES not compile if you do not handle both SOME and ERROR. For golang you can handle the Some and then it crashes if there's a problem. You aren't required to explicitly handle it.
>Not so. I spend most of my days writing code in programming languages that do provide such guarantees. It is a cool party trick, but doesn't really matter at the end of the day because they still don't offer the expressiveness to ensure that the program does what is expected of it. I still have to write tests, and once I've written the necessary tests to ensure all the behaviour is correct, there is no way you can miss a crash situation.
There is a way. You're just not getting it. there's about infinite ways to crash a program that has runtime errors.
>Your fuzz tests never tried passing in values that would lead to division by zero? For such a simple function that has many possible states that can lead to that condition, that seems inconceivable. Hell, I just tried it for fun and it found the issue in less than 100 tries! This must have been the time you were talking about where you deployed to production without running the tests?
Hell I used a programming language with no run time errors and I didn't write a single test. Amazing! There are tons of functions complex enough such that your fuzz test will miss it. Again we had this code working for years because we implictly assumed said devices will never pass duplicate data.
Also we don't write fuzz tests. We just do basic testing. Fuzz testing is something our start up doesn't have time for. We would prefer guarantees without the need of extra testing/work/time in this area.
>Traditionally, the calculation is (p2 - p1) / (t2 - t1). I'll assume you had a non-standard situation that necessitated a different formula, but does serve as a great example of how behaviour is your real concern. One could easily input the formula you gave where they expected (p2 - p1) / (t2 - t1) and sum types wouldn't care one bit.
Nope your formula is correct. I just assumed you were intelligent enough to know what I meant even though I didn't put in all the parenthesis (I'm typing on my phone afte rall). I thought wrong.
>Agreed. Complete type systems are cool. Writing tests is tedious. But we await your proof to my case for a realistic setting where one uses a typical production programming language. If all you have is silly half-measures that only cover a small number of cases, you're not really proving much. All you are doing is giving yourself a false sense of security.
Yes rust. Jesus. You're so inexperienced you don't even know when it's standing in front of your face. You don't need the borrow checker from rust. You only need the sum type. Then take the sum type apply it to division by zero and out of bounds array access and all IO calls. Boom that's it. No more runtime errors.
>There's a good way to change that. Let's see your code!
just look at elm man. Yuo don't even know what I'm talking about because you literally don't have experience. You want to see code that never crashes? Get some experience with Elm and you'll see why it never crashes and you'll see it doesn't take a "complete" type system to make it that way. Elms type system is woefully simplistic.
Rust is like 80% of the way there... the reason why people don't use it is lifetimes and the borrow checker and the complexity associated with it. Additionally rust left some holes so it can crash (like division by zero), but it has all the primitives needed to prevent it.
- 9rx 2y ago> Good luck? Have you done basic programming with rust? Have you? I am sorry that the good luck did not shine upon you. With the types remaining intact, I modified the (pseudo)code: match getFile(fileName) { Some(file) => do someghing Error => do something else unintended } It still compiles. You failed. > The thing with the match operator is that the program DOES not compile if you do not handle both SOME and ERROR. But as you come off your hubris, you can now see above it will compile even when you screw up the error handling. So you haven't gained anything. You still need to write tests to ensure that you are actually doing the right thing. And once you've ensured you are doing the right thing, how do you think crashes are going to go beyond that? Right. Not going to happen. > Fuzz testing is something our start up doesn't have time for. Testing, is testing, is testing. If you have time to write tests, you have time to write fuzz tests where they are appropriate. To throw a test out the window just because it has a slightly different execution model (as provided by the language; not something you have to build yourself) is bizarre. In fact, in your case it seems it could have supplanted the other tests you wrote, actually saving you time not only while writing the code, but also later when you had to waste time dealing with the issue. Time clearly isn't as constrained as you let on. > For golang you can handle the Some and then it crashes if there's a problem. You aren't required to explicitly handle it. Technically, in Go 'Some' should always be valid, regardless of whether or not there is an error. That is a fundamental feature of the Go language. Given (T, error), the values are not dependent. You don't need to explicitly handle the error. That is a huge misunderstanding. The same would not be true in Rust, which does consider them to be dependent by design, but Go is a completely different language. You can't think Go as being Rust with different syntax. There is a lot more to languages than the superficial.
- ninetyninenine 2y ago>Have you? I am sorry that the good luck did not shine upon you. With the types remaining intact, I modified the (pseudo)code: Your modification makes no sense. "do something else unintended" Wtf does that even mean? What are you doing? Why don't you spell it out? Because in golang you can do this: v, err := getFile(fileName) v.read() And that's a fucking crash. You understand examples are used to illustrate a point right? And that your example shows you missed the point. Hey why don't I insert some psuedo code called "blow up the earth" in my program and that disproves every point ever made by anyone and I'm right. Genius. >But as you come off your hubris, you can now see above it will compile even when you screw up the error handling. Think of it like this. The point I'm illustrating is that in rust, you have to handle an error or the program won't compile. In go, you can forget to handle an error and your program will compile. You're going to have to write a bunch of tests to only POSSIBLY catch a missed error handling case. Understand? I don't think you do. >Testing, is testing, is testing. If you have time to write tests, you have time to write fuzz tests where they are appropriate. To throw a test out the window just because it has a slightly different execution model (as provided by the language; not something you have to build yourself) is bizarre. In fact, in your case it seems it could have supplanted the other tests you wrote, actually saving you time not only while writing the code, but also later when you had to waste time dealing with the issue. Time clearly isn't as constrained as you let on. It's not bizarre. It's again, lack of experience from your end. Why do I want to spend time writing generic test code that executes off of fuzzed input? I can write test specific code for specific use cases and that's much faster to write then attempting to write tests that work for generic cases. Also how about not writing tests all together? I mean that's the best solution right? Honestly not to be insulting here, but it's not at all bizarre that you're not seeing how a better type system is better then tests that check for runtime errors. The root of it is that you're just stupid. Like why jump through a bunch of hoops and just call what I'm saying "bizarre" and just be straight with me. We're both mature right? If I think you're truthfully stupid and you think of me the same, just say it. We can take it. Why dance around it by calling my points "bizarre". No your points aren't "bizarre". They are stupid and wrong. >Technically, in Go 'Some' should always be valid, regardless of whether or not there is an error. That's why go is bad. You don't need to handle an error if err is not nil. V will be a nil here. And you know what's the only thing you can do with a nil besides check if it's a nil? Crash the program. Literally. With rust, you can do this: match getFile(fileName) { Some(file) => do someghing Error => {} } and do nothing. Which is the same effect as golang. But rust at least tells you to explicitly watch for it. >You can't think Go as being Rust with different syntax. There is a lot more to languages than the superficial. It's not about what I think of the language. It's about the intention of the designers. Go was made for people with not much experience. Straight from the horses mouth. Pike is saying he designed it for you. >That is a fundamental feature of the Go language. I think you're kind of not getting it. Seriously like the feature of golang is to allow you to unintentionally crash the program and you think that's a good thing? v, err := getFile(fileName) doSomething(v) Take some time to think here. I know you think you're smart, but you need to hit the brakes for a second. Think: What is the purpose of the above code? If err actually is not a nil, and v ends up being a nil. What is the purpose of this type of logic to even exist? Is it for v to crash somewhere in doSomething? Are you saying that a fundamental feature for golang to crash somewhere inside doSomething? Really think about this. You literally said it's a feature for golang to not handle an actual error and for v to still be "valid." So if err is not nil, v is a nil. What happens here? You think this is a feature? Or are you just not thinking straight? Just pause for a second. Another thing to help you along: You know the inventor of the null/nil value called it his billion dollar mistake right? Have you thought about why it's a huge mistake? Here's a hint: You can't do anything with a null/nil except check if it's a null or crash the program by using it improperly. The existence of a nil/null signifies the existence of feature that you can only use to crash your program unintentionally. Why doesn't elm crash? Why is rust safer then most languages? A big part of the reason is both languages don't have nulls or nils. And that doesn't have anything to do with a "complete" type system. Hopefully you get it now. If not I can't help you.