Today I finally had a chance to play with Python compilation support in the recent Fable alpha.
With the latest release, target languages have been expanded to include Python, Rust and Dart!
I did have a quick explore of the REPL after seeing the tweet announcing the alpha, but my eye was really caught by a comment underneath asking if it would be possible to import Python libraries to F#, and the answer that it should work just the same as JS.
I had quite a bit of success with this, however the API doesn't always exactly match the Python binding (although usually close) and of course every sample or guide online uses Python.
With Fable 4, the potential now existed to just use Python's TensorFlow bindings directly, so I decided to give it a go.
The steps I followed were
I initially faced issues as I had Python 3.7 on my machine. Then, after installing it, VSCode still defaulted to 3.7 for the interactive window. This is easy to switch in the GUI but it caught me out (and it resets after you close and open the IDE).
- Create a new folder and navigate to it using the terminal
- Install the Fable 4 dotnet tool preview
dotnet new tool-manifest dotnet tool install fable --local --version "4.0.0-snake-island-*"
- Install TensorFlow using pip
python -m pip install tensorflow-cpu
- Create an .fsx script
- Import Fable.Core from nuget
- Import Tensorflow
Once I had done that, I employed the (not recommended!) dynamic method calling Fable syntax, using a
? to query my CPU info.
#r "nuget: Fable.Core, 4.0.0-snake-island-alpha-007" open Fable.Core open Fable.Core.PyInterop [<ImportAll("tensorflow")>] let tensorflow: obj = nativeOnly tensorflow?config?list_physical_devices("CPU")
Now I just had to compile the script to Python using the Fable dotnet tool:
dotnet fable --lang Python "Fable 4 Python Example.fsx"
This outputs a file with the same name but a
.py extension in the same directory, plus a bunch of fable modules in a sub folder.
There is an optional nuget package called Fable.Python which contains bindings for the Python Standard Library as well as Jupyter, Flask and more - I just didn't need it here.
Right clicking on the
.py file and selecting
Run current file in interactive window executes the code and prints out the CPU info:
Remember to select Python 3.9 if you have more than one version installed!
I did continue to try porting the complete handwritten digit recognition sample from my previous TensorFlow blog. I managed to load the data and print it out in the console, but once I tried to create a model I hit a requirement of using named method arguments which I couldn't get to work with the quick-and-dirty dynamic invocation approach.
I think that the introduction of Python interop is a very exciting development in the F# space. It is no secret that the ML community is very established in the Python world, and therefore many of the most widely used and supported tools exist in that ecosystem. Combining them with the power and elegance of F#'s type system and syntax is an enticing prospect.
I'll continue to experiment with TensorFlow, perhaps starting a proper Fable binding to avoid the dynamic invocation.