3 ms·
Like nearly every time, empty string and 0 for integers can be treated the same as "no value" if you think about it. Are you sending data or sending opinions? U
by jakjak123 2y ago
Like nearly every time, empty string and 0 for integers can be treated the same as "no value" if you think about it. Are you sending data or sending opinions? Usually to force a choice, you would make a enum or a one-of where the zero-value means the client has forgotten to set it and it can be modelled as a api error. Whether the value was actually on the wire or not is not really that important.
- hot_gril 2y agoYeah, I think it's best to first rethink of null as just, not 0 and not any other number. What that means depends on the context. Tangent: I've seen an antipattern of using enums to describe the "type" of some polymorphic object instead of just using a oneof with type-specific fields. Which gets even worse if you later decide something fits multiple types.
- jakjak123 2y agoI love oneofs in the language with good support, but they are woeful in Golang and the "official" grpc-web message types.
- kortex 2y ago0 as a default for "no int" is tolerable, 0.0 as a default for "no float" is an absolute nightmare in any domain remotely related to math, machine learning, or data science. We dealt with a bug that for weeks was silently corrupting the results of trials pitting the performance of various algos against each other. Because a valid response was "no reply/opt out", combined with a bug in processing the "opt out" enum, also combined with a bug in score aggregation, functions were treated like they replied "0.0" instead of "confidence = None". It really should have defaulted NaN for missing floats.
- hot_gril 2y agoWhat about floats made this a problem? We're treating 0.0 specially in some places.
- jakjak123 2y agoI think your anecdote is rather weak with regards to the way protobuf works, but to entertain, why would a confidence of 0.0 be so different from None? 0.0 sounds very close to None for most numerical purposes if you ask me. Wait, are you using Python?
- sebastos 2y agomessage LatLon { double lat = 1; // Geodetic latitude, decimal degrees double lon = 2; // Geodetic longitude, decimal degrees } "Hmm, lat = 0, I guess they didn't fill out the message. I'll thrown an exception and handle it as an api error" [Later, somewhere near the equator] "?!?!??!" ------------------ "Ok, we learned our lesson from what happened to our customers in Sao Tome and Principe: 0.0 is a perfectly valid latitude to have. No more testing for 0, we'll just trust the value we parse. [Later, in Norway, when a bug causes a client to skip filling out the LatLon message] "Why is it flying to Africa?!?!" ------------------ Ok, after the backlash from our equatorial customers and the disaster in Norway, we've learned our lesson. We will now use a new message that lets us handle 0's, but checks that they really meant it: message LatLonEnforced { optional double lat = 1; optional double lon = 2; } [At some third party dev's desk] "Oh, latitude is optional - I'll just supply longitude" [...] "It's throwing exceptions? But your schema says it's optional!" ------------------ Ok, it took some blood sweat and tears but we finally got this message definition licked: message LatLonEnforced { optional double lat = 1; // REQUIRED. Geodetic latitude, decimal degrees optional double lon = 2; // REQUIRED. Geodetic longitude, decimal degrees } [Later, in an MR from a new hire] "Correct LatLon doc strings to reflect optional semantics"
- hot_gril 2y agoIf both lat and lon are required, you don't need to throw an exception for lat=0. If you want lat=null lon=0.0 to mean something like "latitude is unknown but longitude is known to be 0.0," yeah you need optional or wrapped primitives. Edit: If a client doesn't fill out the LatLng message, that's different from lat and/or lon being null or 0. The whole LatLng message itself will be null. Proto3 always supported that too. But it's usually overkill to check the message being null, unless you added it later and need to specially deal with clients predating that change. If the client just has a bug preventing it from filling out LatLng, that's the client's problem. The confusing part here is that even if the LatLng message is null, LatLng.lat will return 0 in some proto libraries, depending on the language. You have to specifically check if the message is null if you care. But there are enough cases where you have tons of nested protos and the 0-default behavior is actually way more convenient.