Subscripts assignable to closure vars

Just came across this.

I want to be able to hold onto the reference to a subscript "method" for later use.

Assigning the subscript to a var in the init of a type raises a segmentation fault.

Should this - could this - be allowed?

protocol DataProvider
{
  associatedtype ItemType
  
  subscript(index: Int) -> ItemType { get }
}

struct AnyDataProvider<providerType: DataProvider> : DataProvider
{
  private var _subscript: (Int) -> providerType.ItemType

  subscript(index: Int) -> providerType.ItemType
  {
    return _subscript(index)
  }
  
  init<P : DataProvider>(_ base: P) where P.ItemType == providerType.ItemType
  {
    _subscript = base.subscript
  }
}

Joanna

···

--
Joanna Carter
Carter Consulting

The crash is already fixed in master, thanks to Alex Hoppen's work on making actual subscripts distinct from the name "subscript".

I think John's right that this should not be allowed. After all, a subscript may have both a getter and a setter, and it's not immediately obvious from your syntax which one you mean.

We could invent some kind of answer for this (including simply just checking the contextual type), but it would be nice™ if any such solution also had a good answer for properties. Or we could just make key paths and closures work a little better together, which has also been discussed on the list.

Jordan

···

On Sep 15, 2017, at 13:00, John McCall via swift-evolution <swift-evolution@swift.org> wrote:

On Sep 15, 2017, at 3:45 PM, Joanna Carter via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Just came across this.

I want to be able to hold onto the reference to a subscript "method" for later use.

Assigning the subscript to a var in the init of a type raises a segmentation fault.

Should this - could this - be allowed?

It really shouldn't be allowed. I think KeyPaths are the intended language solution here.

Please file a bug about the crash, though.

Just came across this.

I want to be able to hold onto the reference to a subscript "method" for later use.

Assigning the subscript to a var in the init of a type raises a segmentation fault.

Should this - could this - be allowed?

It really shouldn't be allowed. I think KeyPaths are the intended language solution here.

Please file a bug about the crash, though.

John.

···

On Sep 15, 2017, at 3:45 PM, Joanna Carter via swift-evolution <swift-evolution@swift.org> wrote:

protocol DataProvider
{
associatedtype ItemType

subscript(index: Int) -> ItemType { get }
}

struct AnyDataProvider<providerType: DataProvider> : DataProvider
{
private var _subscript: (Int) -> providerType.ItemType

subscript(index: Int) -> providerType.ItemType
{
   return _subscript(index)
}

init<P : DataProvider>(_ base: P) where P.ItemType == providerType.ItemType
{
   _subscript = base.subscript
}
}

Joanna

--
Joanna Carter
Carter Consulting

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

Hi Jordan

The crash is already fixed in master, thanks to Alex Hoppen's work on making actual subscripts distinct from the name "subscript".

I think John's right that this should not be allowed. After all, a subscript may have both a getter and a setter, and it's not immediately obvious from your syntax which one you mean.

As of Xcode 9.0 (9A235), there are still numerous segmentation faults instead of proper errors. This is one of them.

Not wanting to confuse things but, I am also getting a segmentation fault if I pass an incorrect type as a generic parameter to a generic type e.g.

    let personProvider = PersonDataProvider()

   let listModel = ListModel<PersonDataProvider>(data: AnyDataProvider(personProvider))

… provokes a segmentation fault instead of a coherent error.

The code should read :

    let personProvider = PersonDataProvider()

   let listModel = ListModel<Person>(data: AnyDataProvider(personProvider))

See the code below for the entities involved.

We could invent some kind of answer for this (including simply just checking the contextual type), but it would be nice™ if any such solution also had a good answer for properties. Or we could just make key paths and closures work a little better together, which has also been discussed on the list.

Slava Pestov showed me a good solution for the subscript assignment, which works fine. Here is the fully updated code for my example :

protocol DataProvider
{
  associatedtype ItemType
  
  subscript(index: Int) -> ItemType { get }
}

struct AnyDataProvider<itemType> : DataProvider
{
  private let _subscript: (Int) -> itemType

  subscript(index: Int) -> itemType
  {
    return _subscript(index)
  }
  
  init<providerType : DataProvider>(_ base: providerType) where providerType.ItemType == itemType
  {
    _subscript = { base[$0] }
  }
}

class ListModel<itemType>
{
  private var data: AnyDataProvider<itemType>
  
  init(data: AnyDataProvider<itemType>)
  {
    self.data = data
  }
  
  subscript(index: Int) -> itemType
  {
    return data[index]
  }
}

Regards

Joanna

···

Le 15 sept. 2017 à 23:55, Jordan Rose <jordan_rose@apple.com> a écrit :

--
Joanna Carter
Carter Consulting