While creating a client for a web API in C#, I ran into a problem regarding null as a value where it would represent two different things:nothing, e.g. a foo may or may not have a barunknown: by default the API response only includes a subset of properties, you have to indicate which additional properties you want. So unknown means that the property was not requested from the API.After some searching I found out about the Maybe (or Option) type, how it's used in functional languages and how it solves null dereferencing problems by forcing the user to think about the possible absence of a value. However, all of the resources I encountered talked about replacing null with Maybe. I did find some mentions of three-valued logic, but I don't fully understand it and most of the times its mentioning was in the context of it's a bad thing.I'm now wondering if it makes sense to have both the concept of null and Maybe, to represent unknown and nothing respectively. Is this the three-valued logic I read about, or does it have another name? Or is the intended way to nest a Maybe in a Maybe?
Does it make sense to have both the concept of 'null' and 'Maybe'?
programming languages;language design
The null value as a default present everywhere is just a really broken idea, so forget about that.You should always have exactly the concept that best describes your actual data. If you need a type which indicates unkown, nothing, and value, you should have precisely that. But if it does not fit your actual needs then you should not do it. It is a good idea to see what other people use and what they have proposed, but you do not have to follow them blindly.People who design standard libraries try to guess common usage patterns, and they usually do it well, but if there's a specific thing you need, you should define it yourself. For instance, in Haskell, you could define:data UnknownNothing a =     Unknown   | Nothing   | Value aIt may even be the case that you should be using something more descriptive that is easier to remember:data UserInput a =     Unknown   | NotGiven   | Answer aYou could define 10 such types to be used for different scenarios. The drawback is that you won't have available pre-existing library functions (such as those of Maybe), but this usually turns out to be a detail. It's not that hard to add your own functionality.