New C# to Javascript compiler released
erik-kallen.se
erik-kallen.se
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!
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.
And yes, many people are against Coffeescript too for precisely this reason.
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?
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.
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 :)
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).
GWT is not the answer, Dart is not the answer, not writing JS is not the answer (maybe CoffeeScript but I'm skeptical)
JS may have its warts, but in the end that's what browsers understand. That's what you'll have to know to debug things.
And the browser doesn't have to execute 2x, 3x the code, and use more memory as well
If you want something to help my perception is that it should be a thin shin (like CS) rather than "full bells and whistles" on top like GWT or Dart
So by that logic, one shouldn't be writing C# that targets the CLR either, but should rather be coding in MSIL directly. Mmm, no thanks!
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.
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.
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.
Check out this stack trace:
http://www.ibm.com/developerworks/java/library/os-ecspy1/sta...
Now imagine that across three different languages.
Of course, source maps will soon make this point largely moot.
http://www.html5rocks.com/en/tutorials/developertools/source...
The slightly overbearing complexity of the solution matches the linguistic complexity of the statement above :)
Process: C# --(compiler)--> Js --(parser)--> IL --(compiler)--> machine code/interpreter.
Type conversions: Static --> dynamic --> static --> none.
That's just too much to go wrong in my mind. I wouldn't touch it with a barge pole.
- If I had written Javascript, I would have to debug the Javascript that is running in the browser.
- If a tool writes Javascript for me, I have to debug Javascript running in the browser.
A better wish would be: I hope that your tool outputs nicely formatted and easy to debug Javascript.
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?
Another question, did you do any performance comparisons of Saltarelle? (to normal C# builds, to JSIL, or anything else?)
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.
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.
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.
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.
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.
https://developers.google.com/closure/
There are no editors that give you the nice intellisense bells and whistles, but static typing is by far the most important for me.
Here is a nice side project, static typed coffee script, with eclipse IDE support...
I really don't want to go back to GWT or move to Dart...
Scala's Javascript DSL is another hope I have, but it's still under development
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.
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.
- It might be simpler to write JS, but I can imagine people wanting to see if type-safety has benefits.
Curious to see how you managed the emulation - splitting up a function? Web workers? :)
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).
Looking forward to seeing how this performs.