TensorFlow is a well-established player in the deep learning framework field. First, it works pretty damn well. Second, it’s a Google product that’s easily found throughout their own ecosystem (including Android, Chrome, and a slew of apps). Lastly, the TensorFlow team been very respectful of and responsive to both the researcher community as well as the commercial/production community.
The latter reason is why I admire Swift for TensorFlow. Google identified Python’s foreseeable scaling wall and is responding by pulling in a well-established—yet modern—language into their ML toolset. However, as if avoiding re-inventing the wheel once wasn’t enough, they also recognized that Python still very much plays a major role in ML and will continue to do so moving forward.
Hence, the need to include Python interoperability into Swift.
How It Works
To give some background on how this works, here’s a quick summary on how this is possible under the hood, and how Swift allows devs to use Python (near-fluently) in code.
Match Made in C
Swift was made with the goal of language interoperability in mind. In particular, working with C and Obj-C were a few of the original goal languages. Since the former is baked in, however, it actually helped the team at Google when it approached Python. According to their white paper, Python’s own C interface acts as the bridge so that a “Swift script/program simply links the Python interpreter into its code”.
The last piece of the puzzle, then, was to allow developers to interact with Python in as familiar a way possible within their Swift code. To do this, they created a struct called PythonObject. This links Swift to essentially any Python value during runtime and handles passing on values and commands to and from Python.
Basics of Python in Swift
Now that we know what’s happening behind-the-scenes, let’s take Python for a spin in Swift.
The easiest way to get started is to actually play around in a Google Colab notebook. Colab notebooks are primarily used for Python, but they’re also set up to run Swift, as well (think Swift Playgrounds but in a Python-styled notebook).
Importing Python is as simple as… well… importing Python! It’s as simple as importing any other Swift package. Let’s do that now and also see which version Colab is currently defaulting to:
Importing and Using Python Packages
A primary reason we’d be interested in Python interoperability is to leverage the rich and well-established packages written in Python. Particularly, there are some key packages from the data science community that are commonplace.
Fortunately, importing the packages we’ve come to know and love is also as straightforward as just importing them, only doing so through our Python library.
When we do, the package is imported as a PythonObject, so we set it to a Swift variable (much like we would set it to a variable in Python).
When we go to use our package, however, we can use it as if we were writing a command in Python. Any results would come back as aPythonObject.
Running Python Operations
If Swift detects that we’re working with a PythonObject, it will pass operations over to Python to handle.
This translates to packages that handle operators themselves, such as NumPy ufuncs.
Converting to/from Python and Swift Objects
The last bridge to be crossed in Swift/Python interop is converting objects between the two languages. If we want our Swift data to be manipulated in Python and then expect to bring it back to be used in Swift code, conversion is essential.
Fortunately, this, too, is rather simple.
Take the example below. We set a number of PythonObjects to a number of Swift objects, yet they’re automatically converted to Python objects.
And then we can go back to Swift.
The last feature I’ll show off is using matplotlib with Swift. This is more exclusive to using Swift and Python in Google Colab, but it’s still pretty cool. First, we need to run a special command to enable displaying plots in Google Colab:
Then, we can simply set up a plot and display it in-line!
While having Python interoperability is incredibly useful, there are certain limitations. These are constantly being addressed by the S4TF team and the Swift community, as a whole.
However, I think it’s worth noting that, if you do seem to hit a roadblock trying to make a line of Python work in Swift, perhaps the simplest workaround is creating your own Python package. Wrap the code you’re wanting to use into functions and classes that minimize complexity on the Swift side, and then simply import it into Swift and call your custom code.
At the end of the day, we’re trying to leverage Python for a much larger (and Swift-y) picture, so massaging and modularizing your code to achieve your goals just makes sense.
It’s a great time to be in data science, AI, and ML. Whether you’re a fan of Swift, S4TF, or even Python (but wanting to get into Swift/S4TF), my hope is that you can still appreciate the work that has been done to build this interoperability.
Not only does it display the power and flexibility of Swift, but it also humbly recognizes Python’s significance well into the future. It unites the new and the old to create a richer future for tech!