4 ms·
why no nulls? and no exceptions? I am no language designer but as a user they seem ... usable.
by Graffur 6y ago
why no nulls? and no exceptions? I am no language designer but as a user they seem ... usable.
- noir_lord 6y agoIf you have nulls (or nullable types) then you end up checking for them everywhere (in every codebase I've seen anyway - keeping them on the boundaries only works if that's practical and the language always does it for it's standard libraries etc). Additionally you can no longer say Thing is Thing, it's always Thing or null - which results in special handling if (foo === null){} everywhere and when you don't boom NullPointerException. Exceptions cause problems in other ways (especially when they are allowed to escape up the stack), business logic shouldn't be handling FileNotFoundException that was thrown 6 layers away.
- skwirl 6y ago>Exceptions cause problems in other ways (especially when they are allowed to escape up the stack), business logic shouldn't be handling FileNotFoundException that was thrown 6 layers away. So instead all 6 layers should have to know about it in addition to business logic? In most cases you can't really ignore the fact that a file didn't exist in your business logic.
- dkjaudyeqooe 6y agoThat's an argument for exceptions. If they shouldn't be handling it they shouldn't be catching it. If they're the highest level why didn't the other 6 layers handle it? It's easier to be adaptive with error handling with exceptions, and who's going to (correctly) test for all possible errors on every call?
- Graffur 6y ago> If they're the highest level why didn't the other 6 layers handle it? I would have the same question.
- larzang 6y agoSo what's your proposed alternative that doesn't involve checking? Option-style wrappers enforce consistent checking and handling, but so do explicitly nullable type signatures. At some point you're going to need to know whether you have data or not, and that requires checks.
- TeMPOraL 6y ago> business logic shouldn't be handling FileNotFoundException that was thrown 6 layers away No, that's the job of whoever requests a file to be read. But what they may do in reaction to this, or discovering the file is empty, or has malformed data, is to throw a DataUnavailable exception, a subtype of RequestError. This is something appropriate places of the business logic up the stack may be interested in. Maybe some code few layers up the call stack can recover from DataUnavailable by attempting to pull from an alternate data source. Maybe not. Maybe that too will fail. Further up still, something else will intercept RequestError and report a problem to the user. But, unlike with Result types, only those three places in this piece of business logic have to ever care about some file not being read. Everything else can just assume the operation succeeded. Exception types follow the same rules as "regular" user-defined types: they're relevant in a subsection of a program, and shouldn't propagate beyond that subsection.
- dkjaudyeqooe 6y agoThey live in a world where nothing ever goes wrong and nothing is ever missing. Sounds nice.
- dunefox 6y agoIt's almost as if nulls and Exceptions aren't optimal for modelling missing states and faulty logic.
- orthoxerox 6y agoExceptions are not a part of your method signature, so every time you call something you don't know if you have to catch an exception or not. Java tried to fix that, but doesn't let you generalize over exceptions, "my method throws FooException and whatever exceptions method Bar on the instance of Glorbable you're passing me throws". Nulls have the same problem. Every time you get an instance of Foo you don't know if it's a null or an object. C# is trying to migrate to explicit nullability, but it's hard to convert an established ecosystem with idiosyncratic nullability rules.
- brabel 6y ago> ... but it's hard to convert an established ecosystem with idiosyncratic nullability rules. Dart has just done that, though admitedly, it did not have an ecosystem as large as C#'s.
- orthoxerox 6y agoC# had to invent attributes to work around structs vs classes and around TryX methods where out variables are null or not based on the return value. And the issue of arrays of objects or objects inside structs hasn't been resolved yet.
- wvenable 6y agoAssume all methods can throw exceptions. And if, by chance, you believe a method doesn't throw an exception today you have no idea if it's implementation will change tomorrow and it will then throw an exception. Whether a method throws an exception or not doesn't matter as much as people think it does. You can rarely recover from an exception in the immediate parent calling method anyway. More than likely the error will occur in a stack 20 layers deep and recovery is to restart the entire operation from the start. Nulls are useful but I totally agree that they should be opt-in in the type system.
- pjmlp 6y ago> Java tried to fix that Nope, Java picked the idea from CLU, Modual-3 and C++, in what seemed the way forward to declare exceptions. It does provide both checked and unckecked exceptions, unfortunely it suffers from bad learnings and quick hacks to shut the compiler instead of thinking it through when designing class libraries (yes even the std suffers from this).
- samatman 6y agoFrom an ADT perspective, letting any type T be null is the same as saying everything is an Option<T>. Except nothing else in the language forces you to handle the optional case, so you end up with either null checks everywhere, or your code blows up with NullPointerExceptions, or sometimes both. Ever been deep in a Java call stack, and wondered if you've already checked for null in all cases? In a language with (only) Option types, you can simply declare that variable to be T, and if it's actually Option<T> (i.e. you haven't checked for absence along some path) you'll get an error. A good compiler will even tell you where in the code the None is sneaking in, so you can fix it there, or pattern-match on Some and None where the error is, depending on which is correct for your logic. I'm ignoring the exceptions question, because the post doesn't even consider a condition/restart system, which means it's not-even-wrong.
- Graffur 6y agoWhy can't a compiler essentially do the same for null as you're describing for None?
- samatman 6y agoIt's basically a definitional thing. An Option type means you must specify Some (pointer) or could-be-None (null, NULL pointer) and the compiler will enforce the distinction. Generally this comes with exhaustive pattern matching, so you can turn Some<T> into <T>, and handle None by raising an error or assigning a default or blowing demons out your nose. None and null are the same thing, the name isn't the important part. Zig, for example, has optional types as ?*Foo, and calls the null pointer "null".