5 ms·
It depends on the language, and the API of the libraries you use. If we have a Haskell-like Maybe type, you should be able to create functions that refuse to ta
by scott_s 12y ago
It depends on the language, and the API of the libraries you use. If we have a Haskell-like Maybe type, you should be able to create functions that refuse to take a Maybe. That would force you to determine soon after the fileOpen call: did it succeed or not?
To be clear, this would involve the static type system for your language forcing certain things to happen, or not compiling. The sequence:
1. fileOpen returned a Maybe<FileObject>
2. You want to store the FileObject somewhere, and it expects an actual FileObject.
3. Maybe<FileObject> is not itself a FileObject, so you have to figure out: is it Nothing, or a FileObject?
4. You have to handle the Nothing case (language forces you to, even if you do nothing about it - you explicitly decided to do nothing).
5. If it is indeed a FileObject, you store it for later use, and you are guaranteed it is, indeed, a FileObject.
- taeric 12y agoRight. This makes sense. Though, I would have thought the lazy semantics of Haskel would trip you up here. Ultimately doesn't matter, my main argument is that I see people proliferate "Optional" values all over the bloody place. So, I would expect to find that they just put the optional ref up and used it later when necessary. And I should note that I don't necessarily dislike the optional types and such. I just also don't have the major disdain for null that the internet seems to send through a massive echo chamber nightly.
- wtetzner 12y agoThe problem with languages that have null is that they don't let you write non-nullable types. That means any variable at any time could be null. You don't have the option of guaranteeing something won't be null.
- dragonwriter 12y ago> The problem with languages that have null is that they don't let you write non-nullable types. That's a problem with Java (because it doesn't let you do that) and a similar problem exists with dynamic languages (because types aren't attributes of variables, so any variable could be null -- or any other value, null isn't particularly exceptional in dynamic languages for being a source of this kind of problem), but its not a problem "with languages that have null", as there are statically typed languages that have null but distinguish nullable and non-nullable types (C# and other static .NET languages are probably the most well-known examples, though there are others.)
- wtetzner 12y agoC# only kind of gives you this. When I said "the problem with languages that have null", that's really what I meant. There definitely could be a static language that let you choose if something is nullable or not. But really, at that point it's just sugar for an option type.
- dragonwriter 12y agoC# is absolutely a static language that lets choose if something is nullable or not, there is no "kind of" about it. > But really, at that point it's just sugar for an option type. No, having a the free choice not use nullable types doesn't make the languages nullable types into sugar for option types. Nullable types don't compose the way option types do -- the issue in the article this thread is about isn't about whether or not you have the choice for nullable types, its about the fact they don't compose so you can distinguish a function returning a null as a substantive value because the thing you tried to store was also a nullable type and had a null value (Just None, in a world with Options instead of nullable types) or where the null is a result of the lookup failing (None, in a world with Options instead of nullable types.) The deficiency of nullable types in C# compared to Options isn't the lack of choice of writing non-nullable types -- as you certainly have that choice for any data you need to represent -- its that nullabe types don't compose the way Options do.
- wtetzner 12y agoAs far as I understand, the only way to get a type that's not nullable is to make a struct. How do you specify that a function can take a non-nullable string?
- dragonwriter 12y ago> As far as I understand, the only way to get a type that's not nullable is to make a struct. Well, any value type -- but, yes, a custom type has to be a struct to not be nullable. > How do you specify that a function can take a non-nullable string? "string" in C# is the name of a particular reference (and hence, nullable) type. If you want a function that takes a non-nullable sequence of characters, that's quite possible, but the type of its argument won't be string. (The fact that there is no such type predefined and the entire .NET framework library is built around the assumption that if you want a sequence of characters you are going to use the built-in, reference -- and therefore nullable -- string type is an issue with the cost, in programmer-time, of doing this for any substantial use, but its not a "the language doesn't let you have a non-nullable type for any kind of data you want" issue.)
- Dewie 12y ago> I just also don't have the major disdain for null that the internet seems to send through a massive echo chamber nightly. The disdain is probably (allow me to project) because it is a totally unnecessary problem which can be solved easily with virtually no drawbacks.
- taeric 12y agoHaving worked on some projects that have more bloody optional variables than I can shake a stick at, I wouldn't claim there are no drawbacks. The cognitive overhead of some of them is bloody heavy. Especially if there is poor judgement on when a parameter is optional or not.
- dllthomas 12y agoThat's not solved by making them implicit. Then you need to keep even more in your head!
- taeric 12y agoI prefer to architect the code such that it is only possibly null in one section of the code. For the rest, it should never be null. Pretty much period. Granted, this can certainly be done with optional types. So, I'm not ultimately against them. I just think they are oversold quite a lot.
- dllthomas 12y agoIt's not just that this "can be done" with optional types - this is precisely what optional types are for. And they help make sure you're never mistaken about that "pretty much". Like any tool, people can misuse it (propagating them everywhere would be an example of this, partial extraction functions would be another).
- taeric 12y agoRight, that is essentially my point. I do still hold more pessimism than I probably should, but by and large my main objection is just to the nature with which optional types are sold. They are almost like the vitamins of programming. Great for when they are really needed, probably wasting a ton of time for where many people that just found them put them to use.
- chriswarbo 12y ago> I would have thought the lazy semantics of Haskel would trip you up here. Laziness doesn't come into it, since you won't even manage to compile your code, let alone run it, if you try to use a "Maybe FileHandle" when a "FileHandle" is expected. With that said, laziness does cause problems related to file handles, but those have nothing to do with unhandled failures. The problem is that files are a limited resource which we should release as soon as possible (just like memory, sockets, etc.). Lazy evaluation is at odds with this, since it essentially defers function calls to the last possible moment. One way of thinking about it is that laziness is "call-by-need", but we never really need the return values of functions like "closeFile".
- taeric 12y agoRight, I would have thought you could get tripped up by getting a FileHandle that is invalid, but you wouldn't know it till you get to the point that you use it. Though, I am clearly not familiar with IO API design in Haskel. :)
- dllthomas 12y agoIf something returns Maybe FileHandle, and it can't provide you a valid FileHandle, it'll provide Nothing (and if it can provide a valid FileHandle, it will provide "Just" that filehandle). Edited to add: Note that this can be the case in Haskell when you're relying on exceptions for error handling. That's the opposite approach from option types, though.
- taeric 12y agoIn my case, I thought the laziness could be more crazy, where you created a function that would evaluate to a FileHandle, but until you actually evaluate that function, you don't have a FileHandle. So, depending on just how "lazy" the program truly is, sure you passed it something that unwraps a Maybe, but only once you actually go to use it. That make sense? Consider this fun bit of nonsense scala def foo(x:=>String): Unit = { println("Hello") println(x) } If I call this as "foo(None.get)", then it will print "Hello" before barfing. In fact, if I didn't evaluate x, it wouldn't even barf. I had thought the laziness of Haskel was that ++. (Meaning I thought if I stored x off to another also lazy reference, it wouldn't barf right away.) To make that a little more clear of what I meant, some even more amusing scala. class Foo(x: => String) { def happy = println("Doing good.") def sad = println(x) } If I create something with "new Foo(None.get)", I can call happy on this object all day long. If I ever call sad, I get an exception.
- dllthomas 12y agoLaziness is a run time question. Nullability is a compile time question. Nullness, given nullability, is a run time question. Laziness in no way enters into this.
- taeric 12y agoSee my response upthread https://news.ycombinator.com/item?id=8007555 https://news.ycombinator.com/item?id=8007555. Basically, I was under the impression that it wouldn't actually unwrap the Maybe until you went to actually use it. I think I was just holding the laziness a little too magically. :)
- dllthomas 12y agoThat is essentially true, actually - it will be a thunk until you force it. That is the case whether or not Maybe is involved, though.
- taeric 12y agoI'm confused, then. Sounds like it can have obscure, "doesn't bite you immediately and appears far away from where the problem actually is," properties that were attributed to null. That is, at the point that a Maybe String statically changes to a String is not necessarily where the program will explode. A lot like a null assign. (Again, in a lazy language. Unless I'm mistaken on this subthread, the point was simply that you can still have that level of WTFery with Maybe that you can have with a null.)
- dllthomas 12y agoMaybe doesn't have to be involved at all. The point where the exception is raised is the point when the relevant thunk is forced. It is certainly the case that this can be problematic. This is an artifact of the intersection of laziness and IO, and there are methodological approaches (helped very much by libraries) to it, but it is a similar problem to nulls. Note that there are plenty of languages that are strict and provide an optional type - including Idris, I think, which is Haskell-like, dependently typed, and strictly evaluated.