12

Swift has Optionals. C# has Nullable types.

As far as I can tell both serve same purpose, besides value of some type they store information whether variable has value or is undefined (uninitialized).

Question is are Optionals just Nullable types with different name or are there other conceptual differences?

In another words, talking about concept itself, or in context of languages that do not have Optionals or Nullables, does it matter whict term is used?

When implementing that functionality in language does it matter whether I name type Optionals<T> or Nullable<T>

  • From a language agnostic viewpoint, they are identical. That said, a language may differentiate the concepts (e.g. Whether or not pattern matching is enforced). – Thomas Eding Feb 2 '15 at 9:33
  • C# can have Options too (it's just a monadic pattern): github.com/louthy/language-ext – Den Feb 2 '15 at 11:59
  • 2
    Using a null reference (or a NULL pointer, in languages with pointers) is a hack that some languages use to represent optional values, i.e. a container that may have one value or no value at all. This has the limitation that you can only consider optional a type that is based on references (or pointers). So, e.g., in Java you cannot make an integer optional without wrapping it in an object (e.g. Integer). Other languages provide optional types as generic types that can wrap any other type, e.g. Maybe in Haskell, Option in Scala, and so on. – Giorgio Feb 2 '15 at 13:33
5

There is a different connotation, even though they work very similarly. Everyone but Microsoft (insert eye-roll here) uses null and nullable only in the context of references. Options and Maybes are generally understood to refer to both references and values, especially in functional programming languages where referential transparency means there isn't much difference between a value and a reference.

In another words, talking about concept itself, or in context of languages that do not have Optionals or Nullables, does it matter which term is used?

Options is the term that causes the least confusion among a broad audience. Only C# programmers will think of a Nullable as potentially applying to a value type, and I think most of them are at least aware of what an Option is.

  • Everyone but Microsoft and the designers of SQL, I think you mean. – Jules Feb 2 '15 at 20:56
9

In .NET, there are two categories of type: references and values (int, double, structs, enums etc). Amongst their differences is the fact that a reference can be null, whereas a value cannot. Thus if you have a value type and want to convey "optional" or "unknown" semantics, you can adorn it with Nullable<>. Note that Nullable<> is constrained by type to accept only value types (it has a where T : struct clause). Nullable<> also has special affordances from the compiler whereby a null value is protected from NullReferenceExceptions:

string x = null;
x.ToString(); // throws a NullReferenceException

int? y = null;
y.ToString(); // returns ""

In functional languages (such as Scala, F#, Haskell, Swift etc) it is common for null to not exist. This is because on the whole people regard the existence of null as a bad idea, and language designers have decided to address this problem by disallowing it.

This means that again we need some way to represent a non-value in these languages. Enter the Option type (nomenclature varies, it's called Maybe in Haskell). This does a similar job to Nullable in that it wraps a type to add the case where the value is "None" or "Unknown" etc.

The real difference is in the extra functions given to you by languages that implement Option. As an example, take Option.map (in pseudocode):

function Option<T2> Option.map(opt: Option<T1>, mapFunc: T1 -> T2) {
    if (opt is None) return None
    else return Option<T2>(mapFunc(opt.Value))
}

Chaining functions like Option.map is a powerful way to avoid the typical null check boilerplate you see everywhere in C#:

if (service == null)
    return null;
var x = service.GetValue();
if (x == null || x.Property == null)
    return null;
return x.Property.Value;

The Nullable equivalent in C# would be:

public static Nullable<T2> Map<T1, T2>(this Nullable<T1> nullable, Func<T1, T2> f)
    where T1 : struct
    where T2 : struct
{
    if (!nullable.HasValue) return (T2?)null;
    else return (T2?) f(nullable.Value);
}

However this has limited utility in C# because it will only work for value types.

The new version of C# offers the "null propagation" operator (?.) which is similar to the Option.map function except it is only applicable for methods and property accessors. The above sample would be rewritten

return service?.GetValue()?.Property?.Value;
  • C# is an impure functional language (just as F#). Also F# has nulls. – Den Feb 2 '15 at 11:52
  • C# 6 has null value coercion, so at least some of your code is not up to date: github.com/dotnet/roslyn/wiki/… roslyn.codeplex.com/discussions/540883 – Den Feb 2 '15 at 11:54
  • Also Options are easy to implement: github.com/louthy/language-ext – Den Feb 2 '15 at 11:57
  • 1
    @Den: C# leans towards OOP while F# leans towards FP. Lack of currying and mutability by default means C# is not appropriate for serious functional programming. I mentioned null propagation at the end of the answer. Options are indeed simple to implement in C# but that strays from the question. – AlexFoxGill Feb 2 '15 at 12:04
  • 4
    @Den I think there's some poor choice of words in your comments. An impure functional language is a functional language that allows side effects. C# may have some functional features and you can use them to great effect, but it's not a functional language. I guess you meant that neither language is 100% functional, but F# is very close to OCaml which is by most accounts a functional language. Whatever deviations it makes from the functional paradigm mostly exist so it can interoperate with foreign .NET code. Case in point, null is not a valid value for F# types. – Doval Feb 2 '15 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.