> On 18 Nov 2016, at 10:25, Adrian Zubarev via swift-evolution > <[email protected]> wrote: > > Thank you guys for all your suggestions so far. > > I understand the idea behind the generic subscript here, they are neat and > highly needed, but even this approach won’t solve my issue of clarity here. > > The Array I extend here has an Element of type Value which is an enum that > wraps other types around (part of BSON). > > I’d have to insert a huge pattern matching switch into that generic subscript > and unwrap every possible type. Don’t get me wrong, this would work, because > the result type is an optional, where I just can return nil if nothing > matches. > > But again I lose the clarity from the readers prospective, because I don’t > know by reading code like array[at: 123] = someValue what kind of subscript > I’m using here. >
Is that necessary? Either the user knows the type of his ‘someValue’ or he does not. If not then I assume that he does not need to know. If he needs to know then inspection functions can make the discovery process simple. In general I try to hide implementation details that do not matter to the user. Rien. > As already suggested, the view workaround would result in the exact the same > syntax I look for, but it has it own downsides as I already mentioned (+ > every time you’d need to instantiate a new view). > > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 18. November 2016 um 09:55:00, Haravikk ([email protected]) > schrieb: > >> Could this be addressed by allowing generic constraints on subscripts? >> For example, with methods we can currently do: >> >> struct Foo { >> var values:[Any] = [] >> >> func get<T>(at:Int) -> T? { >> return values.indices.contains(at) ? values[at] as? T : nil >> } >> >> func get<T>(at:Int, as theType:T.Type) -> T? { >> return values.indices.contains(at) ? values[at] as? T : nil >> } >> >> mutating func set<T>(at:Int, to:T) { >> if values.indices.contains(at) { values[at] = to } >> } >> } >> >> let foo = Foo(values: [1.5, 2.5, 3.5, 1, 2, 3]) >> let a = foo.get(at: 0, as: Double.self) >> let b:Double = foo.get(at: 1)! >> let c:Int? = foo.get(at: 2) >> let d = foo.get(at: 3, as: Double.self) >> let e:Int = foo.get(at: 4)! >> let f = foo.get(at: 5, as: Int.self) >> i.e- the type is inferred from the call-site either with an explicit >> variable type, or by passing in the expected type as the second argument, >> which I think is a pretty neat way to do it. >> >> If we could do the same with subscripts we could do something like: >> >> struct Foo { >> var values:[Any] = [] >> >> subscript<T>(_ at:Int) -> T? { >> get { return values.indices.contains(at) ? values[at] as? T : nil } >> set { if values.indices.contains(at) { values[at] = newValue } } >> } >> >> subscript<T>(_ at:Int, as theType:T.Type) -> T? { >> return values.indices.contains(at) ? values[at] as? T : nil >> } >> } >> >> let foo = Foo(values: [1.5, 2.5, 3.5, 1, 2, 3]) >> let a = foo[0, as: Double.self] >> let b:Double = foo[1]! >> let c:Int? = foo[2] >> let d = foo[3, as: Double.self] >> let e:Int = foo[4]! >> let f = foo[5, as: Int.self] >> >> Are generic constraints on subscripts part of the generics manifesto? >> >>> On 17 Nov 2016, at 20:14, Adrian Zubarev via swift-evolution >>> <[email protected]> wrote: >>> >>> Dear Swift community, >>> >>> while building a framework for BSON I had the following idea. >>> >>> Here is a snippet of some code I do have in my module: >>> >>> extension Array where Element == Document.Value { >>> >>> public func double(at index: Int) -> Double? { >>> >>> guard self.startIndex <= index && index < self.endIndex else { >>> return nil } >>> >>> if case .double(let double) = self[index] { >>> >>> return double >>> } >>> return nil >>> } >>> >>> … >>> } >>> >>> This function is used to query the array and check if the element at the >>> given index is of a specific type. Now I would like also to implement a >>> semi-schema setter. >>> >>> The problem that I see, is the ugliness of the subscript I’d create. >>> >>> Currently the code would read nicely let d = array.double(at: 42), but >>> after change to a subscript the API would look odd array[doubleAt: 42] = >>> 5.0. >>> >>> Don’t get me wrong here, I also have methods with larger names like public >>> func scopedJavaScript(at index: Int) -> …. You can easily imagine that such >>> subscripts would look ugly array[scopedJavaScriptAt: 123] = …. >>> >>> I propose to align the design of subscript with functions where one could >>> optionally give subscript a name. >>> >>> func name(label parameter: Type) -> ReturnType >>> >>> subscript optionalName(label parameter: Type) -> ReturnType >>> >>> This change would make my API nice and clean. array.scopedJavaScript[at: >>> 213] = … >>> >>> This also might be the opportunity to rethink the labeling rule on >>> subscripts, but this shall not be the main focus of this pitch. >>> >>> >>> >>> >>> -- >>> Adrian Zubarev >>> Sent with Airmail >>> >>> _______________________________________________ >>> 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 _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
