I think that you're getting ahead of yourself. Fixed-size arrays are still 
useful even if they have to have been demonstrably initialized before you can 
use dynamic indices with them. A ton of people have already gotten into the 
habit of writing `int foo[40] = {}` in C.

I would like to encourage you to exercise your sense of priority and figure out 
the minimum changes that you need to make to the language to get something 
useful, without blocking avenues for expansion. I think that everyone, 
especially the people that you would be signing up for a tremendous amount of 
work with your current direction, will be happier this way.

> Le 16 juil. 2017 à 15:18, Daryle Walker via swift-evolution 
> <swift-evolution@swift.org> a écrit :
>> On Jul 13, 2017, at 1:41 PM, Daryle Walker via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> As I understand it, Definitive Initialization means the Swift compiler will 
>> make sure an instance is fully initialized before the first attempt to read 
>> it. It does not require mandatory assignment at declaration; an instance can 
>> be declared with no initializer and receive an assignment at a later point.
>> * Class and structure types are considered OK by DI when an initializer is 
>> called.
>> * Enumerations can either use an initializer or have an enumeration-case 
>> assigned for DI.
>> * Compound types (function pointers and tuples) use assignment (possibly at 
>> declaration) for DI.
>> * Tuples can also have the individual members can be tracked for DI. A 
>> member has to be initialized by the time that member or the entire tuple is 
>> read (whichever comes first).
>> Tuples (and the other types) can statically determine when a sub-object is 
>> initialized. When adding a new member, via new text in the source code, a 
>> corresponding new line(s) of code has to be added during the initialization 
>> sequence. But built-in arrays, no matter how they’re defined, would be 
>> different. The whole point of arrays is to allow adjustment the number of 
>> sub-objects without per-sub-object alteration to the array type’s 
>> declaration code. That means you can’t write out all the member 
>> initializations in advance (in general). And that means you generally use a 
>> loop and subscripting instead. And since that moves the references to which 
>> elements get initialized to run-time, we have a fundamental incompatibility 
>> with definitive initialization. (The fixed-size array proposal I recently 
>> posted about does have a static indexing mode, but the point I’m making here 
>> is that it doesn’t scale from the perspective of the regular array 
>> interaction model.)
>> Besides banning fixed-size arrays forever and ever (which just hides the 
>> problem), we’re limited to:
>> * Mandatory assignment at declaration, and the initializing expression has 
>> to cover all elements
>> * If arrays keep a static indexing mode, apply DI to an array instance using 
>> that. This would mean changing the initialization sequence code every time 
>> the number of elements is adjusted. And the initialization would have to be 
>> from the static indexing mode for DI to recognize it (i.e. always “a.0 = 4”, 
>> no “a[0] = 4”) Note that if we gain an equivalent to C++’s constexpr, then 
>> static indexing mode could be spelled with the subscript operation.
>> * For each array instance not initialized on declaration, define a secret 
>> extra Boolean-array object that keeps the initialization state of each 
>> element of the first array. Of course, this means tracking each element read 
>> and raising a run-time error if not initialized first.
>> * Something I haven’t considered.
>> If anyone from the original Swift team is around: is this why you didn’t add 
>> fixed-size arrays at the start? (Or did you just forget?) I don’t think you 
>> missed a way to link FSAs to DI; the two are just incompatible (if you want 
>> to keep the way most people use arrays).
>> So I’m asking for either some way to make FSAs and DI work together that I 
>> missed. Or start a discussion on how undefined behavior on 
>> uninitialized-data reads should work on compiler, ABI, and run-time levels.
> Right now, my solution is run-time deterministic initialization, but only to 
> fixed-size arrays that are either local objects or stored instance 
> properties. Other instances require the array to be initialized in one shot. 
> To segregate code initializing an array, a special attribute suspends the 
> full initialization requirement in function arguments.
> Deterministic Initialization at Run-time
> For each local object of a fixed-size array type that is not fully 
> initialized at declaration and has at least one call to its subscript method 
> and/or used as a fragmentary argument, there shall be a secret map object 
> indicating which elements of the array have been initialized. When an element 
> is initialized, either statically or dynamically, the corresponding flag in 
> the initialization map shall be set. When an element is read statically or 
> dynamically, the flag is checked before access, and a run-time error shall be 
> triggered if the element has not been yet initialized. (The check can be 
> elided if the element’s initialization and access were both static.) The same 
> triggering occurs if the array as a whole is read and at least one element is 
> uninitialized, unless the array’s access is being passed as a function 
> argument with the corresponding parameter having the “fragmentary” attribute.
> (An array that does not need run-time deterministic initialization checks 
> still has the compile-time ones for it and its sub-objects, just like tuples.)
> For each stored instance property of a fixed-size array type declared without 
> a full initialization, then an element initialization map is made for that 
> property at the start of each designated initializer. The properties’ 
> elements’ initializations are confirmed like for local arrays, with the 
> addition of a run-time error gets triggered if the initializer finishes with 
> at least one property element still uninitialized. (The map is elided for a 
> property if all access to its elements is static. Compile-time deterministic 
> initialization still applies.)
> Global fixed-size arrays and stored type properties of fixed-size array type 
> must have their initializations done in one shot (i.e. let compile-time 
> deterministic initialization work).
> The “fragmentary” type attribute can only be applied to a parameter’s type in 
> a method or function declaration, where the parameter is of a fixed-size 
> array type and also marked with “inout”. It makes the array argument be 
> passed by reference instead of copy, and be secretly accompanied by an in-out 
> (or by-reference) object representing which elements of the array are already 
> initialized. If an element is accessed for reading when the initialization 
> map indicates that it hasn’t been initialized, a run-time error occurs. When 
> an element is written to, the corresponding element in the initialization map 
> is set to TRUE; the updates are sent back out through the secret map 
> argument. When a function with a parameter with this attribute is called, the 
> corresponding array is passed as the explicit argument and the element 
> initialization map is passed as the secret argument. If the array argument 
> does not have a map, like if it was fully initialized statically already, 
> then an equivalent with indicators that all elements are initialized shall be 
> passed.
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
swift-evolution mailing list

Reply via email to