Search code examples
javascriptswifttranspiler

Swift to JavaScript transpiler - possible?


As an iOS developer coding in Swift, I find it increasingly annoying to have to coordinate the same code written in Swift with front-end developers coding in JavaScript. It would be much neater to implement common functionality in one place and then translate to JS, right?

I've started to wonder if a Swift to JS compiler was feasible? Perhaps not to share the full code, but some generic common functions at least.

I found this transpiler online: SwiftJS. Sadly, this one doesn't really cut it.

The following code:

let a = [1, 2]
print(a.count)

returns Invalid Swift code in the demo. Which doesn't instill confidence. Never mind the more intricate bits like optionals or function overloading.

I was wondering about starting a transpiler project, but then I realised there were many pitfalls. For instance this code:

var a = [1, 2]
var b = a
b.append(3)

should make a equal to [1, 2] and b equal to [1, 2, 3]. In JavaScript, both would be [1, 2, 3] as they're passed by reference and not by value.

Would it be at all possible to write a proper transpiler?


Solution

  • One has to wonder if it makes any sense to write a Swift to JavaScript transpiler, as the languages don't map 1:1. There are many pitfalls besides the ones you've mentioned (e.g. inout parameters or function overloading). There's already some viable alternatives, such as using Haxe/Kotlin to transpile both to JavaScript and Swift, or developing cross-platform apps in Xamarin/React Native.

    That being said, both languages share many common best practices as well as have a rather substantial feature overlap (e.g. closures/assigning functions to variables). I don't think there are any features that would be impossible to transpile, although some resulting code could be quite messy.

    There is also a distinct advantage over using e.g. Kotlin - you would be able to grab an existing Swift project and transpile it into JS, without having to make the decision to write in Kotlin beforehand. And it's one language less you need to learn.

    I have started a transpiler project with live preview myself that I think is an improvement over ShiftJS. It will indeed handle the cases you've mentioned (including passing arrays/dictionaries by value).

    Still, it's work in progress, as I haven't even got around to implementing support for classes yet. The inout parameter is one of the things that are bugging me, although there might be an (ugly) solution.

    var a = 2
    func incr(_ a: inout Int) {
        a += 1
    }
    incr(&a)//a now equals 3
    

    could be transpiled to something like

    var a = 2
    function incr(a) {
        a.set(a.get() + 1)
    }
    incr({get: a => a, set: val => a = val})//a now equals 3!
    

    How's that for a hack!

    Is it possible to write a 1:1 Swift to JS transpiler? I'm leaning towards yes, but the jury is out - and it's quite possible I will eventually run into a feature that's impossible to replicate in JS.