[swift-evolution] [Proposal] Generic and `throw`ing subscripts

Robert Widmann rwidmann at apple.com
Mon Jun 20 19:06:47 CDT 2016


They are quite related considering a subscript can have a getter-setter pair.  Brent already has a proposal to cover throwing properties (and subscripts), so we’re overlapping in that regard. 

> On Jun 20, 2016, at 1:33 PM, David Rönnqvist <david.ronnqvist at gmail.com> wrote:
> 
> Would this proposal in any way be related to `throw`ing properties (more specifically throwing setters)? Or would that be a completely different discussion/proposal?
> 
> - David
> 
> On 20 Jun 2016, at 21:27, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> 
>> 
>> Sent from my iPhone
>> 
>> On Jun 20, 2016, at 1:10 PM, Robert Widmann via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> Good morning all.  Attached is the proposal Harlan Haskins and I will be submitting shortly about adding generic and `throw`ing subscript declarations to the language. 
>> 
>> +1.  Thank you for bringing forward this proposal.  I ran into these limitations in exactly the context you mention in the proposal.
>> 
>> Another context where this will be useful is emulating higher-rank "callable" types (using subscript for function invocation).
>> 
>>> 
>>> Cheers,
>>> 
>>> ~Robert Widmann
>>> 
>>> Generic and Throwing Subscripts
>>> 
>>> Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
>>> Author(s): Harlan Haskins <https://github.com/harlanhaskins> and Robert Widmann <https://github.com/codafi>
>>> Status: Awaiting review <https://github.com/typelift/SwiftCheck/pull/168#rationale>
>>> Review manager: TBD
>>> Introduction
>>> 
>>> Currently, subscripts cannot be declared [re]throws and cannot declare new generic parameters.
>>> There isn't a clear reason why they aren't as capable as full-fledged functions, so we propose
>>> adding generic constraints and throwing semantics to subscripts.
>>> 
>>> Motivation
>>> 
>>> On the throwing side, currently there are two ways to express a failing subscript:
>>> 
>>> Return an Optional, failing with nil.
>>> Call fatalError(_:) on failure.
>>> Both of these throw out useful information about the cause of the underlying error that using Swift's error handling mechanism can otherwise provide.
>>> 
>>> As for generics, to take an example, it has become a common pattern among JSON decoding DSL libraries to express a throwing generic extension on Dictionary like so
>>> 
>>> extension Dictionary {
>>>     public func parse<T>(key: Key) throws -> T {
>>>         guard let value = self[key] else {
>>>             throw JSONError.MissingKey("\(key)")
>>>         }
>>>         guard let ofType = value as? T else {
>>>             throw JSONError.InvalidKey(key: "\(key)", expectedType: T.self, foundType: value.dynamicType)
>>>         }
>>>         return ofType
>>>     }
>>> }
>>> 
>>> public enum JSONError: ErrorType, CustomStringConvertible {
>>>     case InvalidKey(key: String, expectedType: Any.Type, foundType: Any.Type)
>>>     case MissingKey(String)
>>>     public var description: String {
>>>         switch self {
>>>         case .InvalidKey(let key, let expected, let found):
>>>             return "Invalid key \"\(key)\". Expected value of type \"\(expected)\", found \"\(found)\"."
>>>         case .MissingKey(let key):
>>>             return "Key \(key) not found."
>>>         }
>>>     }
>>> }
>>> Given this, one can decode JSON with the full support of native type inference and exception handling. But when working with the DSL, one would expect to be able to express this as a subscript on Dictionary, allowing the following:
>>> 
>>> //...
>>> 
>>> extension Dictionary {
>>>     public subscript<T>(key: Key) throws -> T {
>>>         guard let value = self[key] else {
>>>             throw JSONError.MissingKey("\(key)")
>>>         }
>>>         guard let ofType = value as? T else {
>>>             throw JSONError.InvalidKey(key: "\(key)", expectedType: T.self, foundType: value.dynamicType)
>>>         }
>>>         return ofType
>>>     }
>>> }
>>> We believe this is an even more natural way to write these kinds of libraries in Swift and that bringing subscript member declarations up to par with functions is a useful addition to the language as a whole.
>>> 
>>> Proposed solution
>>> 
>>> Add the ability to introduce new generic parameters and mark throws and rethrows on subscript members.
>>> 
>>> Detailed design
>>> 
>>> This change will modify and add the following productions in the Swift grammar
>>> 
>>> GRAMMAR OF A SUBSCRIPT DECLARATION
>>> 
>>> subscript-declaration → subscript-head subscript-result code-block
>>> subscript-declaration → subscript-head subscript-result getter-setter-block
>>> subscript-declaration → subscript-head subscript-result getter-setter-keyword-block
>>> -subscript-head → attributes(opt) declaration-modifiers(opt) subscript parameter-clause
>>> +subscript-head → attributes(opt) declaration-modifiers(opt) generic-parameter-clause(opt) subscript parameter-clause
>>> +subscript-result → -> attributes(opt) throws(opt) type
>>> +subscript-result → -> attributes(opt) rethrows(opt) type
>>> Rationale
>>> 
>>> On [Date], the core team decided to (TBD) this proposal.
>>> When the core team makes a decision regarding this proposal,
>>> their rationale for the decision will be written here.
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>

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


More information about the swift-evolution mailing list