For programming languages, I agree with you. Though I don't really see how "int*" is different from "Optional<int>". You can write:
func foo(maybeInt *int) {
if maybeInt == nil { panic("not so optional!!!!") }
...
}
Just as easily as:
func foo(maybeInt Optional<int>) {
switch maybeInt {
case None:
panic("not so optional!!!!!")
...
}
}
To me, it just isn't a big deal. Your program is going to crash and return unexpected results when it expects something to exist and it doesn't, and the type system won't save you. (Even Haskell crashes at runtime when a pattern match doesn't resolve. Don't see how that's any different than a nil pointer dereference. Your live demo is ruined.)
For protocols,an Optional type just pushes the problem one level down. Is the optional value "None" because the client didn't know the field existed, or because they explicitly set it to "None"? You can't tell.
I think rather than going 3 levels deep, it's easier to just define the default values and not distinguish between these three cases. If you want an Optional value, you can make yours as complex as you wish:
message Optional {
int value = 1;
bool empty_because_the_user_said_so = 2;
bool client_has_version_of_proto_with_this_field = 3;
}
Now if you get (0, false, false), you know that's because the client is outdated. If you get (0, false, true), you know that's because the user didn't feel like sending a value. And if you get (0, true, true), you know the user wanted 0. (Of course, there are all the other cases that you have to handle -- what about (1, false, true), or (1, true, false)?)
I think you'll find that nobody but programming language purists want this feature. If your message is:
message FooRequest {
int foos_to_return = 1;
}
You do the right thing regardless of whether the 0 in foos_to_return is what the user wanted, something the user forgot to set, or the user has an old version of FooRequest ("message FooRequest{}").*