[swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

Chris Lattner sabre at nondot.org
Sat Nov 11 12:33:36 CST 2017



> On Nov 11, 2017, at 10:15 AM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> 
> On Nov 11, 2017, at 10:04 AM, Chris Lattner <sabre at nondot.org <mailto:sabre at nondot.org>> wrote:
> 
>> 
>> 
>>> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>>> 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
>> 
>> In fact, this is the subject of the next proposal that I will write up when I have time.
> 
> It seems to me like a dynamic method-of-last-resort feature would subsume this proposal. Out of curiosity, why would we need both?

It seems that you missed the "[Discussion] Swift for Data Science / ML / Big Data analytics” thread, in which a lot of context was discussed, as well as multiple design approaches.  In any case, I will summarize here:

There are two fundamental operations that need to be supported to make a big impact on dynamic language interop: member lookup and calls.

Many languages treat these as separable concepts.  In Python for example, these are equivalent:

	return foo.bar(x: 1, 23, y: 17)
and:
	a = foo.bar
	return a(x: 1, 23, y: 17)

Swift and the other Smalltalk inspired languages are the odd ones out who tie method arguments into the base name of a function.  With no language changes, it is possible to implement a pretty reasonable Python interop layer with the call and member operations explicit, it looks like this:

	func example(foo : PyVal) -> PyVal {
	  return  foo.get(member: “bar”).call(args: (“x”, 1), (“”, 23), (“y”, 17))
	}

and while it is totally possible to sugar common cases, e.g.:

	func example(foo : PyVal) -> PyVal {
	  return  foo.call(member: “bar”, args: (“x”, 1), (“”, 23), (“y”, 17))
	}

you still need to support the basic model because Python supports currying and has global functions with keyword arguments.  FWIW, Perl follows a similar model, but doesn’t have keyword arguments.

I don’t really care much about the implementation approach (if this proposal isn’t the right one, fine!) but it is important to get this down to:

	func example(foo : PyVal) -> PyVal {
	  return  foo.bar(x: 1, 23, y: 17)
	}

which I hope you’ll agree is a *HUGE* readability and writability benefit, so much so that users would reject the long hand notion.


The discussion phase in the previous thread considered several approaches, including burning python specific support in, implementing a python importer, and implementing a single “dynamic thing” protocol.  These are all bad ideas for reasons described in the thread.  If you’re curious, I’m happy to elaborate in alternatives considered.

As such, discussion converged on pitching two proposals, which are generally useful beyond this niche:

1. The dynamically callable one already written.
2. A dynamically member lookupable proposal to sugar things like foo.get(member: “bar”) - and the corresponding setter.

The former one is presumably useful for things outside dynamic languages, e.g. implementing dynamic “proxy” type interfaces.
The second one is useful for far more than just dynamic languages, e.g. sugaring json keypath traversals.


-Chris



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


More information about the swift-evolution mailing list