[swift-evolution] Spread Operator as Shorthand for Map

Stephen Celis stephen.celis at gmail.com
Wed Dec 16 22:48:59 CST 2015


> On Dec 16, 2015, at 11:28 PM, Matthew Johnson <matthew at anandabits.com> wrote:
> 
> 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!

I think it's described, but obviously not clearly enough. Might be worth opening a bug requesting better documentation around the behavior.

>> 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())) 

Ah, yeah, the fact that there are arguments disambiguates (which is interesting in itself). If you make a variable and then a function without arguments, per your earlier example, it won’t compile:

    struct Foo {
        //static var bar: String = "var"
        static func bar() -> String { return "func" }
    }
    // prints "func" and won't compile 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.

Of course :) And if the overload stays and your suggested syntax were added, it would be ambiguous and also fail to compile.

> 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.

This was my exact point earlier. It's unlikely to be ambiguous (because context _generally_ disambiguates), but in the examples I give, they certainly are ambiguous (and thus can be).

My general stance remains that, while an interesting idea, adding a second behavior around dot abbreviation causes more confusion than it's worth (especially given that the behavior is not well understood—this thread being an example), and that {$0.whatever} is not a big burden over (.whatever).

Stephen

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


More information about the swift-evolution mailing list