Sparse (fixed-size) array literal syntax


(Daryle Walker) #1

Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear arrays, but isn’t so great later on when we add fixed-size arrays and the defined (non-zero) elements are sparse and/or the array is multi-dimensional (not nested). In these cases I’m thinking of leading each element with its coordinate:

… 6: a, … // complete value, linear array
… (1, 2): b, … // complete value, multi-dimensional array
… (let x, let y) where y % 2 == 0: c * y + x, … // pattern of qualifying coordinates
… default: d, … // when no other initializer covers an element (Use “_” instead?)

A complete coordinate beats a pattern, which beats a default. The issue I see here is that I’m using a colon as a separator between the coordinate expression and the value expression. Would that interfere with dictionary literal syntax? Would it help the we’ll most likely have to demand that the object receiving the literal has to have its type specified (with whatever syntax we agree on), as either a declared object with a type annotation or a function parameter (for a function either without overload or with the variant used otherwise made clear)?

···


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


(Jaden Geller) #2

Comments inline.

Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear arrays, but isn’t so great later on when we add fixed-size arrays and the defined (non-zero) elements are sparse and/or the array is multi-dimensional (not nested). In these cases I’m thinking of leading each element with its coordinate:

… 6: a, … // complete value, linear array

You can already do this with a dictionary since a Int can be used as the key type.

… (1, 2): b, … // complete value, multi-dimensional array

This would be possible if tuples of hashable types were considered hahable. Right now, you could define some point type.

… (let x, let y) where y % 2 == 0: c * y + x, … // pattern of qualifying coordinates

You can build this sort of thing using an initializer that takes a function. You wouldn’t get this sugar, but I don’t think it is necessary.

… default: d, … // when no other initializer covers an element (Use “_” instead?)

This one is a bit harder. I think it would be reasonable for there to exist some subtype of the dictionary literal type that also included information about a default value, but I think this should be motivated by the Swift standard library (e.g. a defaultable dictionary type).

Right now, you can just make literal syntax default to a `nil` default value, and then you can define a function that nil-coalesces the default value. This is definitely less elegant, but I don’t think it matters a whole lot.

Sparse([1: “foo”, 5: “bar”, 100: “baz”], default: “”)

A complete coordinate beats a pattern, which beats a default. The issue I see here is that I’m using a colon as a separator between the coordinate expression and the value expression. Would that interfere with dictionary literal syntax? Would it help the we’ll most likely have to demand that the object receiving the literal has to have its type specified (with whatever syntax we agree on), as either a declared object with a type annotation or a function parameter (for a function either without overload or with the variant used otherwise made clear)?


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

Cheers,
Jaden Geller

···

On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:


(Daryle Walker) #3

I’m not asking how to do this in current Swift with current types, but fixed-sized arrays in a future Swift. I’m asking if this mixing of array- and dictionary-literals for these advanced-array literals would be too hard for compiler implementors to implement.

···

On Jun 2, 2017, at 2:11 AM, Jaden Geller <jaden.geller@gmail.com> wrote:

Comments inline.

On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear arrays, but isn’t so great later on when we add fixed-size arrays and the defined (non-zero) elements are sparse and/or the array is multi-dimensional (not nested). In these cases I’m thinking of leading each element with its coordinate:

… 6: a, … // complete value, linear array

You can already do this with a dictionary since a Int can be used as the key type.

… (1, 2): b, … // complete value, multi-dimensional array

This would be possible if tuples of hashable types were considered hahable. Right now, you could define some point type.

… (let x, let y) where y % 2 == 0: c * y + x, … // pattern of qualifying coordinates

You can build this sort of thing using an initializer that takes a function. You wouldn’t get this sugar, but I don’t think it is necessary.

… default: d, … // when no other initializer covers an element (Use “_” instead?)

This one is a bit harder. I think it would be reasonable for there to exist some subtype of the dictionary literal type that also included information about a default value, but I think this should be motivated by the Swift standard library (e.g. a defaultable dictionary type).

Right now, you can just make literal syntax default to a `nil` default value, and then you can define a function that nil-coalesces the default value. This is definitely less elegant, but I don’t think it matters a whole lot.

Sparse([1: “foo”, 5: “bar”, 100: “baz”], default: “”)


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


(John McCall) #4

"Literals" like this are obviously complicated to the point that you would be much better off just using an initializer that takes a function to construct each element. There's no point in reinventing switches in the array-literal syntax.

John.

···

On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org> wrote:

Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear arrays, but isn’t so great later on when we add fixed-size arrays and the defined (non-zero) elements are sparse and/or the array is multi-dimensional (not nested). In these cases I’m thinking of leading each element with its coordinate:

… 6: a, … // complete value, linear array
… (1, 2): b, … // complete value, multi-dimensional array
… (let x, let y) where y % 2 == 0: c * y + x, … // pattern of qualifying coordinates
… default: d, … // when no other initializer covers an element (Use “_” instead?)

A complete coordinate beats a pattern, which beats a default. The issue I see here is that I’m using a colon as a separator between the coordinate expression and the value expression. Would that interfere with dictionary literal syntax? Would it help the we’ll most likely have to demand that the object receiving the literal has to have its type specified (with whatever syntax we agree on), as either a declared object with a type annotation or a function parameter (for a function either without overload or with the variant used otherwise made clear)?


(Jaden Geller) #5

Why would this not be possible with fixed sized arrays? Theoretically you could create a type that wrapped a fixed array and make it conform to whatever protocol you want, including the “ExpressibleBy” protocols.

···

On Jun 2, 2017, at 12:22 AM, Daryle Walker <darylew@mac.com> wrote:

On Jun 2, 2017, at 2:11 AM, Jaden Geller <jaden.geller@gmail.com <mailto:jaden.geller@gmail.com>> wrote:

Comments inline.

On Jun 1, 2017, at 10:49 PM, Daryle Walker via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Current array literal syntax (i.e. “[a, b, c]”) works for dense and/or linear arrays, but isn’t so great later on when we add fixed-size arrays and the defined (non-zero) elements are sparse and/or the array is multi-dimensional (not nested). In these cases I’m thinking of leading each element with its coordinate:

… 6: a, … // complete value, linear array

You can already do this with a dictionary since a Int can be used as the key type.

… (1, 2): b, … // complete value, multi-dimensional array

This would be possible if tuples of hashable types were considered hahable. Right now, you could define some point type.

… (let x, let y) where y % 2 == 0: c * y + x, … // pattern of qualifying coordinates

You can build this sort of thing using an initializer that takes a function. You wouldn’t get this sugar, but I don’t think it is necessary.

… default: d, … // when no other initializer covers an element (Use “_” instead?)

This one is a bit harder. I think it would be reasonable for there to exist some subtype of the dictionary literal type that also included information about a default value, but I think this should be motivated by the Swift standard library (e.g. a defaultable dictionary type).

Right now, you can just make literal syntax default to a `nil` default value, and then you can define a function that nil-coalesces the default value. This is definitely less elegant, but I don’t think it matters a whole lot.

Sparse([1: “foo”, 5: “bar”, 100: “baz”], default: “”)

I’m not asking how to do this in current Swift with current types, but fixed-sized arrays in a future Swift. I’m asking if this mixing of array- and dictionary-literals for these advanced-array literals would be too hard for compiler implementors to implement.


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


(Daryle Walker) #6

I DO want it to be possible with future fixed-sized arrays. This is not a user-side question, but implementor-side. I’m asking if the parsing routines for it would conflict with the current array- and dictionary-literal rules, since they will co-exist. If this syntax would make determining whether we have an enhanced array literal or a dictionary literal too hard, then we should change it before anything is finalized.

···

On Jun 2, 2017, at 3:56 AM, Jaden Geller <jaden.geller@gmail.com> wrote:

Why would this not be possible with fixed sized arrays? Theoretically you could create a type that wrapped a fixed array and make it conform to whatever protocol you want, including the “ExpressibleBy” protocols.


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


(Jaden Geller) #7

I don’t know if you’re aware, but you can extend arbitrary nominal types with literal syntax.

extension FixedSizedArray: ExpressibleAsDictionaryLiteral { … }

Nothing special needs to be done on the implementation side to make this possible. If fixed sized arrays are not nominal types (like tuples, unlike `Array`s), then you will only be able to give this sugar to types that wrap them, not the type itself (w/o special support).

What’s the discussion on enhanced array and dictionary literals? I think I missed that.

Cheers,
Jaden Geller

···

On Jun 2, 2017, at 1:02 AM, Daryle Walker <darylew@mac.com> wrote:

On Jun 2, 2017, at 3:56 AM, Jaden Geller <jaden.geller@gmail.com> wrote:

Why would this not be possible with fixed sized arrays? Theoretically you could create a type that wrapped a fixed array and make it conform to whatever protocol you want, including the “ExpressibleBy” protocols.

I DO want it to be possible with future fixed-sized arrays. This is not a user-side question, but implementor-side. I’m asking if the parsing routines for it would conflict with the current array- and dictionary-literal rules, since they will co-exist. If this syntax would make determining whether we have an enhanced array literal or a dictionary literal too hard, then we should change it before anything is finalized.


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


(Daryle Walker) #8

I don’t know if you’re aware, but you can extend arbitrary nominal types with literal syntax.

extension FixedSizedArray: ExpressibleAsDictionaryLiteral { … }

Nothing special needs to be done on the implementation side to make this possible. If fixed sized arrays are not nominal types (like tuples, unlike `Array`s), then you will only be able to give this sugar to types that wrap them, not the type itself (w/o special support).

I don’t think that’ll work with the “where” clauses and “default” values in the new syntax.

What’s the discussion on enhanced array and dictionary literals? I think I missed that.

This is the discussion. I’m asking if this “enhanced array” syntax I just came up with would interfere with the existing dictionary syntax from a parsing perspective.

···

On Jun 2, 2017, at 4:06 AM, Jaden Geller <jaden.geller@gmail.com> wrote:


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


(Jaden Geller) #9

Comments inline.

I don’t know if you’re aware, but you can extend arbitrary nominal types with literal syntax.

extension FixedSizedArray: ExpressibleAsDictionaryLiteral { … }

Nothing special needs to be done on the implementation side to make this possible. If fixed sized arrays are not nominal types (like tuples, unlike `Array`s), then you will only be able to give this sugar to types that wrap them, not the type itself (w/o special support).

I don’t think that’ll work with the “where” clauses and “default” values in the new syntax.

I explained point-by-point which of these would be possible. If you reference the original message, I stated that the “where” sugar could instead be expressed with a lambda function. Personally, I’m against adding this new “where" sugar to the language, especially since the alternative seems no worse. I do think the “default” sugar is a good idea (as I stated there as well), but I don’t think it must be considered with fixed length arrays. It seems like an entirely additive and orthogonal feature.

What’s the discussion on enhanced array and dictionary literals? I think I missed that.

This is the discussion. I’m asking if this “enhanced array” syntax I just came up with would interfere with the existing dictionary syntax from a parsing perspective.

I see. The first two cases (which are just normal dictionary syntax) are already possible. I don’t know about the third “where” case, but I don’t think it’s necessary. The 4th case seems possible since the keyword “default” cannot be used as an identifier.


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

Cheers,
Jaden Geller

···

On Jun 2, 2017, at 2:38 AM, Daryle Walker <darylew@mac.com> wrote:

On Jun 2, 2017, at 4:06 AM, Jaden Geller <jaden.geller@gmail.com> wrote: