9 ms·
New C# to Javascript compiler released
- bdfh42 14y agoThe 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.
- erik-kallen 14y agoActually, 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"?
- jrajav 14y agoWell, 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.
- erik-kallen 14y agoYou can use the Chrome debugger just as if you had written the Javascript directly.
- prasincs 14y agoThe 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?
- erik-kallen 14y agoIt 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.
- prasincs 14y agoI 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 :)
- giulianob 14y agoI 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).
- bdfh42 14y agoI think it would help the discussion if you could define a "large app" as far as JavaScript is concerned and why you think it is a "nightmare".
- giulianob 14y agoI'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).
- marcelvr 14y ago"... but when it is JavaScript that will be run by the browser then JavaScript is what you should be writing." 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!
- weego 14y agoCome on, we all know that isn't a logical equality.
- giulianob 14y agoOnce the debugging tools are able to keep everything abstracted then you no longer need to dig down. Example is of course writing assembly.
- 0ptr 14y agoYeah there's no logical equality to machine code and C++ but still people use debuggers. I don't think this is something that cannot be solved.
- bdfh42 14y agoBut 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.
- marcelvr 14y agoI 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.
- mistercow 14y ago>when it is JavaScript that will be run by the browser then JavaScript is what you should be writing. Of course, source maps will soon make this point largely moot.
- batista 14y agoHaven't happened for the last 2 years we've been waiting for them.
- Kototama 14y agoMaybe that's where source maps come handy? http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ http://www.html5rocks.com/en/tutorials/developertools/source...
- eckyptang 14y agoThis 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 :)
- randomfool 14y agoI don't see how these are significantly different than .PDBs which allow Windows developers to step through their source code when debugging compiled binaries.
- eckyptang 14y agoIt is similar to PDB files, which is fine but that is not the issue. The issue is that the abstraction is criminally tall. We're talking a tower of: 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.
- dmethvin 14y agoThey do come in handy, if only they were supported everywhere. Right now it's just Chrome and a small number of tools.
- WayneDB 14y agoI don't see the problem. - 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.
- bdfh42 14y agoBut 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.
- jdonaldson 14y agoI 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.
- michaelwww 14y agoIt's likely there would be less need for JavaScript debugging.
- dotborg 14y agoYou should run and debug the C# code, before you compile it to JS, that's how I understand the idea behind this project.
- hhudolet 14y agoLooks cool, but need more docs and samples (for each feature)!
- jaz 14y agoI came across a similar project on /r/csharp last week. The project's called Blade, and is available here - https://github.com/vannatech/blade https://github.com/vannatech/blade
- erik-kallen 14y agoSaltarelle is way more complete, though.
- WayneDB 14y agoThanks Erik! I haven't touched Script# due to the fact that development stalled and it (was) closed source. Looking forward to seeing how this performs.
- josephcooney 14y agoScript# is alive and well AFAIK. It is hosted on github, with about 9 commits from the primary author in the last week. https://github.com/nikhilk/scriptsharp/commits/master https://github.com/nikhilk/scriptsharp/commits/master
- erik-kallen 14y agoBut all those commits are, unfortunately, tiny. Also the compiler is not open-source only the runtime library (which Saltarelle uses a modified copy of).
- scorcher 14y agoI 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?
- jeswin 14y ago- 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.
- erik-kallen 14y agoThat's right, it doesn't get horrific until you use goto or yield (which don't exist in Javascript so they have to be emulated).
- TazeTSchnitzel 14y agoSome 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? :)
- erik-kallen 14y agofor (;;), continue and switch.
- 0ptr 14y agoI 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!
- ecocentrik 14y agoThere 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.
- eckyptang 14y agoFlash, silverlight, Java, native apps...
- deleted 14y ago[deleted]
- acron0 14y agoNot entirely the same, but for those of us on Window, I prefer the look of http://jsil.org http://jsil.org.
- erik-kallen 14y agoJSIL 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.
- azakai 14y agoCould you not somehow reuse the JSIL code generator, and add things for the approach you took in Saltarelle (good integration with JQuery etc.)? Another question, did you do any performance comparisons of Saltarelle? (to normal C# builds, to JSIL, or anything else?)
- erik-kallen 14y agoI 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 :)
- azakai 14y agoWell, 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.
- OllieJones 14y agoWow! A great hack on hacker news! Thanks Erik. Don't let the griping grind you down.
- TazeTSchnitzel 14y agoWow, very cool. I like C#, and the DOM is actually specified with types, so statically-typed web dev with this would be awesome.
- Hovertruck 14y agoYou can get the majority of this functionality with Closure Compiler though, without needing to abstract the entire language away.
- TazeTSchnitzel 14y agoThat's true, but I don't really like the closure compiler's syntax.
- Fizzer 14y agoLooks impressive! 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?
- erik-kallen 14y agoWhy would I want to use the proprietary Roslyn when I have a working solution with the open-source NRefactory and Cecil?
- Fizzer 14y agoI can think of a dozen reasons off the top of my head. But if you prefer to avoid proprietary utilities that's understandable.
- hpguy 14y agoNRefactory itself depends on Cecil, so his translator might not use Cecil at all.
- DougWebb 14y agoI 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.
- michaelwww 14y agoI think what you're saying is a given...
- DougWebb 14y agoThe 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.
- michaelwww 14y agoI'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.
- eranation 14y agoThe 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.
- goggles99 14y agoHow does this compare to http://sharpkit.net 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.
- erik-kallen 14y agoSharpKit 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).
- goggles99 14y agoThanks 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.
- consultutah 14y agoWe 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.
- skrebbel 14y agoAs 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. Can't wait to dive in!
- michaelwww 14y agoAfter 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.
- randomfool 14y agoMy 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.
- NonEUCitizen 14y agoDoes this include a library for accessing Canvas ? Thanks.
- prpatel 14y agogood grief... just learn some fscking JavaScript already! It's not _that_ hard!