5 ms·
You don't need option types for the compiler to enforce safety around nulls. Its possible to model null as its own type in the type system to enforce safety.
by RX14 8y ago
You don't need option types for the compiler to enforce safety around nulls. Its possible to model null as its own type in the type system to enforce safety.
- coldtea 8y agoThis means you need a different type system though.
- RX14 8y agoYeah, its a good option for new languages though.
- lmm 8y agoIt's the same mistake as checked exceptions all over again. If you make null a special case in the type system then anything that interacts with the type system has to know about null or will handle it wrong. Far better to have the type system work with plain (non-nullable) values, and implement a plain old library type like Maybe/Option for use in places that need absence semantics; that way your concerns are properly separated and you can spend your type system complexity budget in more generally applicable ways.
- RX14 8y agoJust because null is a type in the type system doesn't mean it has to be a special type.
- lmm 8y agoThat's the only way I've ever seen it implemented. If you're proposing some idea for having null in the type system as a normal type (that doesn't boil down to just being equivalent to Option/Maybe), can you be more concrete?
- RX14 8y agoBeing able to create arbitrary union types between different types, like crystal (which I work on). The difference between that and option/maybe is that it ends up playing nicely with flow typing without any special cases for optional/maybe in the flow typing.
- lmm 8y agoYou shouldn't need special cases for optional/maybe in the first case; optional/maybe are simple sum types, you would want whatever flow-typing system you have to do the right thing with user-defined "x or y or z" types, and if you do that then it'll automatically work just as well for optional/maybe. (I don't like inclusive union types because they're noncompositional - code you write with them isn't parametric any more - which seems particularly awkward in a compiled language - how do you compile code that forms unions involving type parameters?)
- RX14 8y agoYou shouldn't be able to use a type without giving all the necessary type parameters, so you can't form a union type with unbound type parameters in so it's not a problem? I'm not 100% sure what you're asking... I'm not 100% sure how you can integrate sum types with a flow-typing system, perhaps with pattern matching?
- lmm 8y ago> You shouldn't be able to use a type without giving all the necessary type parameters, so you can't form a union type with unbound type parameters in So inside the body of a generic method (or class) you can't form unions involving the method's type parameters? That works but makes them much less useful as a language feature - most language features work as normal within a generic method. > I'm not 100% sure how you can integrate sum types with a flow-typing system, perhaps with pattern matching? Whatever you do for union types should work, surely. Indeed it ought to be simpler since you have more information to work with - with a sum type if the thing is B then you know it's not A, whereas with a union type it's possible for the thing to be both A and B.
- mannykannot 8y agoIn such a type system, is every variable and function potentially null, or does its type have to be declared as being potentially null (or not declared as not null)? Would the latter case not be, in practice, just like using option types, and would the former case require ubiquitous null checking? My understanding so far is that option types have two advantages over the way current mainstream languages handle the null case: a) you can find the potential uses of null values statically, and also ensure that the programmer writes some code that at least nominally handles the case; b) you can avoid this burden in cases where null is not an option. Does null-as-its-own-type improve on this?
- RX14 8y agoI mean the latter. And in practice, it's not just like using option types because it works well with flow typing. Being able to express your nil checking in ordinary control flow instead of special optional methods is often cleaner (think `raise "foo" if bar.nil?` as a guard statement and for the rest of the method body bar is no longer nil). All absolutely safe and checked at compile-time. If you then allow calling methods on nil you can even implement the "try" method that most Optional implementations have, which is pretty nice sometimes even when you have flow typing. In Crystal we go a step further and allow type unions between arbitrary types (of which nil is just an ordinary empty struct in the stdlib which you can call methods on). I love how it works in practice.