[ 
https://issues.apache.org/jira/browse/THRIFT-2429?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13962575#comment-13962575
 ] 

Ben Sigelman commented on THRIFT-2429:
--------------------------------------

Using default values as a convenience is one thing (your first example). It's a 
matter of taste, and I don't really have any super-strong feelings. That said, 
I was at google for a while (perhaps too long!) working on core infrastructure, 
and default values were generally frowned upon, though certainly not forbidden 
or anything similar. I agree with your point about their convenience when 
adding a new field and supporting older peers (or older serialized data).

I could be missing something, but in the table you outlined 
[here|https://issues.apache.org/jira/browse/THRIFT-2429?focusedCommentId=13957788&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13957788],
 it seemed to suggest that optional fields set to their default value would not 
serialize. (When I said "the wire protocol", btw, I just meant "the wire" -- 
mea culpa on that front, this is certainly a protocol-independent discussion, 
as you observed!)

Given those proposed semantics, it is unsafe to change the default value in the 
future; it becomes as essential to the field as its tag number. Rather than a 
programming convenience (i.e., rather than what it was intended to be), it 
quite literally becomes part of the protocol...

E.g., using your example above, if the value of `y` is set, serialize it 
*unless* it's set to `5`, in which case *don't* serialize it. Now if we wish to 
change or remove the default in the future, if `y` isn't set in a serialized 
message, we can't be sure if it was actually intended to be un-set, or whether 
it was intended to be set to `5`.

I do applaud the effort to make these semantics well-defined, though. Here's 
what I'd propose:
- I like your "deserializer" table; no proposal on that front!
- I also like your treatment of required fields (i.e., always serialize)
- For optional field serialization: a default-constructed IDL-generated type 
initializes the optional field with its default value. The user then has the 
option to clear that field (i.e., un-set it) if they so choose, which would 
prevent it from serializing. Of course, if the optional field takes on a 
non-default value, it is serialized [surely we can all agree on that :)]. But 
if the optional field is (a) not cleared, and (b) set to its default value, it 
*is* serialized.

This allows the user of the thrift type to remove the default value in the 
future without creating uncertainty for all future readers of the optional 
field; which is what I'm principally concerned by.

I am admittedly baffled by the idea that "optional is an optimization", by the 
way. If that's a widely-held belief, then I should probably bow out of this 
discussion because I'm clearly missing too much context! I essentially never 
use `required` (when I was at google there was even a movement to ban 
`required`, as so many critical protocols had to swallow bitter pills when they 
realized required things weren't actually required after one migration or 
another), "opting" (pun!) for `optional` since it's harder to paint yourself 
into a corner with it. (Even if it requires more annoying boilerplate and 
validation in the layer above the protobuf/thrift/etc objects)

Anyway, those are my thoughts. I think this proposal is sensible/desirable(*) 
with the exception of the case I outlined above. I am ok with the fact that 
others will disagree, but I do want to make sure that I'm at least 
communicating the problem I'm concerned about. For my own projects, I just 
won't use default values :)   So I'm not personally going to be affected by 
this regardless.

Thanks for the clear and thoughtful response!
Ben

(*): I will admit to not-understanding the `-` case (not-optional, 
not-required). I know that it's historical, and I know I don't grok it... I am 
using thrift out of necessity due to the [poor] quality of protobuf bindings in 
one of my target languages, and I only ever tried to understand enough of 
Thrift to recreate what I got out of protobufs. Shame on me!

PS: I recognize that users (at fb or otherwise) may be clamoring for this (or 
whatever else). Users of infrastructure software sometimes unknowingly ask for 
things that will harm them in the long run; it is our job to understand their 
actual requirements and offer solutions that address them, but not necessarily 
to simply give them what they want in the immediate. This is especially true 
for things (like this default-optional thing) that have a "back-loaded" cost: 
e.g., in this case, the feature is incredibly convenient for the migration *to* 
the new field, yet equally painful for the migration away from it years later. 
The busy application developer is understandably more focused on the immediate 
need and thus suggests a feature without necessarily thinking through all of 
the implications. </sermon> I'm sure none of the above is controversial, but 
hearing the bit about this feature being "popular" prompted me to reiterate it 
:)

> Provide option to not write default values, rely on receiver default 
> construction instead
> -----------------------------------------------------------------------------------------
>
>                 Key: THRIFT-2429
>                 URL: https://issues.apache.org/jira/browse/THRIFT-2429
>             Project: Thrift
>          Issue Type: Improvement
>          Components: C++ - Compiler
>    Affects Versions: 0.9.1
>            Reporter: Chris Stylianou
>            Assignee: Randy Abernethy
>              Labels: default, optional, required
>
> Would there be any objections to a patch that does not write default values 
> (essentially the same logic as the optional attributes). This obviously 
> relies on the receiving application using the same IDL version to ensure the 
> defaults used on object construction match the senders.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to