[swift-evolution] Generic Subscripts

Slava Pestov spestov at apple.com
Thu Jan 12 22:23:49 CST 2017


> On Jan 12, 2017, at 7:05 PM, Karl Wagner <razielim at gmail.com> wrote:
> 
> 
>> On 12 Jan 2017, at 22:37, Slava Pestov via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> 
>>> On Jan 12, 2017, at 9:53 AM, Chris Eidhof via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> Ok, I've got a draft up as a gist: https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 <https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25>
>>> 
>>> Before I submit it, could someone let me know if adding generics to subscripts would influence the ABI? ( still feel pretty clueless in that area).
>> 
>> It won’t change the ABI of existing subscript calls, but if the standard library introduces new generic subscripts that replace older non-generic subscripts, it will impact ABI.
>> 
>> Slava
> 
> Why are subscripts so different, anyway? One would think they are basically sugared functions, but they don’t support so many things that regular functions support. Not just syntax stuff, either - they also don’t support @inline(__always) for some reason…

Nice catch with @inline(__always). Please file a JIRA issue, since I’m actively working on this stuff now.

Subscripts are a bit different from ordinary functions because they’re lvalues. You can call mutating members on the result of a subscript, or chain it with another property access or subscript. So the code path in SILGen is a little different than ordinary function calls. This is the reason subscripts cannot have default arguments also. With a bit of refactoring we can unify the code path for forming call arguments in ordinary calls and subscripts, and hopefully the default argument and generic cases will fall out naturally also.

> 
> Where generic subscripts are concerned, there are a couple of different things to express:
> - Generic parameter  (I can understand various co-ordinates for the data)
> - Generic return type (I can construct your preferred representation of the data)
> - Generic setter type (I can set the data using various compatible types):

I think all of these should be expressed with a single generic signature on the subscript itself. The element type passed to the setter and returned from the getter should be the same IMO, otherwise it’s not clear how it will work.

> 
> protocol MeaningfulToFoo {}
> protocol ConstructableFromFoo {}
> 
> struct Foo {
>     subscript<Index>(index: Index) where Index: SignedInteger {
>         get<T> where T: ConstructableFromFoo { return T(self) }
>         set<U> where T: MeaningfulToFoo      { self.someProperty = newValue.someData }
>     }
> }
> 
> The syntax looks a bit awkward, though, IMO. I’m wondering if it might be better to have some kind of combined subscript + property behaviours (remember those?) and allow those to be generic instead. Subscripts and properties are very similar anyway - they are both bundles of functions to represent getting and setting data (not just regular-old “get” and “set”, either, but also magic stuff like “mutableAddressWithPinnedNativeOwner”). The only difference is that property getters can’t have parameters — which is something I would also like to see lifted one day (I believe I’ve even seen people asking for “named subscripts” due to the lack of this =P)
> 
> - Karl
> 

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


More information about the swift-evolution mailing list