As I see the author reads these comments, I'd just like to add that this makes me very excited. C# is my favourite language by far, combining some of the most powerful (mainstream) language features with some of the most powerful dev tools out there.
Having the ability to run the same code in the browser and on the server, in C#, is really a big thing for me.
I think the debugging problem stated in many comments here is overrated: If you're writing an app the size that seriously benefits from the modularity, the tool support and the type checking of a language like C#, you will have a relatively small amount of code directly touching the DOM. All of that other code can be simply unit tested in C#-o-world, straight from the dev environment. If you're writing C#, don't test and debug like it's JS!
Surely such an approach won't catch all bugs and the occasional leaky abstraction (or compiler bug), but it should get one pretty far. Some in-browser unit testing lib together with the fact that the generated JS is quite readable indeed, should help me get the rest of the way.
After the initial curve of getting VC10 configured right, I did an inheritance test. It worked (copied base class prototype, called base constructor with this.) Minutes later I was happily converting C# code to nicely formatted JavaScript. Having spent the last two weeks converting JS to Dart (basically a one way process because you don't want to look at Dart->JS), I'd say this project is a winner and immediately usable. I'm positive there are C# features and libraries that don't convert well, or at all, but I'm not interested in those in the browser any way.
The very best of luck when it comes to debugging the code when it is running in the browser.
Maybe your experiences are different to mine but I avoid such abstractions wherever possible.
It has become fashionable to say things like "JavaScript ... is not well suited for developing large systems" - indeed so much so it often passes without comment but when it is JavaScript that will be run by the browser then JavaScript is what you should be writing.
But JavaScript is not (another daft meme) "the assembler of the web" as it is itself interpreted (or what have you) into byte code for execution.
The point is that one should limit the level of abstraction to one which sits in that comfort zone between code that is sensible to humans and code that is sensible to the machine running it and (perhaps more importantly) the available dev/debug tools.
No, one should limit the level of abstraction to the fastest one that is reliable enough to get the job done. There's nothing intrinsic about high abstraction layers that say they must suck for debugging what you need debugged. It just depends on what you need to do with it. If it gets your job done faster and it's reliable enough for your job, then why not? That's why higher abstractions are created in the first place.
In short, you can't instantly rule out this compiler without knowing exactly what you'd want to do with it. And exactly how good it would be at that specific problem.
I don't agree that JavaScript being good enough for one person makes it good enough for everyone.
I don't agree that limitations should be placed on abstractions; I have no clue what's happening at the CPU level when a line of JavaScript or MSIL or bla bla executes. I don't need to know what's happening at all the layers of abstraction beneath the one I'm working on, and that helps me be productive.
There might be a pragmatic argument against using compile-to-JS languages _right now_, but with things like Google Chrome's Source Maps, this is a problem that is being solved if it hasn't been already.
Actually, debugging is quite simple. The generated script (unless minified) is very similar to the input code. Are you also against other options such as CoffeeScript? And do you think it is very hard to debug higher-level languages such as C, C# or Java because "if you are writing code to run on a processor, it is assembly you should be writing"?
The question is how similar? Coffeescript has come a long way in keeping symbols similar enough to be debuggable and not polluting the javascript namespace. Once the code grows to a certain size, tracing from line number in error to a line of code in your source becomes non-trivial.
Also, since this has been a constant pain for me when using Google Closure compiler, how do you anticipate this tool working with existing javascript libraries? Hypothetically, can I port a C# application ( a reasonable/simple one, not with crazy winforms and stuff)? Is there a spec you're adhering to?
It comes with metadata for jQuery and jQueryUI, so obviously those libs can be used. I know of people using Node as well (and I hope to include that import lib in the distribution at some point).
As for porting an existing C# application, it will probably not be trivial, but the back-end stuff is most likely possible (as long as it doesn't have external references). Personally, for my own stuff I tend to compile stuff like DTOs and helpers to both Javascript (running on the client) and regular MSIL (running on the server), but that code has been written with this intent from the beginning.
I prefer to regard working with this to be writing Javascript but with tooling from 2012 instead of 1995.
Well, he actually said "debugging code when it is running," which a lot of people find valuable. Of course you can debug anything in the looser sense of the term, but tools like debuggers make the process more productive.
And yes, many people are against Coffeescript too for precisely this reason.
I agree. Having had used GWT and other similar cross compiling to javascript type tools, it's often a huge problem in debugging than if you just write a short javascript code. No offense to the author but projects like these that try to fit a static language like Java/C# that run in their own managed environments into dynamic world of Javascript fail miserably.
I fear projects like these tend to attract programmers who know C#, Java but don't quite want to learn javascript and they don't even try to do it once they run out of runway in this tool. And, the code becomes undebuggable, bloated on the browser.
Nothing against other languages, they're amazing at what they do. But, javascript is, for better or worse, the language of browsers. And it's really powerful with established best practices to organize, debug code + great tools (thanks to Chrome Team @ Google and Mozilla).
From a programming languages/compilers standpoint, it definitely tickles my fancy :)
I program both C# and JS on an almost daily basis and am pretty well versed in both. I have to say that JS is great for adding scripting to pages but for large apps it's a nightmare (especially when coupled w/ the dom).
I'd call something with more than 100k LOC a large app. It can get messy even before then though. The main concerns I have with Javascript are:
1) Most frameworks try to make JS into a typical OOP language which tends to hurt performance and can make debugging a PITA.
2) In "one page apps" it can become difficult to map nodes to JS objects so things get cleaned up properly. You often see memory build ups even in jQuery because of html node wrappers and events that get cached but don't get cleaned up.
3) Static analysis. It's possible to get some level of static analysis if you use JSDoc but it's still very poor compared to something like C#. For example, you need to add tons of JSDoc code to make autocomplete somewhat usable. After using something like Resharper, you can really see how lack of good static analysis hurts.
4) Difficult to refactor large apps. Since the static analysis is poor, it's difficult to use tools to create dependency graphs, finding usages, etc... I really wish Js would just let you specify a type of an object like ActionScript 3 does. You can still use var if you want but 99% of the time an object has an expected type.
5) Lack of visibility keywords. This makes it hard to organize code into modules and prevent programmers from getting access to things they aren't supposed to. I'm sure there are entire debates on this point alone.
6) Performance. The browsers try to do tons of optimizations during runtime to speed up javascript. If you want to get the most out of JS, you really need to know about them (e.g. always initialize your class vars in the same order).
This sounds like a solution to a problem that probably shouldn't exist because there is a solution that shouldn't exist to start with which has caused a problem that doesn't need to occur.
The slightly overbearing complexity of the solution matches the linguistic complexity of the statement above :)
I don't see how these are significantly different than .PDBs which allow Windows developers to step through their source code when debugging compiled binaries.
But it will not write JavaScript the way you would write it - and (avoiding arguments about personality in code) that JavaScript will be way harder to follow and debug.
I agree, but generating "harder to debug" output isn't really a big argument against generators.
The first argument is that "the style is different". I use a js generator language (not this one, I don't want to shift attention), and it does "nice" things that would be a pain for me to do manually... like setting up namespaces for code, spacing everything perfectly. Even if the output is not to your taste, at least you know that the style will be 100% consistent in style and implementation. I never have problems debugging.
The other argument is that "the generated code is complex/ugly". Unfortunately, "fast" code is often ugly. Static compilers can do some optimizations by default (e.g. optimized for loops), and you only need to worry about the "pretty" code at the higher level of abstraction. I doubt you will ever have to debug one of these optimizations, any decent compiler should get them right. You merely have to understand why they were used, which often makes you a better programmer to boot.
I'm curious how you're doing the parsing. I see that you reference both NRefactory (which reads C#) and Cecil (which reads IL) -- can you talk about how are each of these used and how you combine them?
Also, did you consider using Roslyn (Microsoft's official C# parser)? Obviously it's still beta, but once it's complete would it remove the need for Cecil and NRefactory completely?
JSIL is also great, but its philosophy is that yo write .net code and run it in the browser, whereas Saltarelle's (and Script#'s) is that you write Javascript but with better tools. Also, the script that JSIL generates is very far from what you would write by hand, whereas that generated by Saltarelle/Script# can be distinguished from hand-written script primarily because the indentation is always correct and there is never an accidental loose comparison operator.
I think the tools fill different purposes, so integration with JSIL is absolutely a possibility in the future. I did not do any speed comparisons, I just translate what you write in C# to the equivalent script, so if you write a fast script it will be fast, if you write a slow script, it will be slow :)
Well, how you create data structures might matter for performance - if you turn C# structs into JS typed arrays for example and do the proper conversions, that could be much faster than simple JS objects or even arrays.
I don't see how you can really use this without already being very familiar with Javascript. While you're writing your code you'd need to be constantly aware of how the code will be translated to js (so you can use the correct attributes and define datatypes correctly), and you'd also need to be aware of avoiding. NET library classes that can't be used by the translated js. It seems easier to just learn to manage large js projects.
The reason I'm looking for either C# / Scala JS compiler is that I'm a static typing fan, I am an old school developer who likes IDEs and like discovering API by pressing ctrl+space, instead of mentally knowing it or constantly checking the API docs, I know it's against the trend, and not considered cool, but this gets me working software out the door. I'm much more productive and have much less bugs while writing old school, unpopular Java, and using the IDE's (eclipse) sugar features. Scala is now my favorite language (I really hope it was a little more new dev friendly, it can become very syntax overwhelming sometimes) as I can many of the functional features in Ruby / Python / JavaScript / Clojure, but still stay in Static Java land.
Another thing static typing gives me that I really wish I had in JavaScript, is (almost) worry free refactoring.
In Java, I can extract methods, constants, delegates, change method signatures, rename members, fix typos in code, and never to worry I copy pasted something wrong.
I have yet to find such a way to do it safely in JavaScript / CoffeScript or any other dynamically typed language. (feel free to point if I'm missing something, I said I'm not that a great of a developer)
So maybe I'm just not good enough as a developer, but I like IDEs to protect me, perhaps I'm not smart enough to use VIM / Emacs / TextMate, and I can't memorize APIs. Static typing + functional features make me the most productive.
So C# / Scala / Java 8 javascript compilers are on the top of my wish list.
I hear you, but I can't agree. Maybe it's my background. For 13 years as a professional developer my primary languages were Perl and Javascript, using Vim and the Unix command-line as my IDE. For the past 1.5 years I've swapped C# for Perl and Visual Studio for my IDE (still have a vi emulator though.) Intellisense is definitely useful, but I find it gets in the way a lot... both literally by overlapping the code around the code I'm typing, and figuratively by trying to insert text while I type which causes me to double-type characters and backspace a lot. It does help with remembering (not learning) APIs, but that's one of my concerns about translating to js: Intellisense won't know which APIs are usable and which ones are not. If you're a C# developer who's dependent on Intellisense, it's going to mislead you here.
Regarding refactoring, it's hardly worry free for me. I always have to double check what VS is going to do when I use its refactoring tools, because sometimes it makes a significant mistake. Now, that's often caused by the way I wrote some code and I have to fix it up as part of my refactoring, but I would have discovered that while refactoring manually too, and if I trusted VS I wouldn't have discovered it at all. So VS helps a bit with the typing, but it's not much faster than I'd be without it. A lot of that is probably because I learned to refactor using vim, grep, sed, and other Unix command-line tools, so I have no problem doing large-scale refactoring changes touching thousands of lines over a 100k+ line codebase. Extracting a method is childs play in comparison, and I don't mind the extra few seconds it takes to do it manually exactly the way I want it.
There is definitely a need for better javascript editing tools. VS, with the right plugins, wouldn't be bad, but I'm not sure Intellisense can really cut it. When I'm putting some code into an MVC template or js file and I want to refer to a jQuery plugin I know is loaded by my layout template, there is no way for Intellisense to know about that plugin or its API, so it can't help me. In contrast if I load my app in Firefox and use Firebug's console and debugger, I can type in some code and it's able to show me the API in real-time because it's reflecting the live javascript objects as I type. That's the kind of intellisense I want.
I fully relate, I wish I had the same background, it would have made me probably a better developer, but I'm already hooked...
What I'm wondering is, why can't we have the browser then be our IDE, chrome already supports editing, just need to persist it to my code base
By the way, I strongly suggest using something like resharper, VS is great, but I found eclipse much better if you are looking for those tricks and shortcuts.
If you haven't tried it yet, I encourage anyone to get eclipse, put in some java code, and play with ctrl+1 magic shortcut (mark anything in code and let it do the work for you) it allows you to be more expressive and write code in a modular way, for example, I don't have to be a boolean logic master, or even a smart developer to extract negation up a boolean condition, and if I forgot a param / method, it will create it for me with the right signature, and if I see a piece of string I want to replace with a variable, it takes it for me and adds those dreadful " + ... + " in so I don't have to. does it makes you a zombie programmer? probably yes, does it make you smarter? probably not, but does it make you more productive? absolutely yes.
again, VS I think is nowhere near eclipse JDT in that end (without resharper at least)
I think this is why GWT, Dart, Scala, Hibernate / Seam, Spring all invest so much in eclipse,
most developers of this world (me included) are just not good enough hackers to do it the VIM / grep way... sad but true.
For statically typing Javascript, I strongly recommend Google's Closure toolset- it uses JS comments to statically type and validate your code, plus you can either run it compiled or uncompiled.
but I find it gets in the way a lot... both literally by overlapping the code around the code I'm typing, and figuratively by trying to insert text while I type
I sometimes forget that this is the default, since my first step when installing VS.NET is to turn off all the automatic popping up and getting your way functionality. I think it's analogous to that "Torch Mode" setting that new TVs are on when they're in the showroom, demonstrating every feature they have at once so you see it all and are impressed. The VS.NET that I know doesn't do that. But I guess it would prefer to if you didn't reel it in.
Keep all the good stuff, but leave it behind CTRL+Space. You're four checkboxes away from having your cake and eating it too. And not having it leap up in between you and what you're trying to accomplish.
The author might assume it, but I think it needs to be explicitly stated. Tools like this are often sold as "You don't need to know X because you can now code in Y and translate automatically to X!" That never works out though because there are always leaky abstractions. (For this project, just take a look at the Attributes docs to see how leaky the abstractions are.)
I've had to work with a bunch of C, C++, Java, Perl, and C# developers who were good at backend stuff and just started to learn HTML, CSS, and Javascript, and they're mostly pretty awful at it until they give in and dedicate themselves to the frontend web developer platform and environment. Prior to that they'd grasp at tools like this one that seem to offer hope that they won't have to learn that nasty javascript.
I'm coming at it from a different perspective. I can't worry about what other programmers do. I need tools. I love JS but the tools for it could be better. I'm hoping C#->JS will be a great addition to the toolbox.
My largest criticism for projects like this is that I absolutely abhor running into compiler errors. When you don't fully trust the compiler, it suddenly becomes a suspect when code isn't working like you think it should.
Given decent source maps to allow debugging through the original code, I don't think solutions like this are terribly different than native Javascript. The primary difference though is that I trust the browser JS interpreters and VMs more than I trust many X->JS compilers.
We use an older version of Script# for a very large site at work. This looks like it might be worth trying to upgrade to.
But what I really want is a way to convert Silverlight to JS. I don't care whether it is source or binary level conversion, but it would be awesome to take projects we've written in silverlight and run them on any browser without a plugin.
I totally agree that JavaScript can easily end up being a huge mess especially when project grows. Using more strict language like C# can help on that. I have to try this, good job!
There are frameworks and best practices for organizing JavaScript heavy projects. I'm all for solutions to unify front and backend web application development so cheers to Erik for developing this, I've just never been a fan of cross language compilation.
I don't really get this. Surely JavaScript and C# are so hugely different that any converted code would be horrific? Wouldn't it be simpler to just write JavaScript in JavaScript?
- Translating a statically-typed Object Oriented language to JS wouldn't produce hugely different (/horrific) code. From inheritance to lambdas, there are comparable features available in JS. Going from JS to C# might be harder though.
- It might be simpler to write JS, but I can imagine people wanting to see if type-safety has benefits.
Some browsers, and ES Harmony, have yield. You could add a compiler switch to use native support, although only Firefox seems to support this just now.
Curious to see how you managed the emulation - splitting up a function? Web workers? :)
How does this compare to http://sharpkit.net (free for small and open source projects) Feature wise? SharpKit seems more complete (language support and has source map debugging support on Chrome). Also support for all popular JS libraries.
SharpKit is only free as long as you want to use it for projects that don't need it (the limit is like 2k lines or something). When I last tried it I was not very happy with the code it generated. Additionally, it uses the standard mscorlib so it is not unlikely that you will end up calling methods that are not implemented (which is the very problem the tool is designed to avoid). If it were open source, I would have contributed to SharpKit instead of rolling my own, but it is not.
When it comes to the language support, I think Saltarelle is slightly ahead, as it supports goto and yield (I don't count SharpKit's implementation of yield which translate 'yield return "x"' to '$yield.push("x")' and then returns the $yield array).
Thanks for the reply, This seems to be a very nice tool. I will definitely try it out. Though I don't think that I will switch unless debugging is implemented (via source maps) like SharpKit has. This is invaluable to me at times.
But all those commits are, unfortunately, tiny. Also the compiler is not open-source only the runtime library (which Saltarelle uses a modified copy of).
Having the ability to run the same code in the browser and on the server, in C#, is really a big thing for me.
I think the debugging problem stated in many comments here is overrated: If you're writing an app the size that seriously benefits from the modularity, the tool support and the type checking of a language like C#, you will have a relatively small amount of code directly touching the DOM. All of that other code can be simply unit tested in C#-o-world, straight from the dev environment. If you're writing C#, don't test and debug like it's JS!
Surely such an approach won't catch all bugs and the occasional leaky abstraction (or compiler bug), but it should get one pretty far. Some in-browser unit testing lib together with the fact that the generated JS is quite readable indeed, should help me get the rest of the way.
Can't wait to dive in!