[swift-evolution] Spread Operator as Shorthand for Map

Matthew Johnson matthew at anandabits.com
Wed Dec 16 22:28:49 CST 2015


> On Dec 16, 2015, at 1:32 PM, Stephen Celis <stephen.celis at gmail.com> wrote:
> 
> On Wed, Dec 16, 2015 at 2:18 PM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
> 
> I believe the dot abbreviation only works for enum cases right now.
> 
> Nope :)
>  
> I suppose those can be viewed as static members in some sense but they really something different than that.  If I am mistaken I would like to be corrected.
> 
> I'll do my best!
> 
> It works as I was trying to describe earlier. Any static member that returns Self. Try the following in a playground/REPL:
> 
>     struct Foo {
>         static var bar: Foo {
>             return Foo()
>         }
>         static func baz() -> Foo {
>             return Foo()
>         }
>     }
>     let bar: Foo = .bar
>     let baz: Foo = .baz()
> 
> Here's a SwiftStub demonstrating the behavior: http://swiftstub.com/579553153 <http://swiftstub.com/579553153>
> 
> Enum cases work with dot abbreviation _because_ they are static members that return Self. Enumerations aren't special-cased for dot abbreviation.
> 

I stand corrected.  This is pretty interesting.  Is this covered in any documentation?  I haven’t seen anything about it nor any code that uses this until now.  It would be useful with factory methods.  I appreciate your calling this to my attention!

> The shadowing is *current* behavior in the language.  It is not something I propose.
> 
> Is this true? Can you provide a full example that works in the playground and demonstrates this? The hypothetical you paste already has certain ambiguous issues (e.g. `var foo` and `func foo()` cannot compile together because of redefinition).

Here is an example.  I tested it in an app rather than a playground (moving the print line into main).

struct Foo {
    //static var bar: Foo -> String = { _ in return "var" }
    static func bar(f: Foo) -> String { return "func" }
}
// prints “func”, but will compile and print “bar” if you uncomment the var
print(Foo.bar(Foo())) 


>  
> This would not refer to either.  It cannot refer to Foo.bar because Foo has nothing to do with the array you are mapping over.
> 
> The example I give works in the playground. Try it! :)

You are right here as well.  I didn’t read closely enough and didn’t notice the overload of map you added to Array.

If you remove that overload your code will fail to compile.  This is because the dot abbreviation is context sensitive.  It only works when the type system knows the type the expression is expected to produce.

Because of this context sensitivity no ambiguity would arise from the example you provided.  As you note, the type of the static property or method must always be Self, which is never going to be a function type.  This means that it is never going to have the same type as an unbound instance method (that its non-self arguments bound).  

Because of this the two shorthand notations will never be applicable in the same type context.  I can see how the similarity could be confusing but it is not ambiguous.  The potential confusion might even be enough to avoid introducing it into the language, but I’m not sure about that.  

I still think it’s an interesting idea.

Matthew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151216/fed42cb2/attachment.html>


More information about the swift-evolution mailing list