> On Nov 10, 2017, at 4:20 PM, Joe Groff <[email protected]> wrote:
> 
> 
> 
>>> On Nov 10, 2017, at 4:12 PM, Charles Srstka <[email protected]> 
>>> wrote:
>>> 
>>> On Nov 10, 2017, at 5:51 PM, Joe Groff <[email protected]> wrote:
>>> 
>>> 
>>> 
>>>>> On Nov 10, 2017, at 3:45 PM, Charles Srstka <[email protected]> 
>>>>> wrote:
>>>>> 
>>>>> On Nov 10, 2017, at 5:36 PM, Joe Groff <[email protected]> wrote:
>>>>> 
>>>>> How `MyObject.foo(_:bar:)` gets implemented is its own business, as far 
>>>>> as the compiler is concerned. The compile-time name resolution for the 
>>>>> method isn't impacted.
>>>>> 
>>>>> -Joe
>>>> 
>>>> The compile-time name resolution for the method doesn’t happen *at all.*
>>> 
>>> You declared the method in your @interface, and the compiler saw that and 
>>> brought it in as what Swift considers to be a regular method, and your call 
>>> on the Swift side was resolved to it by Swift's usual lookup rules. To do 
>>> what Chris is suggesting requires changing the way calls get resolved in 
>>> the compiler before the call is even formed.
>> 
>> The only thing that makes this the “usual lookup rules” is that the 
>> Objective-C bridge has already been implemented.
> 
> As I mentioned in my original reply, I personally think the "importer" 
> approach would be superior, and that in a perfect world we'd have type 
> providers to make writing something like the ObjC importer but for a 
> different language or other dynamic data source something that doesn't 
> require invasive compiler hackery. The importer puts all of this:
> 
>> - It’s changing the compile-time name resolution! The Swift name is 
>> foo(bar:), but it’s changing that to fooWithBar:!
>> 
>> - It’s changing the signature! The argument took a String, but now it’s 
>> passing an NSString!
>> 
>> - It’s not resolving the method at compile-time! It’s passing the modified 
>> method name and the arg list to some objc_msgSend() function, which resolves 
>> it dynamically in a way that user code can intercept and interpret at 
>> runtime!
>> 
>> I’m just not seeing the conceptual difference here.
> 
> below the fold as far as the rest of the language is concerned. You could 
> just as well written what the importer synths up in Swift directly:
> 
> func foo(bar: String) {
>  unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
> }
> 
> and the rest of the language would be none the wiser.

Though, since you bring up objc_msgSend, the way it works in ObjC might be a 
better fit for Swift's name lookup model, since their keyword argument models 
are similar. If Swift had a 'method of last resort' like ObjC's, say as a 
strawman you could overload the '.' operator, then you could use it to provide 
an implementation for a method given a compound name in a similar way. So if 
you had:

struct Dynamic { func .(methodName: String) -> (Any...) -> Int }

let x = Dynamic()
x.foo(x: 0, y: 1)

Then, when we do name lookup into x for foo(x:y:) and that fails, we'd fall 
back to turning this into x.`func .`("foo(x:y:)")(0, 1). It would take a bit 
more work to turn this into something like a Python call, but would fit Swift's 
language model better.

-Joe


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to