Hacker News new | ask | show | jobs
by sshine 1464 days ago
Yes, I'd have an enum with Yes, No and Unset.

Many languages have a typed "no value" value that is composable with other types: Maybe<T>, Option<T>, Nullable<T>.

In other situations I might have an Option<Yes, No>, i.e. when I want a non-null value to indicate that it isn't Yes or No. The reason why I don't want a null, in general, is that it's the billion dollar mistake:

https://hackernoon.com/null-the-billion-dollar-mistake-8t5z3...

But if the user can actually choose "Unset", then that's a choice, too.

"Unset" might, for example, have implications that other null-ish answers don't have in the future.

As for SQL: I might go for a NULL for performance, knowing that if another neither-yes-or-no option with different implications came, I might have to migrate the NULLs.

1 comments

When the final record should have either Yes or No, but the there is an intermediate state where the answer could be missing, you want something like a Maybe<Bool> which you can map to a simple Bool as part of validation. Ideally you'd use a functor-style parameter for this, for example in Haskell:

  data Record f = Record { …, someField ∷ f Bool, … }
  type PartialRecord = Record Maybe
  type CompleteRecord = Record Identity

  getCompletedRecord ∷ PartialRecord → Maybe CompleteRecord
  getCompletedRecord (Record { …, someField, … }) =
    Record <$> … <*> (Identity <$> someField) <*> …
This way you can define your record type once and handle all the missing fields in a uniform way, and functions can easily indicate whether they expect a partial record full of Maybes or a complete record with no potentially missing fields. You can use the same type definition for other things, too, by substituting different functors in place of Maybe or Identity. For example, `Record ToString` where `ToString a` is a newtype over `(a → String)` could be a record of functions describing how to render each field as a string.

In the DB you would need to store incomplete records in a separate table, since they have different validation rules. Queries against the main table should be able to assume that all the records are complete.