> On Aug 2, 2017, at 11:44 AM, Félix Cloutier via swift-evolution
> <[email protected]> wrote:
>
>
>> Le 31 juil. 2017 à 18:54, Xiaodi Wu <[email protected]
>> <mailto:[email protected]>> a écrit :
>> It doesn't allow you to specify the size of the array, it's just a promise
>> that the array is some immutable size. For instance, a `fixed [CGFloat]`
>> would be a terrible type to represent a vector, but a
>> FixedSizeArray<CGFloat, 4> would be appropriate, at least for the backing
>> storage. A raw tuple would be a poor choice because dynamically indexing
>> into them is painful.
>>
>> Shouldn't this be solved by improvements to tuples? It's a highly desired
>> feature (by me and at least a few others) to allow tuples to conform to
>> protocols, whether fixed-size arrays are added or not. I expect that
>> conforming homogeneous tuples to Collection and enabling subscripting is
>> simply a matter of time.
>
> Of course, if this happens, the point is moot and we have the type of
> fixed-size arrays that I've been asking for. However, crystal-balling Chris's
> last comment on the matter, it looks like it might not be happening too soon
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170724/038225.html>.
>
>> `fixed` is only useful when the compiler can determine the size of the array
>> statically. This makes it mostly useless as a storage qualifier if you
>> received the array as a parameter (*even* if you received a `fixed` array),
>> because you know that it has a constant size but you don't know what that
>> size is.
>> Therefore, using a fixed-size array as a generic parameter (crucially, such
>> as `fixed [fixed [Int]]`) is unlikely to work.
>> Even if that semantic hurdle is overcome, we'd still have no idea how much
>> memory to allocate for the outer array's buffer to make it work.
>>
>> As John McCall has replied, the array's bounds don't need to be statically
>> known for fixed-size arrays to have benefits.
>
> This (partially) applies to the first point, but it leaves a lot of holes.
> The size does not need to be statically known, but you need to know how much
> memory you're going to need ahead of allocating it. How much memory do you
> need for this?
>
>> var foo = fixed [Int]()
>> for i in 0..<param {
>> foo.append(i)
>> }
>
> Arrays can't work if elements don't have a fixed size. How big is an element
> in this example?
This is not the idea. The idea is more like
let n = ...
var foo = [Int x n](repeating: 13)
The bound value is still fundamentally part of the type of the variable; it's
just that the actual value is not known statically.
John.
>> var foo = fixed [fixed [Int]]()
>> foo.append([1])
>> foo.append([2, 3])
>
>
> Where do you allocate this array's storage, and how big is it?
>
>> struct Foo {
>> var array: fixed [Int]
>> }
>>
>> var foo = Foo()
>> foo.array.append(4)
>
>
> In the general case, this makes `fixed` meaningful as a type annotation for
> parameters, but instantiating such an object in the first place would require
> you to give up a lot of flexibility in how it's populated. The unconstrained
> problem of finding how many elements you'll have in an array is uncomputable.
>
> You could say that a fixed-size array stays as big as it was when it was
> instantiated, but this still causes problems with fixed-size arrays in
> structures (storage has already been allocated when the initializer runs),
> and with generic collections (you couldn't initialize a variable-sized array
> of fixed-size arrays, for instance).
>> Even if `fixed [fixed [Int]]` could work, then each inner array could still
>> have a different size, which is almost certainly not what you intend by
>> nesting two fixed-size arrays.
>>
>> That's fair, but why at that point wouldn't you make your own Matrix type of
>> fixed size, which uses an Array of fixed size as the underlying storage?
>
> I'd do it if I needed to, but there are plenty of 2D arrays that are just
> that and don't need their own wrapper type to function, and I'd be happier to
> not do it.
>> Layout compatibility is important if you want to use fixed-size arrays to
>> replace the clunky tuples that currently represent fixed-size arrays in
>> structs exported from C (which is probably my one single biggest motivation
>> for fixed-size arrays). You can't achieve layout compatibility if the size
>> is part of the data instead of part of the type.
>>
>> For me, that's an anti-goal, as IMO tuples are the most sensible way of
>> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue
>> that the most idiomatic way to represent four CGFloat instances is
>> `(CGFloat, CGFloat, CGFloat, CGFloat)`. The solution to certain operations
>> being clunky with tuples is to improve the ergonomics of tuples. For
>> instance, if we need a shorthand to avoid typing all those `CGFloat`s, then
>> add one: `(4 * CGFloat)`. If we need subscripting, then add it.
>
> I think that any template-based fixed-size array structure would still need
> that kind of (4 * CGFloat) syntax to be implemented, or some other facility
> to allocate a parameterized amount of automatic storage. With that said, if
> we can implement fixed-size arrays with just that without having to wait for
> the restrictions on anonymous types to be lifted, to me, it's a fully
> acceptable solution.
>
>> Besides, attaching fixed-size array semantics to an inherently variable-size
>> Array is awkward. For `fixed` to be effective, it needs to disable methods
>> that change the size of the array, or warn that you're using them. I don't
>> like the cross-concern impact: now a keyword needs to know about method
>> implementations to restrict them. It also has to work with extension methods
>> on the Array type, and it shouldn't apply to just mutating functions because
>> mutations that don't change the length of the array are fine.
>>
>> The idea is that all facilities which would benefit from knowing that an
>> array is of a fixed count would opt into that benefit by indicating as such.
>> That is, all stdlib array methods that are guaranteed to preserve the size
>> of the array would be annotated as such. Again, by analogy to the ownership
>> manifesto's design where functions that take shared arguments could be
>> optimized on the basis of such annotation. The rest would fall out naturally.
>
> There are more problems to this that you may be able to iron out but that
> make the story more complex still. How do you annotate
> MutableCollection-based algorithms, or any other protocol-based extension
> that doesn't directly accept an array? What's the syntax of an Array
> extension method, which doesn't have an explicit self parameter, to mean that
> the function is mutating but doesn't change the array's bounds?
>
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution