Some thoughts inline.

> On Jan 21, 2017, at 11:06 AM, Daryle Walker via swift-evolution 
> <[email protected]> wrote:
> 
> 1. Variadic generics
> 
> When I look at SwiftDoc.org <http://swiftdoc.org/>, I see some functions 
> repeated with differing numbers of parameters. This seems like a job for 
> variadic templates^H^H^H^H^H^H^H^H^H generics, like in C++. Fortunately, 
> someone has already wrote about this, at 
> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#variadic-generics
>  
> <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#variadic-generics>>.
>  A new idea I came up with is that both homogeneous (the current support) and 
> heterogeneous variadic parameters can appear in function declarations. Each 
> can appear at most once in a declaration. And they can co-exist in the same 
> declaration; there’s no problem unless the two packs are adjacent and at 
> least the (lexically) second one doesn’t mandate a label. In that case, and 
> when the homogenous pack appears second, count from the lexically last 
> argument backwards until an argument cannot be part of the homogeneous type, 
> that’ll be the border. Count the other way when the homogenous pack is first. 
> (It’s possible for one pack to have zero elements.)

C++ has a simpler rule (for once): If you’re going to pack, you have to pack 
last.  This is roughly the rule we have as well for argument lists in functions 
that don’t have labels - they can have any number of variadic parameters 
because we can use the argument label to guide the tuple type comparison and 
disambiguate.  Here we lack argument labels (and I’m not sure it’s useful to 
have them).  

As for the distinction between heterogeneous and homogenous lists, I’m not sure 
it’s a useful thing to have unless you’re trying to roll your own Tuple (which 
is a thing you can do now with HLists 
<https://github.com/typelift/Swiftz/blob/master/Sources/HList.swift> anyway).  
Any type that wishes to take a variadic number of homogeneous type variables is 
a type that can be parametrized by one type variable and enforce the 
cardinality invariant elsewhere (see std::initializer_list).

> 
> 2. More on Arrays
> 
> Before, I’ve proposed expressions like “4 * Int” for arrays. But, looking 
> back, it’s not very Swift-y. I had problems with some forms of the syntax 
> giving the specification indices in the reverse order of the dereferencing 
> indices. It looks too quick-and-dirty. And I want to have a revolution over 
> arrays from C, like we gave the enum type.
> 
> The new inspiration came from me looking at a random blog about Swift (1?) 
> tuples, where a 2-Int tuple can be expressed by “(Int, Int)” and a 12-Int 
> tuple by “(Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int)”, I 
> thought the latter was too excessive, and that there should be a way to 
> reduce the repetition. Oh:
> 
>       (repeat Int for 12)
> 
> I originally had “by” for the second keyword. But why add one keyword and 
> reuse another when I can reuse two instead. Any compile-time positive integer 
> constant can be used. The specification does not add a nested level:
> 
>       (Double, repeat AnyObject for 4, Int)
> 
> The floating-point object is at “.0”, the class array uses “.1” through “.4”, 
> and the integer uses static index “.5”. [NOTE: Should we change this?] A 
> funny thing happens if you use a label:
> 
>       var X: (Int, sample: repeat Double for 5)
> 
> We can use “X.sample” as a source/sink for a 5-tuple of Double. It can also 
> serve as a “[Double]”, except any methods that would change the size are 
> banned. Note that since the elements are not nested, “X.sample.2” is illegal. 
> (“X.sample.2” would be “X.3” instead.) [NOTE: Should we change this?]
> 
> I originally was going to have multi-dimensions, but I couldn’t nail the 
> syntax down.
> 
>       (repeat Int for 4 for 6 for 3)
> 
> looks ugly. And I still would had to figure out the storage-nesting and 
> dereferencing orders. So only single-dimensions are supported. Note that you 
> can nest, like in C:
> 
>       (repeat (repeat Int for 4) for 6)
> 
> but it’ll be weird that although the outer dimension starts its listing 
> first, the number parts are listed in the reverse order of indexing.
> 
> This syntax will be the equivalent of C’s quick-and-dirty syntax. The main 
> feature will be arrays that act as FULL VALUE TYPES, like struct and enum:
> 
>       “array” IDENTIFIER “:” SHAPE-EXPRESSION [, PROTOCOL-LIST] “{“ 
> DEFINITION-BLOCK “}”
> 
> where the shape expression is:
> 
>       “repeat” TYPE “for” “(“ INDEX-LIST “)”
> 
> where each index is:
> 
>       MIN..<MAX or MIN…MAX or TYPE
> 
> where the type option is a enum with contiguous and countable cases (so: no 
> attribute cases, no raw type that can’t be Stridable, no repeated case 
> values, and no value gaps). The range index kinds use Int bounds. [NOTE: Even 
> if I expand it to any Stridable, where would I specify the type?] The index 
> specifiers are comma-separated. It is legal to have zero specifiers; such 
> arrays have a singular element.
> 
> If multiple index specifiers are used, they are co-equal from the user’s 
> perspective. The storage order can be specified within the definition block by
> 
>       “#storagerank” “(“ NUMBER-LIST “)”
> 
> The numbers go from 0 to one less than the number of indices and can appear 
> at most once in the list. (Zero-dimension arrays must have an empty 
> storage-rank list.) Omitted numbers are inserted after the explicit ones, in 
> increasing order. The first number of the list represents the index with the 
> largest span of elements between index values; the last number represents the 
> index with in-memory adjacent elements. If omitted altogether, it defaults to 
> implementation-defined. [NOTE: Should it be 0, 1,…, INDEX-COUNT-MINUS-1 
> instead?]
> 

This also doesn’t seem to fit with the rest of the language.  To my mind a more 
correct answer is, once again C++-style, integers-in-parameter-position and a 
catch-all homogenous `Tuple<T, .UInt>` (more than likely, magic type alias).

> The included members should at least be:
> 
>       * withUnsafeBufferPointer, like Array
>       * withUnsafeMutableBufferPointer, like Array
>       * a default initializer, if the element type has one
>       * an initializer that takes a block with INDEX-COUNT arguments and a 
> ELEMENT-TYPE return type, for other initialization
>       * a subscript that takes the index types in order (will be empty for 
> zero-dimensional arrays)
>       * a subscript that takes a tuple of all the indices (in order) [NOTE: 
> Should we have this?]
>       * some sort of apply function that goes over all the elements, includes 
> the index coordinates as parameters to the block
>       * another apply function that can mutate the elements
>       * find some way to partially subscript the elements to a smaller array 
> (may need variadic generics first)
> 
> 
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> _______________________________________________
> 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

Reply via email to