> On Jul 22, 2017, at 3:02 PM, Chris Lattner <clatt...@nondot.org> wrote:
> 
> On Jul 18, 2017, at 1:00 PM, Daryle Walker via swift-evolution 
> <swift-evolution@swift.org> wrote:
>>> On Jul 17, 2017, at 3:26 AM, Félix Cloutier <felix...@yahoo.ca> wrote:
>>> 
>>> 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.
>> 
>> The person with the initial suggestion regrets this habit and deliberately 
>> doesn’t want it. In other words, don’t support the waste of cycles to 
>> pre-initialize just for the elements to be immediately paved over with the 
>> real initial data. And we may make arrays of types that are heavy to 
>> initialize and may not have a default initializer, so even using a 
>> default-value term at declaration will lead to a big waste of cycles.
>> 
>> We eventually have to decide how to modify deterministic initialization. Do 
>> we take the safe path with dynamic deterministic initialization (and add 
>> extra resources)? Or the fast path with suspension of checks (and risk 
>> undefined behavior)? We’re probably going to lean toward the former, 
>> especially since we can limit its scope (and therefore cost).

Oh, I just posted that I just updated my proposal before I saw this in my 
in-box.

> In my opinion, there is an easy three step plan :-) to solving this problem, 
> riffing on Array:

Well, fixed-size arrays don’t have initializers, for the same reason tuples 
don’t: they’re compound types instead of named types and they literally have 
nowhere to place initializer definitions. But like tuples, FSAs have a literal 
syntax that works as a substitute for full-blown initializers. My recent update 
made FSA-literals distinct from standard array literals.

Should there be an equivalent to “ExpressibleByArrayLiteral” for 
multi-dimensional literals? I don’t know, but it could wait for version 2.

> 1) Fixed size arrays should have an initializer to init all the elements to 
> some concrete value.

let a = [4; default: “whatever”]  // [4; String]

> 2) They should have an init that takes a closure, and runs it once per 
> element, passing in the index.

let b = [2, 3; func: { Double($0.0 * $0.0 + $0.1 * $0.1) }]  // [2, 3; Double]

The index, “$0” here, is passed as “[2; Int]”.

> 3) Either through a magic value or a third initializer, it should be possible 
> to *explicitly* create a fixed size array with uninitialized garbage for the 
> elements.  This is important for specific optimizations, and should also come 
> to Array as well.

let c = [6; 1, 2, 3]  // [6; Int], last 3 elements uninitialized

Obviously, the literal can’t use a “default” or “func” term if you want to keep 
some elements uninitialized.

Leaving elements uninitialized is a big reason for leaving FSAs compound types. 
We should not violate the expectation that an initializer (which named types 
have) leaves all sub-objects initialized. So I’m against adding this feature to 
Array, unless you mean something like “size” vs. “capacity” in C++’s vector and 
you need to call something like “push_back” to add an element instead of 
directly using subscript. Since a FSA is a compound type, its sub-objects’ 
states are tracked with deterministic initialization, just like tuple members.

> IMO, it isn’t a problem that C allows arrays to be uninitialized - the 
> problem is that it is a really bad default.

I was struggling which way to go; add run-time deterministic initialization or 
allow undefined behavior. For now, it’s neither; the current compile-time 
deterministic initialization has to be followed. But compile-time DI isn’t big 
a setback as long as you have all the information you need to set every element 
before initialization-assignment (with a function term).

I read a post once wishing for a function to join tuples together as a giant 
tuple. I was wondering about the same thing for FSAs, where you have to specify 
which index you want to be the axis of the join (and all the non-axis 
dimensions have to have corresponding lengths being equal). This requires more 
advanced generics than we have now; but if implemented, we could build arrays 
in piecemeal then join them together for the final value. It could look like:

let d = joinArrays<2>( [2, 3, 7, 5, 9; default: 23], [2, 3, 4, 5, 9; func: { 
$0.0 + $0.4 }] )  // [2, 3, 11, 5, 9; Int], axis 2: 7 + 4 == 11

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

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

Reply via email to