[swift-evolution] Improved value and move semantics

Dave Abrahams dabrahams at apple.com
Wed Aug 3 23:15:29 CDT 2016


on Wed Aug 03 2016, Chris Lattner <clattner-AT-apple.com> wrote:

>> On Aug 3, 2016, at 8:46 PM, Chris Lattner via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> 
>> On Aug 3, 2016, at 7:57 PM, Joe Groff <jgroff at apple.com> wrote:
>>>>>> 
>
>>>>>> a. We indirect automatically based on some heuristic, as an
>>>>>> optimization.
>>>> 
>>>> I weakly disagree with this, because it is important that we
>>>> provide a predictable model.  I’d rather the user get what they
>>>> write, and tell people to write ‘indirect’ as a performance tuning
>>>> option.  “Too magic” is bad.
>>> 
>>> I think 'indirect' structs with a heuristic default are important
>>> to the way people are writing Swift in practice. We've seen many
>>> users fully invest in value semantics types, because they wants the
>>> benefits of isolated state, without appreciating the code size and
>>> performance impacts. Furthermore, implementing 'indirect' by hand
>>> is a lot of boilerplate. Putting indirectness entirely in users'
>>> hands feels to me a lot like the "value if word sized, const& if
>>> struct" heuristics C++ makes you internalize, since there are
>>> similar heuristics where 'indirect' is almost always a win in Swift
>>> too.
>> 
>> I understand with much of your motivation, but I still disagree with your conclusion.
>
> ^I understand and agree with much of your motivation...
>
> -Chris
>
>>  I see this as exactly analogous to the situation and discussion
>> when we added indirect to enums.  At the time, some argued for a
>> magic model where the compiler figured out what to do in the most
>> common “obvious” cases.
>> 
>> We agreed to use our current model though because:
>> 1) Better to be explicit about allocations & indirection that implicit.  
>> 2) The compiler can guide the user in the “obvious” case to add the
>> keyword with a fixit, preserving the discoverability / ease of use.
>> 3) When indirection is necessary, there are choices to make about
>> where the best place to do it is.
>> 4) In the most common case, the “boilerplate” is a single “indirect”
>> keyword added to the enum decl itself.  In the less common case, you
>> want the “boilerplate” so that you know where the indirections are
>> happening.
>> 
>> Overall, I think this model has worked well for enums and I’m still
>> very happy with it.  If you generalize it to structs, you also have
>> to consider that this should be part of a larger model that includes
>> better support for COW.  I think it would be really unfortunate to
>> “magically indirect” struct, when the right answer may actually be
>> to COW them instead.  

COW'ing the struct is implied by indirecting it.  You're not allowed to
break its value semantics just because it's being stored indirectly, and
we're darned sure not going to introduce an eagerly copied box there; I
think we all agree that the eager boxes we currently have must evolve
into COWs before ABI stability sets in.

>> I’d rather have a model where someone can use:
>> 
>> // simple, predictable, always inline, slow in some cases.
>> struct S1 { … }  
>> 
>> And then upgrade to one of:
>> 
>> indirect struct S2 {…}
>> cow struct S3 { … } 
>> 
>> Depending on the structure of their data.  In any case, to
>> reiterate, this really isn’t the time to have this debate, since it
>> is clearly outside of stage 1.

Well, I don't want to draw it out either, but I do want to add one
point: the “predictable performance” argument rings pretty hollow for
me.  There are already hard-to-anticipate performance cliffs wherever we
have an inline buffer (e.g. existentials), an opportunity for stack
promotion, or where we mutate a COW data structure that might turn out
to have non-uniquely-referenced storage.  All of these effects add up to
code that performs well without too much intervention in most cases. We
should continue to make Swift perform well automatically, and give
people the tools they need to make adjustments when profiling reveals an
issue.

-- 
-Dave


More information about the swift-evolution mailing list