Great points and prompting some more philosophical thought :) Sam
On Fri, 10 Mar 2017 at 03:09 Kenton Varda <[email protected]> wrote: > On Thu, Mar 9, 2017 at 1:03 PM, Sam Duke <[email protected]> wrote: > > I find that many cases where I at first think I need field presence > actually make more sense as a union -- I find that, surprisingly often, > it's not just that the field is optional, but that there are several > different conceivable "modalities" of the struct, where the field only > makes sense in one of them. It's nice to encode this explicitly, and Cap'n > Proto can then reuse space in the struct for mutually-exclusive fields. > > > As mentioned, I'm coming more from the angle of writing defensively. I > might not ever *want* to communicate an 'unset' case, I just want to detect > it and fail gracefully, early and safely. (i.e. I would want to union wrap > EVERY primitive field) > > > Hmm. If your intent is to "fail" if the field isn't set, then you've made > a backwards-incompatible change to your protocol -- equivalent to defining > a whole new protocol entirely. The right way to detect this is for the > client to declare upfront what protocol (or protocol version) it is > expecting and for the server to fail if the protocol isn't supported. (E.g. > in HTTP you cat use the Content-Type and Accept headers for this sort of > negotiation.) > > Assuming the client has claimed it is speaking the correct protocol, I > would encourage you not to worry about whether the client has filled in > every "required" field. This is unnecessary error detection. Keep in mind > that a buggy client could just as easily fill in garbage values rather than > omit the values, and thus pass your checks while still sending invalid data. > Definitely this one. I'd certainly agree that you could have garbage values too. Presence checks are only the first layer of checks you might do. Checking the content itself is another layer beyond this. Self driving car example: Presence check: "Did you send me the number of cars in front of me?" No -> fail Presense check: "Did you send an action option?" No -> fail Data check: "Does the action option say to accelerate with > 0 cars in front of me?" Yes -> fail So, *if* you are only checking presence so that you can fail if the fields > aren't set, I'd say don't bother. Define default values and go with them. > Is it not that case that displaying or using default values as if they are truth is not always appropriate/safe? Having a potential 'default' flow through an application also creates additional work/thought to make sure it is still 'safe' or appropriate (and you need to think of all the combinations of default values that might occur). The "fail fast, fail early" philosophy is, IMHO, a safer approach. (hopefully it's clear this is just my current opinion and I'm not trying to say you are wrong, just maybe looking from the POV of a different type of application). As a general aside - protos/grpc/cap'nproto et al are attractive from the point of view of type safety and thoroughness. There are less mistakes to make in the contract. The contract is checked in. Changes to the contract likely cause compile time, rather than run-time, errors. The thoroughness/safety of these systems is what draws me to them (over speed/efficiency). > Also, note that boxing all your field values in their own structs would be > very inefficient. > Interesting, this probably also applies for Proto3 (wrappers.proto) > > -Kenton > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. Visit this group at https://groups.google.com/group/capnproto.
