> On 18 Nov 2016, at 11:45, Adrian Zubarev via swift-evolution > <[email protected]> wrote: > > The reason here is because the setter acts like semi-schema setter.
Ah, ok. Just wondered because I had a similar case in SwifterJSON. Eventually I settled for the absence of user-supplied type information while creating the JSON object. On read however, type information must be specified for safety (semi-schema read). > > For the given array example: > > array.double[at: 42] // would return a nil, if the index is out of bounds, or > if the wrapped `Value` instance at the given index is not `.double(Double)` > > array.double[at: 42] = 2.0 // would update the value iff the wrapped `Value` > instance is `.double(Double)`, otherwise the setter will do nothing > > This is a semi-schema approach and different from overriding any existing > value at the given index like array[42] = .double(2.0) > > About the mutation problem you can find the short talk here, right at the > bottom. > > If there is no setter for your view, array.double[at: 42] = 2.0 simply won’t > work. > > Please proof me wrong here, if there is a better way to solve the problem. :) > > I appreciate any suggestions. > > So far we had no concrete arguments agains optionally named subscripts. > Anything you dislike about that? > No, in fact +1 Regards, Rien Site: http://balancingrock.nl Blog: http://swiftrien.blogspot.com Github: http://github.com/Swiftrien Project: http://swiftfire.nl > Personally I don’t think they hurt any Swiftiness at all. > > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 18. November 2016 um 10:39:17, Xiaodi Wu ([email protected]) schrieb: > >> Sorry, can you explain what you >> mean when you say you must have a setter? Why would you mutate the >> view and not the array itself (`foo[42] = .double(42)` as opposed >> to `foo.double[42] = 42`)? >> >> >> On Fri, Nov 18, 2016 at 03: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. >> >> 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 _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
