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