
Show HN: C#-to-JavaScript compiler powered by Microsoft Roslyn - DuoCode
http://duoco.de
======
bkjelden
I would encourage anyone looking at a C# to javascript compiler to check out
typescript first.

I've seen projects use a compiler similar to this, and while writing C# sounds
great to developers who already know C#, the differences between the C# source
and the generated JS make debugging and maintenance difficult.

In my experience typescript provides C# developers much of what they are
looking for - type safety, familiar class definitions, etc - while still being
very easy to debug.

~~~
avodonosov
IMHO the reason for such a compiler is sharing code between client and server.
From that standpoint your advice is reasonable for C# programmers only if they
are ready to abandon C# altogether and switch to node.js on server.

~~~
bkjelden
That's true - if you have some sort of business logic you want to run on both
client and server, this or Script# could be very useful.

But if you're looking to write C# in the browser because you love C# and have
heard JS is terrible (a BIG factor I've seen used when pushing tools like
this), I'd look at typescript first.

------
j_s
SharpKit has a 3+ year head-start selling and supporting their solution
(available commercially and under GPL3). I have no doubt they have considered
transitioning to Roslyn as well; it is a tough decision for all those who had
already built a C# parser. (Note that those using Mono [Saltarelle for sure]
will wind up stuck unless they follow along to Roslyn.)

The biggest part of these projects is the re-implementation of the .NET CLR in
JavaScript (for example, Saltarelle began life using the Script# runtime with
a few tweaks). The more production usage the runtime has seen, the more useful
the translation tool becomes!

[http://sharpkit.net/](http://sharpkit.net/)

------
urvader

        // JavaScript code generated by DuoCode
        GetBestMove = function(board, player, winner)
    

That line will garbage the global scope..

~~~
matchu
The C# function is global, so the compiled Javascript function is global.
Feels to me like the most correct compilation of the C# code.

(Consider: the C# code has no main function, so, if we hid the GetBestMove
definition from the rest of the webpage, it would _never_ get called. The
optimal Javascript compilation would be an empty string, and that's clearly
not valuable.)

~~~
skrebbel
I'm confused. C# doesn't even support global functions. In your example, it's
a static private member of the AI class. Why is it wrong to generate

    
    
        var AI = {
            GetBestMove: function(....) { ... },
            ...
        };
    

?

Another thing, I had someone tell me once that according to Erik Meijer (of
LINQ and Rx fame), years ago, Microsoft tried a C#-to-JS compiler too. It
worked, but they had good reasons to drop the project anyway. Did you ever
hear about that, do you know Microsoft's reasons for doing TypeScript instead?
Are they still valid?

~~~
wesnerm2
The project was Volta from Microsoft Live Labs. It was a technology preview
but appears to have been canceled. There is also Script# by Nikhil Kothari
from the .NET Platform group.

------
bad_user
I love this trend of building compilers for existing languages that target
Javascript. Other 2 languages with fully functional Javascript compilers that
are worth checking out:

\- Scala / Scala.js ([http://www.scala-js.org/](http://www.scala-js.org/)) and
I'm actually using this one for a non-trivial app

\- Clojure / ClojureScript
([https://github.com/clojure/clojurescript](https://github.com/clojure/clojurescript))
with some companies using it in production

Both are using Google's Closure compiler to do tree shaking minification and
are emitting source maps for the compiled code, so the size of the compiled
artifacts is manageable in spite of the huge standard libraries they come with
and debugging works well. Normally if you want tree shaking with Google
Closure, you have to write code specific for Google Closure, however these
compilers are doing that for you.

What you get in comparison with Javascript are saner languages that aren't
just a prettified Javascript - completely different type system, awesome
standard libraries, packages, saner semantics overall; you get a sane
dependency management and build process, by means of their build tools (SBT
and Leiningen respectively); you get libraries that are cross-compiled for the
JVM and Javascript, so you can do code sharing between the server and the
browser and you can use mostly the same tools, like IDEs. For example it's a
great experience to use IntelliJ IDEA for targeting the browser with Scala -
you get code completion, refactoring, the works.

And yes, the compiled size of the final artifact is a source of worry, but in
practice I found to not be an issue and what's awesome is that in the long run
it actually saves bandwidth for heavy apps. With Javascript many people tend
to avoid using third-party libraries, because every imported library adds to
the download size, however with tree shaking you're paying only for what you
use. As I mentioned, being a Scala developer I picked up Scala.js and it's
completely awesome, in spite of the project being young. Unfortunately these
heavier alternatives to Javascript haven't picked up popularity - for some
reason people preferred putting lipstick on Javascript and pretend that it's a
new language.

I'm happy that compilers for C# are happening as well. My only gripe is that
in true .NET fashion I'm not seeing a link to the source, which makes me think
that this won't be open-source. Which is a pity.

~~~
igl
If you use all features of scala you get at least 16mb pure js boilerplate.
Even with dead code elimination you cant get below 100kb with 10 lines of
scala. Im not sure if i would call that manageable. Your app might explode
into megabytes at one point.

With es6 around the corner and the possibilities those features will provide,
i would still bet on pure js. Those precompilers will benefit a great deal
too. Symbols and Proxies alone will remove a lot of the hoops they have to go
through now.

~~~
bad_user
It's technically impossible to use all of Scala's features and if you do,
you'd pay the same price with equivalent Javascript libraries.

I don't get this argument on the size of a hello world, given that JQuery 1.11
is over 270 KB and most people are just doing simple DOM selection with it,
yet they don't complain their hello world comes with 270 KB of stuff they'll
never use. Factor in React, Bootstrap, Angular.js or what have you and you can
easily reach 1 MB of stuff that's never used for a couple of lines of code.

The app doesn't explode in MB, unless those MB are really needed - which is
the fundamental difference between how these work and regular Javascript
development. And given that there are some companies using these in production
for non-trivial stuff and that nobody has ever reported that, I'm thinking
that it doesn't happen.

My current app is currently clocking at 300 KB btw, but I am using the
collections from the standard library, I am using a library for reactive
streams built by myself, I am using React and I do have some code in it. And
personally I find it OK.

~~~
comex
In theory, jQuery can be brought in by reference from Google Hosted Libraries
or cdnjs or whatnot, cached for a long time, and reused in any other website
that uses the same external host and version. You can't say the same about
your tree-shaken thingy... However, I'm not experienced enough to say how well
that works in practice.

~~~
bad_user
It really doesn't work out well, especially where it matters - on mobile
phones with poor connectivity. Why do you think alternatives like Zepto.js
exist?

------
rdwallis
In gwt, reflection isn't supported because it makes it hard for the compiler
to do dead code elimination.

Supporting reflection might make it difficult to reduce the compile size of
the javascript code in the future.

Or does c# reflection work differently from java?

Looks great by the way.

~~~
SigmundA
C# / .Net will have the same issue, but when they developed native compilation
for windows phone apps they added a concept of a runtime definition file that
lets you control how much needs to be retained for reflection:
[http://msdn.microsoft.com/en-
us/library/dn600639%28v=vs.110%...](http://msdn.microsoft.com/en-
us/library/dn600639%28v=vs.110%29.aspx)

The native compilation technology is moving over to normal .Net and I would
imagine the runtime definition file could be used for javascript transpiling
tree-shaking as well.

~~~
rdwallis
Thanks on first glance that looks like a much better solution than gwts'
generators.

~~~
JamesXNelson
My implementation in GWT lets you control how much is retained by using
annotations to control the retention level. It even gives you the option to
defer loading reflection until a future code split, such that you only
download the extra bytes for reflection support when you will actually need
it. See above for link.

------
nercury
JavaScript became this "immediate language" that we compile other languages
to. Could we instead get rid of it by making PROPER immediate language for the
browser?

~~~
CmonDev
Unfortunately most of the people have been inside the barn long enough to stop
noticing the smell, if you know what I mean.

------
tosh
If you like the feeling of working with something like C# it is also worth
looking into Dart: [https://www.dartlang.org/](https://www.dartlang.org/)

    
    
        * Runs on the client and on the server
        * async/await
        * Well designed stdlib
        * Powerful intellisense support
        * Stream and Future based APIs

------
Scarbutt
Can these compilers really generate "readable and maintainable Javascript" and
at the same time generate performant JS? I think this is one of the reasons
why languages like Dart and Clojurescript chose the opposite (not generate
readable JS).

------
WhitneyLand
Well done. I like it but I'm not sure what my use case would be. I mean, if I
wanted a cross compile language upgrade how do you decide between something
like this and ES6?

Also, if there any language left that doesn't convert to JS?

~~~
Sanddancer
A quick googling shows that people are still having some problems with fortran
to javascript, as there's a bit of a dance between toolchains that needs done
there. However, the best bet for if you wanna keep people from turning your
code to javascript seems to be PL/I. Finding even less there for tools to
convert it to javascript.

------
dested
I am a huge fan of Saltarelle [1], which has the save level of support as this
project. The only thing it seems to be lacking is proper source mapping
abilities, which is currently in a dev branch. It also has many libraries
already built, like JQuery or AngularJS. However, full support from Microsoft
makes it much more realistic to bring in to a production environment. As a C#
developer, this will be something to keep an eye on.

Edit: After reading more, this does not seem to be a Microsoft project.

[1] [http://www.saltarelle-compiler.com](http://www.saltarelle-compiler.com)

------
Scarbutt
So is this a Microsoft project? they don't directly say it, but they try to
make it sound as it is:

"DuoCode is an alternative compiler, powered by Microsoft® Roslyn, and
integrated in Visual Studio."

~~~
slg
Roslyn[1] is open source, so nothing that is being listed there implies
Microsoft is behind this project.

[1] - [https://github.com/dotnet/roslyn](https://github.com/dotnet/roslyn)

~~~
Scarbutt
for me, the key in that sentence is "integrated in Visual Studio", implying it
comes or will come bundled with Visual Studio, English is not my first
language so maybe I'm misinterpreting this.

~~~
slg
It just means that it will likely come as a Visual Studio add-on which doesn't
require any official support from Microsoft. [1]

[1] -
[https://visualstudiogallery.msdn.microsoft.com/](https://visualstudiogallery.msdn.microsoft.com/)

------
anprak
Script# has existed for years and heavily used inside Microsoft. Even with
that, it was not adopted as a tool for programming JavaScript in Visual
Studio. If you need to code JavaScript but not in JavaScript as it exists
today, TypeScript is what you should look at.

Please stop these C# to JavaScript compilers. If one needs to program in
JavaScript, let them learn and understand JavaScript.

~~~
CmonDev
Yes! The whole compilation madness must stop. Machine code is good enough for
everyone. And if you still need to code in a high-level language, assembly is
what you should look at.

------
danbruc
There is also Script# [1] which unfortunately seems to be no longer
maintained. Even the domain of the homepage expired at the end of 2014. I used
it for a couple of toy projects and it worked pretty well.

[1]
[https://github.com/nikhilk/scriptsharp](https://github.com/nikhilk/scriptsharp)

------
xenadu02
This isn't new. Microsoft had an unofficial project for a while called Script#
(script sharp) that did the same thing. I think they rightly decided it was a
better idea to support JavaScript directly and come up with a new language
designed to target JS from the start (typescript)

------
kingmanaz
IMHO, Transpilers will likely be the future of web development, with
javascript evolving into an intermediate language which other languages are
compiled to. Projects like this or gopherjs are a taste of what's to come.

~~~
JustSomeNobody
As long as we're doing predictions, here's mine:

All the cool kids will finally stop trying to push everything to the browser,
move some of that back to the server, and become completely content with what
Javascript has to offer.

~~~
JamesXNelson
Why spend cycles doing work on the shared resource (the server), when you can
leverage the (hopefully) millions of CPUs used by clients?

Smart clients reduce server load, and allow increased scale; why pay to make
your server turn models into HTML when you can just send the model to the
client and let it deal with it however it wishes.

For us at Appian, we use the same models and APIs for web, android and IOS; by
having a smart client, the server only has to care about the shared model and
executing requested instructions; it doesn't care how the client renders the
result, nor should it.

------
h43k3r
I don't know how good this is, but I got to know from someone that Microsoft
uses a similar thing for their internal uses and their version had a very poor
debugging.

------
mwcampbell
Can C# classes compiled in this way be exposed to JS, so the main program can
be in JS with libraries compiled from C#? Or is it assumed that the main
program is in C#?

------
hougaard
Hmm.. Wonder if this could breathe life into a Silverlight application that
needs a way forward..

------
Osiris
I'm curious how this handles the very common case of passing functions as
parameters in JavaScript. I know it's possible in C# but it's much more
difficult to do. JavaScript is a much more functional language than C# and the
design patterns are quite different.

~~~
rjbwork
C#:

    
    
        Func<string> blah = () => "im a function";

JavaScript:

    
    
        var blah = function(){ return "im a function"};
    

Not only is it not harder, it's more terse in C#.

~~~
grokys
That can be made even simpler in C#:

var blah = () => "im a function";

~~~
antihero
In ECMAScript 6:

    
    
        var blah = () => "im a function";
    

[http://is.gd/D42hDi](http://is.gd/D42hDi)

:)

~~~
dguaraglia
Wow. I love it when good syntax sugar is inherited by languages.

~~~
antihero
Yep, I've popped 6to5 in our gulp build process (it also handles JSX which is
bleedin' fantastic), and my team and I are absolutely loving it.

The fact that, for instance, you can use ES6 modules, and it will be converted
to whichever module loading system you're actually using (AMD or Browserify,
for instance), means that our code is actually more portable now (our
React/Flux/browseify app may well have to be integrated into a project that
uses backbone/AMD soon, so that's no longer a headache.

------
elwell
Cool to see the open-sourcing of Microsoft code already being put to use.

------
jtwebman
I don't find writing JavaScript to be that hard. I don't get all of these
compilers like this one, CoffeeScript, and TypeScript. Are people really that
lazy that they can't spend the couple days it takes to learn the syntax and
gotchas of JavaScript?

~~~
px1999
I'm working with a singlepage webapp that consists of ~1.5MLOC
serverside(+other) and an additional ~100KLOC of javascript (not including
libraries).

Refactoring and maintaining consistency are the two big problems we have with
Javascript. It's easy enough to write javascript that works and does what we
need it to do. The challenges come in when you start having separate
components that need to interoperate.

eshint/jshint etc take you only so far (preventing you from dumping things
into the global scope, avoiding typos). AMD etc can take you a bit further
with async loading, and give a better [more consistent] pattern for exporting
things than saying to devs "just put your stuff in an IIFE". FB Flow looks
helpful, but it's trying to solve a difficult problem, and unfortunately
doesn't work so well with our code thanks to ONE bad decision made a long time
ago to rely on declaration hoisting ("unreachable code" :( ).

Anyways, knowing that your code isn't going to work before you start spinning
up the application saves a lot of time.

Knowing that you can rename a method/function and have no undefined errors
come out of it is great. Being able to look up usages of a method across the
entire codebase is also useful. Eventually if Microsoft decide to spend
resources on it, TypeScript might get CodeLens (which is on its own all manner
of cool+useful).

Having class syntax means that you don't need to worry about external
consumers accessing properties that they shouldn't be (+gets rid of silly
conventions like underscore private members/methods).

JS is a great language, and it's powerful, but when you're writing large
quantities of stuff, sometimes you need structure. Particularly when it's a
large team and there are people of wildly varying experience, ranging from
near-zero JS experience to people who have used it for a decade or more.

~~~
jtwebman
Unit tests fix the changing methods issue as well as making sure it will run
when you run it. Types don't save you from that anymore then JSLint would as
both can have logic errors.

Browserify can help with breaking your code down into smaller reusable modules
for the client side and node you want to make your modules as small as
possible? From the sounds of it you fell into the one big huge application
that does everything problem instead of breaking it up. The same issues would
have happen if you would have done that in any other language.

Varying experience doesn't mean you can give them TypeScript or CoffeeScript
and not mess something up. You should still put code reviews and training in
place though I do agree JavaScript lets you shoot yourself in the foot much
easier.

You can hide variables through closures and sorry not a fan of getters and
setters, I feel they are a anti-pattern
([http://www.yegor256.com/2014/09/16/getters-and-setters-
are-e...](http://www.yegor256.com/2014/09/16/getters-and-setters-are-
evil.html)).

The one thing that would be nice would be knowing where your code is called.
Though if you are using NPM and Browserify then that can be easier as well. I
agree though that the tools are not as nice as Visual Studios find callers and
the intellisense isn't that good ether but I am willing to trade them for the
flexibility of not having to declare types and the simplicity of not having to
work around types with generics, interfaces, and casting.

So I think there is structure in Javascript you just have to learn the best
ways of implementing it. Yes Javascript makes it a little easier to shoot
yourself in the foot but you can still do it with CoffeeScript, TypeScript, or
even in C# and Java, we learn from our mistakes. I fell to be successful in
Javascript you really need to keep it small and re-factor often but that
really is the same in all languages.

~~~
px1999
Each of your points is valid.

We have unit tests (fewer on the client than server though), CI that runs
integration tests, automated UI tests and other stuff - but that's all much
slower than "VS tells me that my code's broken so I should fix it before
starting to debug". We'll catch bugs with TS or JS, it's just how long it
takes to catch them that's the issue.

Modules aren't so much an issue for us (we don't have a big ball of mud IMO),
it's how these modules talk to one another. This is not a problem that we
experience in our serverside code because we have powerful tools (in terms of
the IDE) that largely stop us from doing dumb things. We refactor a lot, and
historically doing this in js has been a massive pain (ie there are no GOOD
automated tools for refactoring that I'm aware of). If you use C# and move a
method, you expect everything to keep working, but you don't have that same
expectation when refactoring javascript. If your app is structured correctly,
you do get that with TypeScript.

Same with reviews and training - we have both, but our team isn't big enough
to have people dedicated to each area. We mostly hire C# devs, for better or
worse, and want them to be as productive per hour as possible. Having it
harder to shoot yourself in the foot means fewer feet shot over time,
regardless of the team and their skillset.

Getters/setters was an unclear use of term "properties" on my behalf (which
actually referred mostly exclusively to methods). Regardless of my personal
opinions on getter/setter methods/closures etc, we have established patterns
that will take a while to change. The problem is there, and so tooling that
helps reduce what breaks when we make changes is a big plus. We don't have a
robust message bus in the application, so there's a lot of crosstalk (that's a
refactoring area).

And, overall, TS is a superset of javascript so you can always just write JS
if that's what you've gotta do.

I guess that my overall point is that javascript is a great language (well,
it's ok), but that tools like TypeScript just make things "better" for the
average developer working on a large-scale system. JS is an organically grown
language, and it shows in a number of places. You can do some super-cool
things with it, sure, but for a lot of uses it's a worthwhile tradeoff to
write something in a slightly-more-strongly-typed way.

We're about 10% new code, 90% refactoring and updating (though that's a guess,
I haven't looked at the stats lately). For us, JS is more painful to maintain
than C#. From what we've seen, TypeScript will give us significant benefits on
that 90%.

~~~
jtwebman
All awesome points, I'll have to take a second look at TypeScript. Thanks for
the points back.

