
ShiftJS – Swift to JavaScript transpiler - joubert
http://www.shiftjs.com
======
spicyj
I love Swift and work on the web, so I would love to see a serious Swift to JS
compiler. Unfortunately, this isn't it.

One major part of Swift is its value types; many core types, including arrays,
are passed by value, like a C struct. So

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

should make `a` equal to [1, 2] and `b` equal to [1, 2, 3]. ShiftJS eschews
these semantics and instead passes arrays (and other value types) by
reference, which makes it basically impossible to share code between real
Swift and ShiftJS.

Also, the demo compiles

    
    
      let a = 3 4
    

to

    
    
      var a = '3 4';
    

which doesn't instill confidence.

~~~
Waterluvian
I'm curious, when are these kinds of compilers truly useful?

Maybe its my own ignorance, but language design often doesn't map 1:1, so
wouldn't it end up feeling forced?

~~~
joeyjojo
I have successfully used Haxe in isolated cases to build games for WebGL and
Canvas. I think transpilers are most useful when you rarely want to reach
outside of your own code, or you only need to rely on a few key libraries that
are known to be well supported within the ecosystem of your transpiler
language. I also struggle without a static compiler, so for my case it makes
sense to use a transpiler, even with all of its pitfalls.

If there is one thing however that I have learned from using transpilers it is
that externs as a whole are a huge waste of time, as it can be difficult to
determine their quality upfront. If you are building a Node backend or SPA,
you are going to need to rely heavily on existing libraries and will probably
find yourself constantly hitting walls while you try to swim against the
current of the ecosystem if you try to use a transpiler.

~~~
jdonaldson
I disagree about externs being a waste of time for Haxe. I've written several,
and they've been instrumental in helping me understand a codebase, and manage
an upgrade process.

Haxe has a lot of metadata mechanisms that enable mapping language-specific
semantics to Haxe standards (@:selfCall, and @:native for example). Haxe also
has abstract types, which enable automatic inline runtime conversions (e.g.,
converting a native type to a standard Haxe type automatically depending on
usage in haxe methods).

It's true you can't expect to find a high quality extern for a given version
of any given library. However, it's pretty easy to write a small one for the
subset of functionality that you require. It always ends up paying off for me.

~~~
joeyjojo
I should have elaborated a bit more on this point, and I mistakenly used the
wrong terminology. I was thinking specifically of Typescript type definitions
when I wrote about externs, and was meaning to refer more so to the concept in
a general sense (across all transpilers). That said I do use a number of high
quality externs with Haxe (the Pixi.JS one is excellent).

I agree with what you say about writing your own externs with a subset of the
functionality, and I think it is often a better approach than relying on
potentially flakey externs. Still I think this sort of workflow is only suited
to particular types of projects and especially in a team environment it makes
more sense to avoid niche ecosystems.

------
msoad
The true "Swift in web" will happen when WebAssembly is ready and LLVM has a
WASM backend. Then I can just compile my Swift to WASM and bypass JavaScript
altogether because Swift is already a LLVM front-end.

~~~
NEDM64
And then you need to wait for browsers to support it...

~~~
msoad
Browser support landscape has changed. The only concern is Safari but I'm
optimistic

------
LiweiZ
8-9 months without any update to codebase is not a good sign for most open-
source projects, especially when both JS and Swift are marching quickly. This
alone can turn me off on this.

------
schrodinger
It doesn't seem to handle some pretty basic swift code:

    
    
        var a = 3
        let b = { a * 2 }()
    

[http://i.imgur.com/D1FxZcN.png](http://i.imgur.com/D1FxZcN.png)

~~~
subliminalpanda
Same here, tried a basic loop and it broke:

for i in 0...10 { print(i) }

Then again, the project does say it's in early development. Perhaps a re-visit
in a month or two will yield some nice progress.

~~~
expression
If the projects GitHub page is anything to go by, I doubt that. The only thing
that's been changed in 9 months is the readme, and the change was to remove
the note about the project being in "active early development".

------
zephyz
Why didn't they fork the actual swift compiler that does all the lexing,
parsing, syntax checking, type checking, SIL generation, LLVMIR generation,
and add a final phase that compiles to JS?

This whole project seem like a lot of duplicated, wasted (and error prone)
work

~~~
bsaul
Wondered the same thing. I thought maybe a sil to js project could be a good
target, keeping enough semantics to be able to be smart in the generated js
code, rather thab llvmir.

I looked for such a project a few days ago but didn't find anything.

------
closure
I do wish people would stop using the term transpiler as if there is something
novel or different about source-to-source translation.

If you're taking a higher level language and compiling it to assembly, it's a
compiler.

If you're taking a higher level language and compiling it to LLVM IR, it's a
compiler.

If you're taking a higher level language, and compiling it to another higher
level language...it's a compiler.

I am not sure where this term was first coined, but we've been doing source-
to-source compilation for a very long term and it's just within the last 7-10
years I start hearing people use this term, which IMO adds no actual value.

It's perfectly fine to say "Swift to JS compiler".

~~~
PeCaN
I agree with munificent. ‘Transpiler’ implies very similar semantics between
the source and target language; ‘compiler’ implies fairly different semantics
(where a translation between the source and target is not obvious).

~~~
the8472
Some people treat C as portable assembly.

Does that make gcc a transpiler for converting portable assembly to platform-
specific assembly due to their similar semantics?

~~~
PeCaN
I knew someone would bring this up.¹

GCC is an optimizing compiler, at which point all bets are off for
obvious/trivial translation between C and asm. You could, hypothetically,
write a optimizing TypeScript _compiler_ that emits asm.js.

However, while you can reasonably argue C started as a portable assembly,
significant differences like a type system, pointer arithmetic, a calling
convention, etc, exist now. I don't think it's unreasonable to say C is
significantly higher-level than assembly.

1\. My parenthetical at the end was anticipating this—then again, the
translation between C and asm frequently _is_ easy, albeit tedious.

~~~
the8472
I guess you could replace gcc with a dumb compiler / turn off optimizations.
And throw in compiler intrinsics while we're at it, after all people write hot
loops with them. And pointer arithmetics actually translate nicely to all
those fancy addressing modes you find on x86.

And in the other direction one could argue that those so-called "transpilers"
actually compile from a higher-level language when you consider complex type-
inference and static type checking. Optimizing is not all a compiler does.

------
leonatan
From their examples.

Swift: var n = m--;

JS var n = --m;

Forget that ++ and -- operators are deprecated and not available in Swift 3.0;
simple but profound mistakes like this do not instill confidence at all.

~~~
rahkiin
Also, --m and m-- are completely different. One decrements first and returns
the new value, the other returns the new value and then decrements.

------
Zelmor
I hope these sort of madness of everything to JS goes away with the advent of
webassembly.

~~~
rimantas
Or just goes away.

------
hongbozhang
FWIW:BuckleScript([https://github.com/bloomberg/bucklescript](https://github.com/bloomberg/bucklescript))
is to my knowledge the only compiler which compiles an existing language(not a
language designed for compilation to JS) to JS without name mangling.

It is a serious piece of work, the compiler is compiled to JS too, so you can
play it in the playground(even work offline):
[https://bloomberg.github.io/bucklescript/js-
demo/](https://bloomberg.github.io/bucklescript/js-demo/)

It also generates very small code output, for example `hello world` is 20
bytes instead of 100K bytes

------
pbreit
The holy grail would still seem to be the opposite: writing native iOS apps in
JavaScript.

~~~
sixstringtheory
I haven't tried Reactive Native or other options, but my gut tells me it's
less safe to write in Javascript than Swift. What would be an advantage that
outweighs that?

~~~
AndrewGaspar
Less safe in what sense?

~~~
danappelxx
Type safety & all that jazz. Swift is a much more powerful language than
javascript (and typescript) is.

------
echelon
This has a very similar name to the Japanese text encoding, Shift_JIS. I doubt
people will be confused since these are two different domains, but they sound
very similar to pronounce.

------
joeblau
I'm not sure if the examples are actual results from the transpiler, but there
are semicolons in the Swift code which are not necessary unless you have
multiple statements on the same line.

------
sixstringtheory
How I would love to be able to write front-end code with all the safety checks
of Swift, and have it transpiled on a commit hook or something! Wonder how
this could work converting to React?

~~~
azdavis
Have you seen
[https://www.typescriptlang.org](https://www.typescriptlang.org)?

~~~
theodorton
flow ([http://www.flowtype.org](http://www.flowtype.org)) is also an
alternative. Developed at Facebook.

------
flanbiscuit
This is a cool project. I wonder what inspired the developer to make this and
what could be some use cases for this? I could see it being used a tool for
learning.

~~~
sotojuan
First there was "everything that can be written in JS will be written in JS".
Now it's "everything that can be compiled to JS will be compiled to JS".

~~~
oddsignals
"Everything that has been written in JS will be rewritten in every language
that transpiles to JS"

------
kevindeasis
Are there other ways to use other languages in the browser asides from
transpiler, and asm?

~~~
fleitz
Yes, read the browser docs, many browsers support languages other than JS.

However, if the browser only supports a given language than the final target
must be that language, similar to how only machine code executes of a CPU,
everything else is just a turing machine emulating another turing machine.

~~~
coldtea
Where many = IE, and other languages = VBScript (if that's even supported
anymore)?

Because that's the only actual and in use browser I can think of that supports
a language other than JS natively.

~~~
fleitz
Chrome supports ActionScript natively, as well as C++

~~~
coldtea
No, it doesn't support either.

ActionScript is only supported through the Flash plugin, and inside the Flash
environment -- and even that is taken out altogether in the new Chrome
release.

C++, not at all. Except if you mean Chrome is written in C++ itself, or you
can use Native Client, which again is another plugin like environment.

So, nothing similar to JS at all.

Might as well have mentioned emscripten, which does end up running as a web
page.

~~~
fleitz
If you install Chrome it supports these things, that's 'native' to me.

Does it act like JS? No, but its still native.

------
masters3d
It would be interesting if it first converted the swift code to TypeScript
then JS

~~~
PeCaN
Why would that be interesting? Presumably a Swift compiler handles its own
type checking.

~~~
epicureanideal
TypeScript would be a simpler translation target because it's very similar to
Swift, and then TypeScript could handle the translation down to ES6, ES5, ES3,
etc. Why reinvent what's already available?

~~~
TazeTSchnitzel
TypeScript is merely JS with added type annotations, annotations which are
stripped off when it compiles to JS.

There's no usefulness of TypeScript as a target for a compiler for Swift,
because Swift already has static typing.

------
sebastianconcpt
someVar++ and -- is deprecated already.

I wonder why doing this. What's the applicability of doing this? Will this
applicability still remain valid when WebAsembly hits with a real swift
binary?

------
Slippery_John
That's an unfortunate name. Way too close to Shift JIS, an encoding for
Japanese characters. IANAL, but it seems close enough to warrant copyright
issue.

~~~
coldtea
First of all, if it's the name of a an encoding there's no "copyright issue".

Second, nobody (except the Japanese) really gives a duck about Shift JIS (and
not many people care about Shift JS either) to warrant anything on either
side.

