Sent from my iPhone

> On Jun 20, 2016, at 1:10 PM, Robert Widmann via swift-evolution 
> <swift-evolution@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
> Author(s): Harlan Haskins and Robert Widmann
> Status: Awaiting review
> 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@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to