Hi Jordan,

Okay, I just read the Library Evolution section about @fixedContents. Ya, the 
name of this attribute is difficult due to the collection of goals and subtle 
implications. I worry that others will find it difficult too, no matter what 
the name. :-/

I skimmed the rest of the document looking for any kind of list or graphic 
showing the spectrum of fragility tradeoffs (from fully non-fragile to fully 
fragile), but I didn’t see anything. Am I missing something? I’m trying to see 
the overarching vision of how all of these attributes fit and work together, 
and how a user would/should approach giving up some resiliency to gain 
efficiency.

Dave


> On Sep 6, 2017, at 14:18, Jordan Rose <jordan_r...@apple.com> wrote:
> 
> That's exactly why neither of those names are correct. The annotation we're 
> describing here means "the stored properties of this struct will not change, 
> please optimize". That gives us the actual fully-specified layout 
> optimizations when the contents happen to be non-generic and similarly 
> annotated, while still being useful for cases where the members are generic 
> or opaque. (For example, if a client library makes a Pair<MyLocalType>, the 
> client now fully understands the struct layout even if other libraries don't.)
> 
> All of this comes from the Library Evolution 
> <http://jrose-apple.github.io/swift-library-evolution/#fixed-contents-structs>
>  plan, which mentions (in a corner) more low-level promises 
> <http://jrose-apple.github.io/swift-library-evolution/#other-promises-about-types>
>  like "trivial". But these are things that I'd consider "hard mode" and not 
> worthy of focus.
> 
> Jordan
> 
> 
>> On Sep 6, 2017, at 11:08, David Zarzycki <zarzy...@icloud.com 
>> <mailto:zarzy...@icloud.com>> wrote:
>> 
>> I see. Would “@fixedSize” or “@abi(size)” be better names? In other words, 
>> the developer promises that whatever size the struct is now, it will be that 
>> way forever?
>> 
>> Also, wouldn’t the Pair<A> example below require that ‘A’ also be 
>> @fixedContents? Otherwise what does @fixedContents mean if the elements 
>> aren’t fixed?
>> 
>> Dave
>> 
>> 
>>> On Sep 6, 2017, at 13:44, Jordan Rose <jordan_r...@apple.com 
>>> <mailto:jordan_r...@apple.com>> wrote:
>>> 
>>> I don't think that's the right way to think about it either. It's purely an 
>>> optimization tool to say "I won't add anything else to this struct", which 
>>> means the compiler can avoid indirection when manipulating the struct 
>>> across module boundaries. We could implement it with dynamic offset symbols 
>>> and still see some benefit, but in this case we really ought to be able to 
>>> get all the way to C-level performance.
>>> 
>>> The name hasn't been formalized; this will all go through swift-evolution 
>>> at some point. We thought about "fixed-layout" in the past, but that 
>>> doesn't have the right connotations for something like Pair:
>>> 
>>> @fixedContents
>>> public struct Pair<A> {
>>>   public var first: A
>>>   public var second: A
>>>   public init(first: A, second: A) { … }
>>> }
>>> 
>>> This has known properties, but the layout depends on the generic argument, 
>>> and if the generic argument is itself a type with unknown size then the 
>>> actual layout won't be known until runtime.
>>> 
>>> Jordan
>>> 
>>> 
>>>> On Sep 6, 2017, at 10:40, David Zarzycki <zarzy...@icloud.com 
>>>> <mailto:zarzy...@icloud.com>> wrote:
>>>> 
>>>> Ah, now that I see the CGPoint example, I understand. Thanks! Ya, the 
>>>> “hard” user-experience model I brought up feels wrong for CGPoint, etc. 
>>>> (For non-Apple people, CGPoint is a struct of two doubles on 64-bit 
>>>> machines add two floats on 32-bit machines.)
>>>> 
>>>> It wasn’t obvious to me from context that @fixedContents wasn’t / isn’t 
>>>> for people trying to design a comprehensive ABI (disk, wire, etc), but 
>>>> just the machine specific in memory ABI. I wish the name was better, but 
>>>> nothing better seems obvious. (“@inMemoryABI”?)
>>>> 
>>>> Dave
>>>> 
>>>>> On Sep 6, 2017, at 13:11, Jordan Rose <jordan_r...@apple.com 
>>>>> <mailto:jordan_r...@apple.com>> wrote:
>>>>> 
>>>>> I'd be okay with allowing the ABI attributes to control ordering, but I 
>>>>> would definitely not require them on every fixed-contents struct. We hope 
>>>>> making a struct fixed-contents isn't something people have to do too 
>>>>> often, but we don't want to drop them all the way into "hard" land when 
>>>>> they do it. That is, "CGPoint" can't already be "hard mode".
>>>>> 
>>>>> Jordan
>>>>> 
>>>>> 
>>>>>> On Sep 6, 2017, at 05:13, David Zarzycki <zarzy...@icloud.com 
>>>>>> <mailto:zarzy...@icloud.com>> wrote:
>>>>>> 
>>>>>> Hi Jordan,
>>>>>> 
>>>>>> I really doubt that “belt and suspenders” ABI attributes would drive 
>>>>>> people to C, but reasonable people can certainly disagree on that.
>>>>>> 
>>>>>> Bertrand, when he was at Apple, used to say that “easy things should be 
>>>>>> easy, and hard things should be possible”.
>>>>>> 
>>>>>> I think ABI related attributes fall into the latter category. In 
>>>>>> particular, I think that trying to make ABI attributes too convenient 
>>>>>> only does programmers a disservice in the long run because most 
>>>>>> programmers aren't experts, and the cost of ignorance is huge when 
>>>>>> trying to do ABI design.
>>>>>> 
>>>>>> With these thoughts in mind, I think that is reasonable for the language 
>>>>>> to say: “If you want explicit control over a dimension of ABI decisions, 
>>>>>> then you must deal with all of the associated complexity. Here is a 
>>>>>> pointer to the documentation on dimension X that you were/are trying to 
>>>>>> explicitly manage. If that is ’too hard’ for you, then you probably 
>>>>>> shouldn’t be locking down this dimension of complexity yet.”
>>>>>> 
>>>>>> Dave
>>>>>> 
>>>>>>> On Sep 5, 2017, at 20:11, Jordan Rose <jordan_r...@apple.com 
>>>>>>> <mailto:jordan_r...@apple.com>> wrote:
>>>>>>> 
>>>>>>> Hm. This is definitely an option, but I don't think it's really an 
>>>>>>> acceptable user experience. This feels like it'll drive people all the 
>>>>>>> way to declaring their types in C because Swift makes it too hard.
>>>>>>> 
>>>>>>> We do expect to have a tool to diff old and new modules at some point, 
>>>>>>> but we could do something even simpler here: make a public symbol with 
>>>>>>> the struct's layout in its name. That way, even 'nm' can tell if the 
>>>>>>> symbol disappears. (Of course, public symbols do have a small cost, 
>>>>>>> since this might not actually be the best idea.)
>>>>>>> 
>>>>>>> Another idea would be to restrict @fixedContents to require that all 
>>>>>>> stored properties appear contiguously in the struct, possibly even 
>>>>>>> pinned to the top or bottom, to indicate that order's not completely 
>>>>>>> arbitrary. Again, that's just an improvement, not full protection.
>>>>>>> 
>>>>>>> Jordan
>>>>>>> 
>>>>>>> 
>>>>>>>> On Sep 5, 2017, at 13:00, David Zarzycki <zarzy...@icloud.com 
>>>>>>>> <mailto:zarzy...@icloud.com>> wrote:
>>>>>>>> 
>>>>>>>> Hi Jordan,
>>>>>>>> 
>>>>>>>> Thanks for thinking about this. For whatever it may be worth, I’m 
>>>>>>>> concerned about 1) the ability to reorder declarations and 2) the 
>>>>>>>> “either/or” nature of this proposal.
>>>>>>>> 
>>>>>>>> First, reordering: The ability to reorder declarations is deeply 
>>>>>>>> ingrained into the subconsciousness of Swift programmers and for good 
>>>>>>>> reasons. I think adding localized declaration order sensitivity is 
>>>>>>>> likely to be very brittle and regrettable in the long run. I also 
>>>>>>>> think this problem is made worse by having a type declaration context 
>>>>>>>> attribute because it can easily get lost in the noise of nontrivial 
>>>>>>>> declarations. The net result is that people will frequently forget 
>>>>>>>> about local order sensitivity. Yes, the compiler can engage in heroics 
>>>>>>>> and compare the previous module ABI and the new module ABI for 
>>>>>>>> conflicts, but that seems risky, complex, slow, and differently error 
>>>>>>>> prone.
>>>>>>>> 
>>>>>>>> Second, the “either/or” nature of this proposal: What do you think 
>>>>>>>> about a lightweight “belt and suspenders” solution whereby 
>>>>>>>> @fixedContents requires that stored properties be lightly annotated 
>>>>>>>> with their layout order? For example:
>>>>>>>> 
>>>>>>>> @fixedContents(3) struct Foo {
>>>>>>>>   @abi(0) var x: Int
>>>>>>>>   func a() {
>>>>>>>>     // a thousand lines of ABI layout distraction
>>>>>>>>   }
>>>>>>>>   @abi(1) var y: Double
>>>>>>>>   func b() {
>>>>>>>>     // another thousand lines of ABI layout distraction
>>>>>>>>   }
>>>>>>>>   @abi(2) var z: String
>>>>>>>> }
>>>>>>>> 
>>>>>>>> That would enable both renaming and reordering, would it not? This 
>>>>>>>> approach would also aid the compiler in quickly detecting hastily 
>>>>>>>> added/deleted declarations too because the count of @abi([0-9]+) 
>>>>>>>> declarations wouldn’t match the number passed to @fixedContents.
>>>>>>>> 
>>>>>>>> Dave
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On Sep 5, 2017, at 14:59, Jordan Rose via swift-dev 
>>>>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>>>>> 
>>>>>>>>> Hey, all. In preparation for the several proposals we have to come 
>>>>>>>>> this year, I cleaned up docs/LibraryEvolution.rst 
>>>>>>>>> <https://github.com/apple/swift/pull/11742> a little bit based on 
>>>>>>>>> what's changed in Swift 4. This is mostly just mentioning things 
>>>>>>>>> about generic subscripts, but there is one issue that I remember John 
>>>>>>>>> bringing up some time in this past year: once you've made a struct 
>>>>>>>>> fixed-contents, what can you change about its stored properties?
>>>>>>>>> 
>>>>>>>>>> To opt out of this flexibility, a struct may be marked 
>>>>>>>>>> '@fixedContents'. This promises that no stored properties will be 
>>>>>>>>>> added to or removed from the struct, even non-public ones.
>>>>>>>>> 
>>>>>>>>> Interestingly, this means that you can have non-public members of a 
>>>>>>>>> fixed-contents struct. This is actually pretty sensible: it's the 
>>>>>>>>> equivalent of a C++ class with non-public fields but a defaulted, 
>>>>>>>>> inlinable copy constructor. Any inlinable members can access these 
>>>>>>>>> properties directly as well; it's just outsiders that can't see them. 
>>>>>>>>> But if inlinable code can reference these things, and if we really 
>>>>>>>>> want them to be fast, that means they have to have a known offset at 
>>>>>>>>> compile-time.
>>>>>>>>> 
>>>>>>>>> Now, we don't plan to stick to C's layout for structs, even 
>>>>>>>>> fixed-contents structs. We'd really like users to not worry about 
>>>>>>>>> manually packing things into trailing alignment space. But we still 
>>>>>>>>> need a way to lay out fields consistently; if you have two stored 
>>>>>>>>> properties with the same type, one of them has to go first. There are 
>>>>>>>>> two ways to do this: sort by name, and sort by declaration order. 
>>>>>>>>> That means we can either allow reordering or allow renaming, but not 
>>>>>>>>> both. Which do people think is more important?
>>>>>>>>> 
>>>>>>>>> At the moment I'm inclined to go with "allow renaming" just because 
>>>>>>>>> that's what C does. It's not great because you're allowed to reorder 
>>>>>>>>> nearly everything else in the language, but there's a "least 
>>>>>>>>> surprise" principle here that I think is still useful. It'd be 
>>>>>>>>> surprising for the name of a non-public property to affect your 
>>>>>>>>> library's ABI.
>>>>>>>>> 
>>>>>>>>> (In theory we could also make different decisions for public and 
>>>>>>>>> non-public fields, because it's much less likely to want to change 
>>>>>>>>> the name of a public property. But you could do it without breaking 
>>>>>>>>> source compatibility by introducing a computed property at the same 
>>>>>>>>> time as you do the renaming. It's up to us whether that should break 
>>>>>>>>> binary compatibility or not.)
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Note that because the layout algorithm isn't public, Swift isn't 
>>>>>>>>> going to allow the thing from C where you have an existing field and 
>>>>>>>>> you split it into two smaller fields. You can use computed properties 
>>>>>>>>> for that instead. (Strictly speaking this probably isn't even good C 
>>>>>>>>> because the fields in your struct can affect by-value calling 
>>>>>>>>> conventions.)
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> By the way, I'm putting this on swift-dev because we're nowhere near 
>>>>>>>>> a proposal and I want to keep the discussion narrow for now, but of 
>>>>>>>>> course this point will be called out when the fixed-contents 
>>>>>>>>> attribute—whatever its final form—goes to swift-evolution for a 
>>>>>>>>> proper review.
>>>>>>>>> 
>>>>>>>>> Thanks!
>>>>>>>>> Jordan
>>>>>>>>> _______________________________________________
>>>>>>>>> swift-dev mailing list
>>>>>>>>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to