[swift-evolution] [Pitch] New Version of Array Proposal

Tino Heth 2th at gmx.de
Thu Aug 3 06:20:51 CDT 2017

Hi Daryle,

I think we agree a lot on the importance of fixed-size arrays, but have a different opinion on which aspect is the most valuable… (so we now only have to agree that mine is better ;-) ;-)
My motivation for FSA is safety and convenience:
I want to iterate over C arrays in a straightforward way, but primarily, I don't want to accidentally multiply a vector of size 3 with a 2×2 matrix.
Of course, fast is cool, but I don't expect to suffer from bad performance because of implementation details like how, where and when memory allocation happens.
Your focus, on the other hand, seems to be performance:
You don't want to give guarantees about the order because of (hypothetical?) optimisations that could be blocked by that, and avoid initialisation overhead.

You brought "withUnsafeFlattening" to the table to add convenience, but I think that is the wrong direction:
Safe should be default, and it's quite common that you have to live with "unsafe" when you need "fast".

As you don't want to confirm to Sequence at all, it shouldn't bother you if the iterator sacrifices a tiny bit of performance in exchange for a reliable order, and when you really need piecemeal initialisation, you could take a FSA-Variant that skips initialisation of elements.
Of course, that wouldn't be ideal, and there should be an "Unsafe" in the name of that type — but I don't think tuple-like delayed initialisation would help when solving real-world problems:
The "x.0 = 0; x.1 = 1" case is trivial and can be done with normal init, and when this isn't enough, you most likely loose all guarantees because you use a loop to fill that array*.

I really appreciate the effort you spend for digging into the low-level details, and hope that we end up with a draft that satisfies your use case.

- Tino

* There are actually cases where you want to compute the value of one element based on another one, but that might as well be an indicator that you are better off with a tuple, instead of using an array.

>> So would you say Dictionary shouldn't conform to Collection either?
>> Just because a type conforms to a protocol doesn't mean it can't add its own methods on top.
> But the FSA interface and the Sequence/Collection interface would be very similar, basically competing, leading to a schizophrenic interface. Since another part of the overall FSA interface implements Collection, just use that.
Yes, I can't argue against the claim that Collection sometimes feels a little bit odd :-( — but it is what it is, and maybe there will be improvements in the future that could take into account the experience with FSA.

>> Swift has one-dimensional arrays, and they support Collection... this may sound like nitpicking that only works because there is no explicit "fixed-size" in you statement, but feel free to prove me wrong for FSAs.
> Yes, I meant FSAs, not both them and Array; it’s long-winded to keep adding the “fixed-size” part.
So we do agree that there is no fundamental reason that stops FSAs from being collections? ;-)

>> Anyway, withUnsafe(Mutable)Flattening would be available as a standard global function for your Collection needs. It just isn’t built into the array types.
>> So people should get used to use an "unsafe" method for basic tasks like iteration?
> withUnsafeFlattening is not the main FSA iteration task; it’s still the for-loop. If you don’t care how traversal occurs, there’s no problem. Since FSAs are built-ins instead of library types, I want the compiler to have the freedom to determine its iteration method. If you care about a particular traversal path, then implement the looping manually; you shouldn’t be hoping that whatever order I’m convince to canonize happens to match your desired order (or use withUnsafeFlattening if you want storage order). If you manually loop not for the path order but to know the index, there’s the “#indexOf” expression as the equivalent to Sequence.enumerated().
> But wait, wouldn’t storage order be the best order? Maybe, leaning towards yes, but there’s no reason to insist on it in case we’re wrong.
> I’m not starting with Collection and trying to make FSAs fit, but starting from the other direction, and seeing how compatible the interfaces are.

> (1) “Array” here is a named type (class/struct/enum), so you violated DI in your initializer
> (2) “Array” is a compound type although it looks like a named type. That’s confusing. (DI is satisfied as long as the last element is initialized before it, or the object as a whole, is read.)
> [(3) “Array” is a type-alias to a more punctuator-soup-looking compound type. That’s legal, but still a little confusing.]
I think FSAs should as much as possible behave like todays Array, so (1) is my choice.

>>>> [ah, I think I got that point: It's not about leaving parts uninitialised and taking care of them later, but the ability to use literals like
>>>> [[[0, 0, 1], [0, 1, 0]], [0, 0, 2], [0, 2, 0]]]
>>>> right?]
>>> It is about delaying initializations. But I don’t know what you mean about your statement about literals.
>> Then I've no clue what you want to achieve; can you give an example in pseudocode?
> My “delaying initializations” is the same as your “leaving parts uninitialized and taking care of them later.” I can’t give an example since you still haven’t explained what “but the ability to use literals…” means, so I can’t determine the contrast.
I even gave a explicit example! ;-)
As you meant something else, it doesn't matter — but if multi-dimensionality would be integrated into the core of Swift, there would be the option of special syntax.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170803/26a942a1/attachment.html>

More information about the swift-evolution mailing list