Why I prefer Swift over Javascript
The other day while I was adding the ability to generate the protocol file to my Sketch plugin I took the opportunity to make a couple of changes to the code.
In this post I want to talk about what those changes are and why they made me continue thinking that static typed languages are what I like, or in other words, why I prefer Swift over Javascript.
TL;TR: The things that I liked about Javascript are easily replaced by Swift at the same time that it gives me the safety that I like.
The first change that I made was to remove the duplication of code that came from generating multiple files from the same sections. (Sections in that script refers to the container of all the colors to export. So you can translate Sections to colors.)
headerGen += "#pragma mark - " + section.name
headerGen += newLine
impGen += "#pragma mark - " + section.name
impGen += newLine
Obviously that had to be change. What I did was move that part of the code to it’s own function that generates the code for a single file. It receives a Config object that contains some options, for example if it’s a header or an implementation file.
{
path: ...,
template: ...,
implementation: false
}
The second thing that I wanted to do was to generalize the exporting in a way that could accept different languages or any kind of exporting (Swift, XML, images…).
To accomplish that the main export function accepts an Exporter function and by itself doesn’t do anything fancy at all. It just loops over the different configs and calls that function with a specific config and the sections to export.
Then you just have to implement a function with that signature and provide the different configs that you want.
When I missed Swift…
While doing all of those changes I encountered the same problems that I talked in my previous post about the Script. Mainly a lack of a type system.
Dynamic objects is the most fancy thing about Javascript. You can see how in that script I just create literal objects and everything works. But that comes with a price. The function that uses those objects has to know how to access those properties, an there is no one to help with that. Is not weird at all that web developers want to have the declaration and the usage of the objects in the same place.
To me that speed that you gain with dynamic objects is easily replaceable with Swift structs. They are super easy to create, no need for all the boilerplate like .m and .h files. It also has the literal syntax to create arrays and objects. And still you have the compiler helping you to make sure that the usage of the objects is correct.
struct ObjCConfig {
let name: String
let isImplementation: Bool
let template: String // adding this afterwards is easy, the compiler tells you what needs to change!
}
The other important aspect of Javascript is passing functions around and closures. It was the think that I liked the most abut it in the old days, when we didn’t have blocks in Objective-C, but now any modern language has functions as a first-class citizen.
We can implement the Objective-C exporter function:
func objCExporter(config: ObjCConfig, sections: [Section]) -> () {
// export...
}
And pass the function to the main export function:
exportTheme(configs, sections: sections, export: objCExporter)
Even better, we can use typealias and generics to generalize the main export function in order to make it work with any exporter but still keep it safe.
class Plugin<ConfigType> {
typealias Exporter = (config: ConfigType, sections: [Section]) -> ()
class func exportTheme(configs: [ConfigType], sections: [Section], export: Exporter) {
for config in configs {
export(config: config, sections: sections)
}
}
}
The ConfigType
generic type enforces that the type of the configuration objects is the same type that the export function accepts.
Plugin.exportTheme(configs, sections: sections, export: swiftExporter) // error
So yes. The things that I liked about Javascript are easily replaced by Swift at the same time that it gives me the safety that I like.