Hey, this is my first post. I created this gentle intro to Swift in Goolge Colab . Let me know if we can build on it and make it better.
https://colab.research.google.com/github/zaidalyafeai/Notebooks/blob/master/TF_Swift.ipynb
Hey, this is my first post. I created this gentle intro to Swift in Goolge Colab . Let me know if we can build on it and make it better.
https://colab.research.google.com/github/zaidalyafeai/Notebooks/blob/master/TF_Swift.ipynb
Great start! A couple of things I noticed:
struct
is used more often than class
- although perhaps show bothprotocol
and extension
are used frequently in swift including the lesson notebooks, so should be coveredmap
, filter
, and reduce
are important to mention; at the same time you can mention closures, including the neat trailing closure syntaxThey have steps to install nightly versions in Colab, but the procedure needs to be repeated after the runtime is recycled
What’s interesting, using similar approach it should be possible to register any custom jupyter kernel (e.g. Julia) in Colab, which is pretty cool! I thought it’s more restrictive.
@jeremy the current version in Colab is Swift version 5.0-dev. I am not sure what is the latest version.
The issue isn’t swift, it’s s4tf. We’re updating the nightly every night at the moment. Last night’s is the 1st that runs all the notebooks successfully!
Added structs, closures, operator overloading, protocols and extensions.
I created a new notebook for training MNIST
https://colab.research.google.com/github/zaidalyafeai/Notebooks/blob/master/TF_Swift.ipynb
Nice notebook!
In case you haven’t seen it, here’s “A Swift Tour” in notebook form. It’s originally from the “Swift Programming Language” Book and covers Swift but not machine learning.
@dan-zheng, yes I am aware of that notebook. I included similar examples from there. I tried to make the notebook light with minimum details to introduce the bits needed for machine learning.
@dan-zheng, btw, any idea how to run bash commands in colab when the kernel is Swift. Both % and ! don’t work.
Good question! We don’t have a %run
directive for running arbitrary commands yet.
That would be certainly a nice feature for swift-jupyter
- we discussed it before but no one is working on it.
cc @marcrasi who leads swift-jupyter
: how do you feel about adding %run
? It could be a nice starter issue.
In the meantime, you could use Foundation (example from Stack Overflow) or Python to run commands.
import Foundation
@discardableResult
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
shell("ls", "-alh")
import Python
let subprocess = Python.import("subprocess")
...
I actually go around that by creating two notebooks one with python(running commands) and the other with swift because they operate on the same environment. Happy to work on it if it is straight forward.
I think it should be implemented as a Swift library instead of as a part of the kernel, because you can get quite nice syntax as a Swift library (e.g. the "/bin/ls".shell("/")
implemented in https://github.com/fastai/fastai_docs/blob/master/dev_swift/00_load_data.ipynb is a quite nice start, I think), and it keeps complexity out of the kernel implementation.
Yeah, creating a Swift library with some nice syntax would be pretty straightforward! Write some function(s) that execute commands using Foundation. You might want to figure out some way to get a shell to parse the command, so that users can just write a single shell command instead of having to write the exact binary path and manually split out the arguments. Then distribute them as a SwiftPM package. Then anyone can use this in their notebook using an %install
directive.
(%install
doesn’t work in Colab yet, but a new version of the kernel that supports %install
should be released in Colab around Tuesday)
@marcrasi I don’t quite get why it is better to create a library rather than enabling it directly in the kernel (complex ? )
I find it a bit not intuitive to make functions calls for simple commands like !wget, !tar , etc …
It’s possible to define functions that make it look almost like !wget, !tar, etc:
prefix func ! (_ command: String) {
print("Executing command: \(command)")
}
!"wget foo"
// prints "Executing command: wget foo"
Since it’s possible to get so close to !wget
I think there’s not enough extra value in getting all the way to !wget
to balance the extra complexity that it would add to the kernel.
Here’s some more detail about why I want to avoid extra complexity in the kernel:
%install
, %include
, etc) is pretty complicated, with some tricky bug-prone logic required to parse and execute them in exactly the right order, and to show good error messages when something goes wrong. More directives would make it worse. (In fact, I’m pretty interested in removing %include
, which might be possible now that we have %install
).Thanks a lot for the details. I was also thinking of using the prefix notation. I will try to work on that asap.
Some time ago I’ve made simple shell library for myself, feel free to fork and hack on it
btw, %install works in colab if you update to nightly as described here.
Upd: I liked prefix bang function so much and added it too, thanks @marcrasi
That will be a great starting example, Thanks!
So, a prefix bang definition would look like this, right?
import Python
let shell = Python.import("subprocess").getoutput
prefix func ! (_ command: String) {
print(shell(command))
}
!"ls -al"