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

T.J. Usiyan griotspeak at gmail.com
Wed Jun 22 08:28:04 CDT 2016


plx: wouldn't the same overload resolution strategy be appropriate here?
"most specific choice, otherwise diagnostic"



separately:
Are there any subscripts in the standard library that would be
throwing/generic but can't be?


On Wed, Jun 22, 2016 at 9:13 AM, plx via swift-evolution <
swift-evolution at swift.org> wrote:

> Prefacing the below with a “I am well-aware this proposal likely won’t
> make it into Swift 3”:
>
> A feature like this would be nice to use, but before I could get behind
> any proposal along these lines it I’d want to see it include an explicit
> strategy for disambiguation.
>
> EG: in your example, your generic subscript uses `self[key]`, and
> presumably expects that to use the “original” subscript…and not the generic
> subscript being defined.
>
> I think that’s reasonable in that specific case, but it doesn’t seem
> unreasonable to anticipate this proposal introducing ambiguities that would
> need explicit disambiguation…and for which explicit type annotation may not
> always be adequate to resolve (I could be wrong here, though).
>
> This would need addressing (either showing they won’t be an issue, or
> providing a reliable disambiguation mechanism).
>
> Relatedly, in-re: “rethrows”: if the syntax supported it, this kind of
> thing would be another way of tackling the "JSON problem":
>
>   subscript<T>(key: Key, transform: (Value) throws -> T) rethrows -> T {
>     guard let value = self[key] else { throw JSON.MissingKey(…) }
>     return try transform(value)
>   }
>
> …so that e.g. you can write typical parsing-code as
>
>   let asUserID = UserID.init(untrustedString:) // <- assume this is a
> "throwing constructor"
>   let sender = try json[“sender”,asUserID]
>   let recipient = try json[“recipient”,asUserID]
>
> …(modulo any syntax errors, etc.), which would benefit from a `rethrows`
> declaration.
>
> That’s my 2c; thankfully (IMHO) there’s clearly a lot of time for this
> proposal to simmer.
>
> On Jun 20, 2016, at 1:10 PM, Robert Widmann via swift-evolution <
> 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.
>
> 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
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160622/6fe560d7/attachment.html>


More information about the swift-evolution mailing list