[swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

Richard Wei rxrwei at gmail.com
Wed Nov 1 05:20:29 CDT 2017


> On Nov 1, 2017, at 03:14, Richard Wei via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> 
>> On Oct 31, 2017, at 21:31, Chris Lattner via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> 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
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171101/9f9b2cf3/attachment.html>


More information about the swift-evolution mailing list