Today Mix Online Lab released a prototype implementation of Ruby and Python in the browser, named Gestalt. Feeling a bit of de ja vu? If not, you can ignore this post and just see what it’s all about. Regardless, I suggest you read on.
A simple Ruby-based web page using Gestalt would look like this:
Gestalt adds “ruby” and “python” to the languages supported by the <script> tag. You can also include other files rather than writing the code in the HTML page:
My first reactions when hearing about this project was “Holy crap, wow, they got Ruby and Python running in the browser, that’s freakin’ awesome!” But I work on the Silverlight integration with IronRuby and IronPython, already letting you write Ruby and Python in the browser instead of JavaScript. Hmm. Not to my surprise, Gestalt uses IronRuby and IronPython in Silverlight to accomplish this. But damn, wouldn’t it be awesome if this is how the world worked?
For any new readers, IronRuby and IronPython are implementations of Ruby and Python for the .NET Framework, utilizing the Dynamic Language Runtime (DLR).
Gestalt is a effort to show what it would be like if there were other standard languages in the browser, other than just JavaScript. The Mix Online Lab focuses on using Microsoft technology in ways that make non-Microsoft developers interested, so this project is right up their alley. They wanted to showcase the DLR languages in Silverlight as a way of showing how our efforts can make the web a better place.
So what are the difference between IronRuby and IronPython’s Silverlight integration and what Gestalt provides?
Again, you can already make IronRuby and IronPython based applications in Silverlight; Gestalt just puts a new spin on how to do that. IronRuby and IronPython use the XAP file for the application packaging, including script files, and provides a development-tool called Chiron to auto-package the app, providing the edit-refresh experience that is familiar for a web browser app. Chiron is also used to write the package to disk so it can be deployed to any web-server. This model works great for getting new and existing Ruby and Python programs running in Silverlight, as the packaging is transparent to a developer. And it doesn’t fight Silverlight’s packaging conventions, so using Silverlight-specific features will be straight-forward from a DLR language.
Gestalt takes a much different approach using <script> tags, making the integration much more familiar to current JavaScript developers. They also handle all the Silverlight <object> tag stuff in gestalt.js, taking away the need to host Silverlight yourself.
Why Gestalt is interesting to me
The thing that I really like about Gestalt is that Chiron is not needed for development. Just edit the file and refresh the browser. No need to run something in the background generating a XAP file. Gestalt.js detects which languages the page’s <script> tags use, and picks a pre-packaged Gestalt-*.xap file, one for Ruby, one for Python, one for both, and one for none. This means your application could look something like this:
- index.html (can contain Python and/or Ruby code)
- gestalt/
- gestalt.js
- gestalt-rb.xap
- gestalt-py.xap
- gestalt.xap
- gestalt-x.xap
Very clean. The gestalt directory is just dropped onto your web-server (to be shared among all your applications), and gestalt.js is referenced from your HTML file, and your good to go. No running Chiron.exe, or installing Mono on the Mac to run Chiron.exe. I’m jealous.
So what’s the catch?
While Gestalt is a much simpler to get started writing Ruby and Python applications in the browser, it does not support a major feature of Ruby and Python – accessing something like a file-system. For example, including other files at runtime uses the language’s underlying File access to read the file in and run it’s contents. Ruby uses “require” or “load”, and python uses “import” to do this.
IronRuby and IronPython in Silverlight normally support this, as all file reads are redirected to the XAP file. Since Gestalt’s XAP files are opaque to the the developer, they do not support File access. This is only an issue when you want to use existing Ruby or Python code in the browser. For example, existing code usually has more dependencies, especially into portion of the language’s standard library which is written the language itself. Usually you’d just put these files in the folder that Chiron is auto-xapping for you, and that’s it. However, Gestalt has no way of doing this today.
Making it better
A possible solution is to just cache the contents of <script src> tags, and use the languages path resolution mechanism to test if those files have already been downloaded. If it finds a match, serve the file’s contents. If not, it could either fail fast and say that your missing a <script src> reference, or it COULD download the file synchronously (and still cache it) and display a warning that you are missing a <script src> reference.
Unfortunately, this only works for script files; what if you just want to download a txt file? Having <script src=”foo.txt”> is not going to fly. Maybe using <link> tags could work?
Why can’t we just download them synchronously? No! Though the current bits do have a synchronous downloading mode, it’s only experimental and should not be used in production. Synchronous downloads are significantly slower since only one download can occur at a time. Downloads need to be synchronous since “opening a file” is expected to block until it is complete. Also, IronRuby/IronPython do not support continuations (for good reasons), so the code cannot be “paused” while a file is downloaded, and then be “resumed” when done. And even if they did support continuations (as there is a way to get it working for the very specific case of file access), the downloads would still all occur one at a time, making the loading much slower. So downloading “on-demand” for file reads is not a good solution, and that’s precisely why the browser doesn’t do that today … so let’s not fight it.
Is Gestalt going to always be separate from IronRuby and IronPython?
No! :) While Gestalt’s first release was best to be separate, I’m very interested in merging the ideas Gestalt has back into Microsoft.Scripting.Silverlight … in-fact discussions have already begun on the IronPython Mailing List.
In short, Ruby and Python Silverlight applications are a bit too complex, and Gestalt shows us that it doesn’t need to be that way. Work has already begun to merge Gestalt and Microsoft.Scripting.Silverlight, so play with Gestalt and let me know what you think!