> On Jun 29, 2017, at 5:19 AM, Matt Gallagher via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Super short summary:
> 
> I think a function argument or right-hand-side expression prefixed with `.` 
> should allow access to *any* static member on the expected type, dropping the 
> existing limitations of this syntax.
> 
> Detail:
> 
> At the moment in Swift, you can use a `.` (period or dot) prefix to perform a 
> scoped lookup of static vars and funcs on the expected type, if those static 
> vars or funcs return that type.
> 
> For example:
> 
>       // If we have a type `SomeNontrivialTypeName`
>       struct SomeNontrivialTypeName {
>          // With a static function returning `SomeNontrivialTypeName`
>          static func a() -> SomeNontrivialTypeName
>       }
>       
>       // And a function that requires a `SomeNontrivialTypeName` parameter
>       func f(a: SomeNontrivialTypeName)
>       
>       // We can call the function like this:
>       f(a: .a())
> 
> The `.` prefix allows us to omit the typename `SomeNontrivialTypeName`; since 
> the parameter already expects `SomeNontrivialTypeName`, the `.` already 
> implies lookup in the list of static func/vars for `SomeNontrivialTypeName`.
> 
> The purpose is syntactic efficiency and it's used to great extent across a 
> wide range of Swift/AppKit/Foundation interfaces for enum-like value lookups. 
> It lets us have very simple names that won't clash with names in the global 
> namespace because they're not in the global namespace – and yet, they're only 
> a single `.` more syntactic overhead.
> 
> Unfortunately, there is no extendability. This approach will look up only 
> static vars or funcs that immediately return the expected type and you can't 
> transform the result – it's one function and done. For example, if 
> `SomeNontrivialTypeName` has a fluent-style interface (i.e. an interface 
> where instance methods return mutated `self` or new instances of 
> `SomeNontrivialTypeName`):
> 
>       extension SomeNontrivialTypeName {
>               func addThings() -> SomeNontrivialTypeName
>       }
> 
> trying to append this function won't work, even though the return type 
> remains correct:
> 
>       f(a: .a().addThings())
> 
> This fails and claims that we've forgotten to provide a parameter (!).
> 
> A completely different kind of transformation might go via a different type
> 
>       extension SomeNontrivialTypeName {
>               static func another() -> AnotherType
>       }
>       
>       struct AnotherType {
>               func back() -> SomeNontrivialTypeName
>       }
> 
> It would be nice to be able to use this "there-and-back-again" transformation:
> 
>       f(a: .another().back())
> 
> But it also won't work.
> 
> I realize that this is a point about minor syntactic efficiency. Yes, you 
> could simply write:
> 
>       f(a: SomeNontrivialTypeName.another().back())
> 
> but it's clunky and the type name gets in the way.
> 
> There's also an element of consistency. Swift already lets us look up static 
> functions in this way – but:
>       
>       * only functions that return the expected type
>       * and we can't *use* the function result ourselves, it must be 
> immediately yielded to the parameter or left-hand-side
> 
> Seems more than a little strange.
> 
> Anyone else care or have thoughts on this point?

I've also wanted this. It seems like a straightforward extension of the 
existing feature, which already has to set up a constraint system dependent on 
the contextual type, but which happens to be artificially constrained to adding 
only one step of member lookup or of member lookup followed by a call of that 
member to the system.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to