<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Sep 5, 2017, at 2:58 PM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hey, all. In preparation for the several proposals we have to come this year, I <a href="https://github.com/apple/swift/pull/11742" class="">cleaned up docs/LibraryEvolution.rst</a> 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?<div class=""><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">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.<br class=""></blockquote><div class=""><br class=""></div>Interestingly, this means that you <i class="">can</i> 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.</div><div class=""><br class=""></div><div class="">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, <i class="">one</i> of them has to go first. There are two ways to do this: sort by name, and sort by declaration order. <b class="">That means we can <i class="">either</i> allow reordering <i class="">or</i> allow renaming, but not both</b>. Which do people think is more important?</div><div class=""><br class=""></div><div class="">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 <i class="">ABI</i>.</div></div></div></div></blockquote><div><br class=""></div>I think this is the right compromise to make. In addition to your points, I would add:</div><div> - Property ordering can significantly impact performance, both by changing the size of a struct and changing the locality characteristics of accesses to it.</div><div> - Performance tuning often happens throughout the development of a library, but it is quite common for renaming requests to land late, often as part of a final code/design review. Programmers would be quite surprised and dismayed if those changes invalidated most of their tuning.</div><div> - Even very complex layout algorithms are still more likely than not to place subsequent properties near to each other. To the extent that users cluster related properties that are accessed together — and I think they notably do — this will tend to improve locality. Ordering by property name is likely to produce something more like a random jumble.</div><div> - Reordering properties in the source code is a fairly simple and sensible way for an expert to influence the layout of a struct in a way that, practically speaking, can be combined with an easy-to-write layout-printing tool to yield total control over the layout, especially if there's an attribute to force Swift to use a specific layout algorithm. In contrast, as tempting as it is to say that Swift should allow an exact layout to be specified, that sounds like it'd be a horrific feature to actually use.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><div class="">(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.)</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">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.)</div><div class=""><br class=""><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Thanks!</div><div class="">Jordan</div></div></div></div></div></blockquote></div><br class=""></body></html>