[swift-evolution] [Pitch] Flattening the function type of unapplied instance methods

Chris Lattner clattner at apple.com
Thu Feb 25 18:22:23 CST 2016

> On Feb 25, 2016, at 9:13 AM, Joe Groff <jgroff at apple.com> wrote:
>> On Feb 24, 2016, at 8:50 PM, Chris Lattner <clattner at apple.com <mailto:clattner at apple.com>> wrote:
>> None of these are really great.  Since you’re advocating for it, I’m very concerned about making partially applied methods be uncurried always (#2).  I have seen a *lot* of people use curried methods on classes (in particular) and this leads to some pretty elegant patterns.  I’d expect any serious discussion of changing this behavior to include a survey of what people are actually using this for, and whether the end result we’d get from this change would be better or worse overall (not just in a single case).
> I'm concerned about that too, but I think most of these use cases are already impeded by removing tuple argument splatting, since that makes it impossible to make a generic method transformation like `alterMethod<Receiver, Args, Ret>(method: Receiver -> Args -> Ret)`. I think these use cases can be recovered on flattened methods by explicit variadic splatting, since you could then write `alterMethod<Receiver, Args, Ret>(method: (Receiver, Args...) -> Ret)` instead.

I don’t really understand that, because the use-cases I’ve seen aren’t in generic context’s, but let me step back and see if I understand your proposal.  Here’s your example again:

> struct Bar {
>   var x = 0
>   mutating func bar() { x += 1 }
> }
> let a = Bar.bar

I believe that you’re proposing that “a” have type "(inout Bar) -> ()” since the empty argument list got flattened into the self argument.

However, what is the type of the partial application case, i.e. “someBarInstance.bar”?

It seems that this *has* to be invalid for mutating methods, and it is the most commonly curried forms that I’ve seen for classes.

I would be extremely nervous about saying that partial application and the raw name disagree, and I really wouldn’t want to kill partial application for classes and non-mutating methods.

I think that the least bad answer here is to just have sema reject attempts to get the base name of the mutating methods.  In fact, my memory was partially right.  We *are* already rejecting the partial application case:

  5> var b = Bar()
b: Bar = {
  x = 0
  6> b.bar
repl.swift:6:3: error: partial application of 'mutating' method is not allowed

so I think that we are just missing a simple case that we should be rejecting here.


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

More information about the swift-evolution mailing list