[swift-evolution] [Proposal Idea] dot shorthand for instance members

Radosław Pietruszewski radexpl at gmail.com
Sat Dec 19 02:19:53 CST 2015


> anArray.map(.hasPrefix(“foo”))

I’m against this. Yes, it extends the functionality of the proposal even more and could allow for more closures to be rewritten in this style — but at a severe cost in clarity IMHO.

I mean, with `map(.aMethod)`, you’re passing a reference to a method available on the receiver. This is actually very similar to passing `foo(.EnumCase)`, as in both cases we’re accessing a static member of the type. (Yes, also with the former example if you consider instance methods as curried functions on the type that take self as the first parameter.) So, there’s some nice symmetry and predictability, even if the dot-syntax has more than one use.

But with `map(.hasPrefix(“foo”))`, you’re implicitly constructing a new closure, that calls a method, and passes an argument. This isn’t immediately obvious. There’s no symmetry. It looks as if I was passing the result of calling some method, and the dot at the beginning meant something else (cf the se-0009 review thread). I couldn’t figure easily figure out that this is actually implicit contents of a new closure.

The potential for confusion is great. I’m not convinced the benefit outweighs the cost here.

— Radek

> On 19 Dec 2015, at 02:10, Matthew Johnson <matthew at anandabits.com> wrote:
> 
> 
>> On Dec 18, 2015, at 1:36 PM, Radosław Pietruszewski <radexpl at gmail.com> wrote:
>> 
>> Interesting! I’d definitely be for some shortcut syntax here, as this seems to be a very, very common pattern. Passing a function to, say, `map` is so much easier and cleaner than passing a method in Swift — even though Swift generally always prefers methods to functions!
>> 
>> I haven’t spent too much thinking this through, but I think this is sound.
>> 
>> For contexts where a T is expected, .foo means T.foo
>> 
>> But it’s not ambiguous here, because we’re expecting T -> U here, and functions can’t have static members (or any members for that matter :P). So passing a .foo could unambiguously mean T.foo(T) — an instance method on T, returning U.
>> 
>> I’d be for dropping the parens, they seem unnecessary, and are confusing (we’re passing a function, not calling it). It should be unambiguous with properties since methods and properties share a name space.
>> 
>> And, speaking of, I’d also just make it work with properties with the same syntax. So array.map(.foo) would call $0.foo() if `foo` is a method, or $0.foo if `foo` is a property.
> 
> I probably should have showed more examples in my original post.
> 
> Making this work with property getters was one of the examples I posted in the other thread:
> 
> anArray.map(.aProperty)
> 
> The reason I used parentheses in the example of a method that takes no argument is that what we’re actually doing is binding the non-self arguments.  This is more clear with an example of a method that does take additional arguments:
> 
> anArray.map(.hasPrefix(“foo”))
> 
> I hadn’t tried declaring property and no argument method with the same name until you said this.  You are correct that it’s unambiguous. I didn’t realize this when I first posted this idea.  
> 
> If we don’t omit them it’s always clear whether we are passing a property or a method.  I think requiring the parentheses is probably worth the syntactic cost.  It also allows for a straightforward rewrite to a closure by wrapping the expression in braces and placing $0 prior to the dot.
> 
>> 
>> (Am I missing something?)
>> 
>> — Radek
>> 
>>> On 18 Dec 2015, at 04:27, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> Swift currently offers dot shorthand for static members of type Self in type contexts expecting a value of the type in question.  This is most commonly used with enum cases.
>>> 
>>> Swift does not currently offer shorthand for instance members.  Introducing a shorthand for instance members would improve clarity and readability of code in common cases:
>>> 
>>> anArray.map{$0.anInstanceMethod()}
>>> 
>>> becomes:
>>> 
>>> anArray.map(.anInstanceMethod())
>>> 
>>> This shorthand would work in typing contexts expecting a single argument function.  It would allow abbreviated access to any visible instance property getter or instance method on the type of the argument.  Of course the return type would need to match the return type expected by the context or a type mismatch compiler error would occur.
>>> 
>>> The readability advantage is arguably small but it does exist.  The feature also aligns very well with an existing language feature.
>>> 
>>> I think it’s an interesting idea and am wondering whether others feel like it is something worth pursuing or not.
>>> 
>>> Matthew
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 



More information about the swift-evolution mailing list