> On Nov 1, 2017, at 03:14, Richard Wei via swift-evolution 
> <[email protected]> wrote:
> 
> 
> 
>> On Oct 31, 2017, at 21:31, Chris Lattner via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Also, for sake of discussion, we’d have to figure out what the type of 
>> MemberLookupResultType would be for Python.  I can see several choices:
>> 
>> 1) Make it return a  "PythonObject!”
>> 2) Make it strict, returning a PythonObject or trapping.
>> 3) Make PythonObject itself nullable internally and return a null 
>> PythonObject.
>> 
>> #1 matches Python semantics directly, because it allows clients who care to 
>> check, but those who don't can ignore it.  The only problem I anticipate is 
>> that it will break things like:
>> 
>> let x = foo.bar
>> let y = x.thing   // fails, because x implicitly promoted to PythonObject?
>>  
>> #3 is gross and cuts against lots of things in Swift (recall when 
>> UnsafePointer itself was implicitly nullable, lets not go back to those bad 
>> old days).  I think that #2 is the least bad tradeoff.
> 
> I agree, PythonObject-or-die is the right trade-off.
> 
>> 
>> Yes, something like this is what I had in mind, but I think that 
>> functionName should only be required to be StringLiteralConvertible (no need 
>> to actually synthesize a real swift string).
>> 
>> 
>> Since you bring it up, Python exceptions will be annoying - As with other 
>> languages, Python can throw from an arbitrary expression.  Modeling 
>> everything as throws in Swift would be super-annoying and unergonomic for 
>> the programmer, because we'd require 'try' everywhere.  Thoughts on what to 
>> do about that are welcome!
> 
> Requiring ‘try’ on every statement is annoying, but not having the ability to 
> catch python exceptions is annoying too. We could probably make python 
> exception handling an opt-in feature. For example:
> 
> try Python.do {
>     let a = np.array([1, 2, 3])
>     let b = np.array([[2], [4]])
>     print(a.dot(b)) // matrix mul with incompatible shapes
> }
> catch let error as PythonException {
>     // Handle PythonError.valueError(“objects are not aligned”)
> }

To correct my example: 

do { 
    try Python.do {
        let a = np.array([1, 2, 3])
        let b = np.array([[2], [4]])
        print(a.dot(b)) // matrix mul with incompatible shapes
    }
}
catch let error as PythonException {
    // Handle PythonError.valueError(“objects are not aligned”)
}

Maybe ‘Python.do {}’ should be called something like ‘Python.safely {}’.

-Richard

> 
> Python.do enables exception handling for statements in the body, declared as
> func `do`<T>(_ body: () throws -> T) throws -> T
> 
> When we execute python-throwing statements inside a Python.do{}, 
> PythonException gets thrown. Otherwise, it traps.
> 
> The ‘Python.do’ function would ask the python overlay to enter an 
> "error-catching" state when executing the body closure. We make PythonObjects 
> internally nullable, but guarantee that they are non-null (or trap) when the 
> overlay is not in the “error-caught” state. When a python exception is thrown 
> in the error-catching state, the overlay enters the error-caught state and 
> propagates null through any python computation in the body closure. After the 
> body is executed, throw that python exception.
> 
> However, if there’s a throwing Swift statement after the throwing python 
> statement in the body, the python exception won’t be caught first… So having 
> the body as a non-throwing closure may be a better idea.
> 
> -Richard
> 
>> 
>>> 
>>> class Dog:
>>> 
>>>     def __init__(self, name):
>>>         self.name = name
>>>         self.tricks = []    # creates a new empty list for each dog
>>> 
>>>     def add_trick(self, trick):
>>>         self.tricks.append(trick)
>>> 
>>> With your don’t-modify-the-compiler approach, how can I create a Dog 
>>> instance and add a trick? I probably need to look up the class by name, 
>>> call __init__ manually, etc.
>>> 
>>>   let dogClass = python_getClassByName(“Dog”) // implemented in the Python 
>>> “overlay’, I guess
>>>   let dog = python_createInstance(dogClass)  // implemented in the Python 
>>> “overlay’, I guess
>>>   dog.__init__(“Brianna”)      // uses CustomCallable’s callMember
>>>   dog.add_trick(“Roll over”)  // uses CustomCallable’s callMember
>> 
>> I-am-not-a-python-expert, but I'd expect this to work:
>> 
>>      let dogModule = Python.import("DogModule")
>>      dogModule.Dog("jckarter").add_trick("SILGenGen”)
>>      let dog = dogModule.Dog(“Brianna”)
>>      dog.add_trick(“Roll over)
>> 
>> or equivalently:
>> 
>>      let Dog = Python.import(“DogModule.Dog")
>>      Dog("jckarter").add_trick("SILGenGen”)
>>      let dog = Dog(“Brianna”)
>>      dog.add_trick(“Roll over)
>> 
>> Seems pretty nice to me, with zero “Swift compiler knowledge of Python” 
>> required.
>> 
>> 
>>> With compiler integration, 
>>> 
>>>     class Dog : PythonObject {
>>>       init(_ name: Pythonable)
>>>       func add_trick(_ trick: Pythonable)
>>>     }
>> 
>> Something like this is possible, but would be substantially more work, be 
>> substantially more invasive, and would set the precedent that every other 
>> dynamic language would get support hacked directly into Swift.  The only 
>> reason I can see this being useful is if we wanted to support the optional 
>> typing annotations in Python.  While this would be "nice to have", I think 
>> the cost/benefit tradeoff involved is totally wrong for Swift. 
>> 
>>> With either the true “Python importer” solution or this code-generation 
>>> solution, you at least get some level of code completion and basic sanity 
>>> checking “for free”. In other words, you get some of the benefits of having 
>>> a statically-type-checked language while still working on dynamic 
>>> Pythonable types.
>> 
>> We don't need to make Swift better at Python than Python itself is :-)
>> 
>> -Chris
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to