6 ms·
OK, you're right that he wrote the example incorrectly (mine was a copy-and-paste from his). The point still stands though. > "Smartcast to Int is impossible b
by SomeCallMeTim 10y ago
OK, you're right that he wrote the example incorrectly (mine was a copy-and-paste from his). The point still stands though.
> "Smartcast to Int is impossible because value is a mutable property that could have been changed by this time". Right you are.
I disagree. It cannot have been changed by that time, not unless it was changed in another thread, and it would be really, really nice for a language to have built-in threading intelligence to prevent that from being necessary to check. That's what I'm saying. TypeScript is single-threaded, so it can be certain that another thread hasn't changed it. Go is multithreaded, but except for genuine globals (which need to be protected by a mutex, but shouldn't be used for just about anything) you're piping information from one state to another, which again doesn't have a synchronization problem.
If you have to manually mark a variable as "safe" every time you use it, you're just going to need to do that constantly for lots of variables. And you still are stuck getting the thread safety right: The above code isn't safe if something from another thread can change value. Which I guess is the point of the exclamation points, but ... somehow I prefer the Rust approach of "Mark this block of code as unsafe." Not that I've used either language.
The fact that it works correctly as a parameter, though -- that does hit the 80% case, at least.
- pdpi 10y ago> If you have to manually mark a variable as "safe" every time you use it, you're just going to need to do that constantly for lots of variables. > ... > The fact that it works correctly as a parameter, though -- that does hit the 80% case, at least. That's the thing, it's not "80% of the cases". It actually hits just about all of them. For this whole situation to be a problem, rather than the compiler preventing bugs, you need all of the following: — You need a `var`, rather than a `val` (constant). — The `var` needs to be nullable. — The var is either a module global, or a class field. — Your code doesn't touch anything multithreaded. This includes not using NIO, or having any callbacks at all to libraries that might use threading internally. If any of those requirements is missing, the compilation error is either legitimate, or gone. In my experience, eliminating the multithreaded part eliminates all the reasonable use cases for Kotlin-as-a-Java-replacement: Android, web development, desktop applications. Not all languages need to be good at everything. For my purposes, I welcome a language that makes working in heavily-multithreaded environments a bit easier, and I won't begrudge languages targeting other people's use cases either.
- SomeCallMeTim 10y agoModule global variables, I think we can agree, are less than ideal. But I was thinking of class fields. I don't really want my compiler to hold my hand with respect to "nullable", if I know for a fact that, by the time the code gets there, it can't possibly be null. Think of it this way: It's not a compile error to access an int from multiple threads, right? It doesn't require that !! syntax if you're just accessing a mutable class field or variable? So if I test an int for a value and then do something that assumes the value is still the same, I'm writing something that could crash just as easily as the null reference -- and array out-of-bounds, or a flag that says it's OK to do something but that flag changes after I check it, because I didn't grab a mutex. So why does it add an error condition if you're accessing a mutable variable that's available in multiple threads just because it's nullable? Seems like extra busy work for no clear benefit for what is, as you say, a rather rare situation. If we're going to share data across threads, I'd rather the language not present a false sense of security as a result of the !! operator.
- pdpi 10y agoI think you misunderstood me — the rare situation is the compiler complaining about valid code. In practice, I find null handling in Kotlin to be quite straightforward, and it simplifies both writing and reading code a fair bit. I also find that forcing me to opt in to allowing nulls and, therefore, complicating my code a bit (by correctly handling them in the implementation) forces me to clean up my designs a bit. Now, Jetbrains don't claim to solve data races in general, so it's fine to not solve all of them. But they _do_ claim to provide null safety in general (modulo java interop), so they _must_ provide null safety in the face of data races. I do agree that a language that solves data races in general is very, very valuable (and that's part of the reason why I've invested some time learning Rust), but solving nulls better than the half-arsed solution present in java Optional is, IMO, still quite valuable. Finally, what do you mean by "a false sense of security as a result of the !! operator"? The !! operator is effectively "I know for a fact this isn't null, stop bothering me", and, when you read it, it should raise alarm bells, rather than make you feel safe. I also object to the notion that a language that is a bit safer is bad because it lulls you into a false sense of security. That's like saying that GCs are bad because they lull you into a false sense of security from memory leaks.