To Chris’s use case point, I see Python -> Swift interop as a very common use 
case in data science / ML for speeding up certain functions/modules by 
embedding Swift into Python, like you can with, say, ctypes or python 
extensions in dynamic C libraries. This is very common practice in the Python 
universe, it just could be a lot better with Swift instead.

Things like this *sort of* exist with Swift 
(https://gist.github.com/jiaaro/e111f0f64d0cdb8aca38 
<https://gist.github.com/jiaaro/e111f0f64d0cdb8aca38>), but it’s not really 
very mature or functional.

I would LOVE to be able to speed up a lot of python code by implementing swift 
libraries and importing into python. 

- David

> On Oct 30, 2017, at 13:25, Douglas Gregor via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
> 
>> On Oct 29, 2017, at 1:34 PM, Chris Lattner via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Oct 29, 2017, at 8:23 AM, Chris Lattner via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>>> On Oct 29, 2017, at 4:04 AM, Lukas Stabe <lu...@stabe.de 
>>>> <mailto:lu...@stabe.de>> wrote:
>>>> 
>>>>> On 28. Oct 2017, at 23:10, Chris Lattner via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> … which is to say, exactly identical to the Python version except that 
>>>>> new variables need to be declared with let/var.  This can be done by 
>>>>> blessing Python.Object (which is identical to “PyObject*” at the machine 
>>>>> level) with some special dynamic name lookup behavior:  Dot syntax turns 
>>>>> into a call to PyObject_GetAttrString, subscripts turn into 
>>>>> PyObject_GetItem, calls turn into PyObject_Call, etc.  ARC would be 
>>>>> implemented with INCREF etc.
>>>> 
>>>> That sounds like a very interesting prospect. Do you think it would make 
>>>> sense to make the language features that facilitate this (dynamic dispatch 
>>>> of method calls, property accesses, subscript and ARC) available to Swift 
>>>> classes annotated in some way, so that interop like this can be 
>>>> implemented as a library without special treatment by the Swift compiler? 
>>>> This could also enable more dynamic DSL like features.
>>> 
>>> I haven’t explored enough of the design space to be sure, but I’d want to 
>>> make sure that a library version of this could be done without giving up 
>>> ergonomics of the result.  If you were interested in being able to interop 
>>> with other languages that are dynamically typed and reference counted, then 
>>> something like this could be possible in principle:
>> 
>> Thinking about the Perl case makes it clear to me that this should not be 
>> built into the compiler as a monolithic thing.  Perl supports several 
>> different types (SV/AV/HV) which represent different concepts (scalars, 
>> arrays, hashes) so baking it all together into one thing would be the wrong 
>> way to map it.  In fact, the magic we need is pretty small, and seems 
>> generally useful for other things. Consider a design like this:
>> 
>> 
>> // not magic, things like Int, String and many other conform to this. 
>> protocol Pythonable {
>>  init?(_ : PythonObject)
>>  func toPython() -> PythonObject
>> }
> 
> It’s not magic unless you expect the compiler or runtime to help with 
> conversion between Int/String/etc. and PythonObject, as with 
> _ObjectiveCBridgeable.
> 
>> 
>> // Not magic.
>> struct PythonObject : /*protocols below*/ {
>>   var state : UnsafePointer<PyObject>
>> 
>>   subscript(_ : Pythonable…) -> PythonObject {
>>     ...
>>   }
>> }
>> 
>> // Magic, must be on the struct definition.  
>> // Could alternatively allow custom copy/move/… ctors like C++.
>> protocol CustomValueWitnessTable {
>>  static func init(..)
>>  static func copy(..)
>>  static func move(..)
>>  static func destroy(..)
>> }
> 
> Swift’s implementation model supports this. As a surface-level construct it’s 
> going to be mired in UnsafeMutablePointers, and it’s not at all clear to me 
> that we want this level of control there. Presumably, binding to Python is 
> going to require some compiler effort—defining how it is that Python objects 
> are initialized/copied/moved/destroyed seems like a reasonable part of that 
> effort.
> 
>> // Magic, allows anyobject-like member lookup on a type when lookup 
>> otherwise fails.
>> protocol DynamicMemberLookupable {
>>   associatedtype MemberLookupResultType
>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>> }
> 
> AnyObject lookup looks for an actual declaration on any type anywhere. One 
> could extend that mechanism to, say, return all Python methods and assume 
> that you can call any Python method with any PythonObject instance. AnyObject 
> lookup is fairly unprincipled as a language feature, because there’s no 
> natural scope in which to perform name lookup, and involves hacks at many 
> levels that don’t always work (e.g., AnyObject lookup… sometimes… fails 
> across multiple source files for hard-to-explain reasons). You’re taking on 
> that brokenness if you expand AnyObject lookup to another ecosystem.
> 
> Although it doesn’t really seem like AnyObject lookup is the thing you’re 
> asking for here. It seems more like you want dynamicMemberLookup(_:) to 
> capture “self” and the method name, and then be a callable thing as below...
> 
>> 
>> // Magic, allows “overloaded/sugared postfix ()”.
>> protocol CustomCallable {
>>  func call( …)
>> }
>> 
>> The only tricky thing about this is the call part of things.  At least in 
>> the case of python, we want something like this:
>> 
>>   foo.bar(1, 2, a: x, b: y)
>> 
>> to turn into:
>>  foo.dynamicMemberLookup(“bar”).call(1, 2, kwargs: [“a”:x, “b”:y])
>> 
>> We don’t want this to be a memberlookup of a value that has “bar” as a 
>> basename and “a:” and “b:” as parameter labels.
> 
> Well, I think the MemberLookupResult is going to get the name “bar”, argument 
> labels “_:_:a:b:”, and arguments “1”, “2”, “x”, “y”, because that’s the Swift 
> model of argument labels. It can then reshuffle them however it needs to for 
> the underlying interaction with the Python interpreter.
> 
> There are definite design trade-offs here. With AnyObject lookup, it’s a 
> known-broken feature but because it depends on synthesized Swift method 
> declarations, it’ll behave mostly the same way as other Swift method 
> declarations—static overloading, known (albeit weak) type signatures, etc. 
> But, it might require more of Python’s model to be grafted onto those method 
> declarations. With dynamic member lookup, you’re throwing away all type 
> safety (even for a motivated Python developer who might be willing to 
> annotate APIs with types) and creating a general language mechanism for doing 
> that.
> 
>       - Doug
> 
>> 
>> -Chris
>> 
>>> 
>>> protocol DynamicDispatchable { // Protocol is “magic" known by the compiler.
>>> func retain()
>>> func release()
>>> func memberLookup(_ : String) -> Self
>>> func subscript<T>(_ : T) -> Self
>>> func call(_ args: [Self]) -> Self
>>> } 
>>> 
>>> module Python {
>>> struct Object : DynamicDispatchable {
>>>   var state : UnsafePointer<PyObject>
>>> 
>>>   func retain() {
>>>      INCREF(self)
>>>  }
>>> 
>>>    func memberLookup(_ : String) -> Object {
>>>       PyObject_GetAttrString(…)
>>>    }
>>>   etc
>>> }
>>> 
>>> module Perl5 { 
>>>  struct Object : DynamicDispatchable {
>>>   var state : UnsafePointer<SV>
>>> 
>>>   func retain() {
>>>      SvREFCNT_inc(self)
>>>  }
>>> ….
>>> 
>>> 
>>> 
>>> Are there other uses for such a thing?
>>> 
>>> -Chris
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to