Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 instil 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?

like image 566
stuffy Avatar asked Jan 15 '17 18:01

stuffy


2 Answers

A transpiler between any two turing complete languages is always possible. That doesn't mean it's easy, practical, or worthwhile.

At the bare minimum, you can guarantee that a Swift to JS transpilation is possible because you can compile the Swift to x64 machine code, and use a JS disassembler/decompiler to produce JS. However, the resulting code will be really shit JS.

To make a good conversion you need to account for all the intricate best practices of one language, and what their equivalents are in the other language. That's a huge undertaking, that must be done twice (one in each direction) for any two pairs of languages you'd like to transpile. There's a reason transpilers are so uncommon, and usually crap.

like image 154
Alexander Avatar answered Nov 14 '22 16:11

Alexander


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.

like image 25
Marcel Gańczak Avatar answered Nov 14 '22 15:11

Marcel Gańczak