> On Aug 2, 2017, at 11:44 AM, Félix Cloutier via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> Le 31 juil. 2017 à 18:54, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> 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
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to