The important thing here is not that passing onOK and onError callbacks is a good idea. The real issue is that NULL pointers are the most dangerous thing invented in the 20th century and should be avoided like the plague.
From an [expression problem](http://c2.com/cgi/wiki?ExpressionProblem) point of view using a discriminated union (in the same spirit as returning null but safer, since you can you peek at the value after doing a null check) would probably be just fine anyway. You still get to avoid the danger of NULL pointers but you still get a real value to work with (unlike the callback case that allways immediately splits it) so you can store it, pass it around, etc.
That talk gets quoted pretty often, but it's a bit silly for Hoare to take all the blame/credit. Null references were discovered, not invented. They are so easy (from the point of view of someone implementing a non-functional language) that they were inevitable.
From an [expression problem](http://c2.com/cgi/wiki?ExpressionProblem) point of view using a discriminated union (in the same spirit as returning null but safer, since you can you peek at the value after doing a null check) would probably be just fine anyway. You still get to avoid the danger of NULL pointers but you still get a real value to work with (unlike the callback case that allways immediately splits it) so you can store it, pass it around, etc.
By the way, astute readers might have recognized all that callback passing as just the [visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) in disguise.