Friday, November 21, 2008

Speaking at WPI on 2008-11-24

wpi_logo 

Monday, November 24 I'm speaking at Worcester Polytechnic Institute in Worcester, MA about what I've been doing since graduating in May 2007. There will be a trip down memory lane, Ruby, Python, .NET, Macs, Robots, Music, and spontaneity; it will be epic.

Jimmy hacking (at) Microsoft
Monday, November 21, 2008, 6pm
Fuller Auditorium, Fuller Labs
Worcester Polytechnic Institute
100 Institute Road
Worcester, MA 01609

I'm flying to NY tonight (woot for red-eyes) with Felicia, and then driving/busing (depends how much work is left to do ;)) to Worcester Sunday. Should be a fun couple of days.

If you're in the Worcester-area, stop by! Slides/Demos will be posted shortly after the talk, and I'm looking into recording.

Monday, November 17, 2008

Adding scripting to a C# Silverlight app

The Minority

At Microsoft, the people I work with and I are definitely the minority, preaching about the benefits of dynamic languages and using the right tools for the right jobs, as in don't use static languages where you don't need it -- though there are plenty of times where you need it.

And now you ask, "Jimmy, but why would I, someone who gets paid to write C#, use a dynamic language?"

The majority would only have static languages pulled from their cold, dead fingers, and I totally agree with them. Don't change for the sake of change. Though, for certain scenarios, running scripts in a VB/C# application would be useful. For example, a shopping application that has a bunch of business rules, like "when someone has three items in their cart that all have to do with cooking, give them 10% off." These type of rules can change all the time, and traditionally you'd either store the rules in a database and implement a engine to understand the rules, or hand-code them yourself and have to redeploy the system every time you want to change them.

Or, you could save yourself the hassle and store the rules as Python or Ruby code, and then host the DLR in your application to run the code. Want to update the rules? Just update the code, nothing more. And a dynamic language is probably closer to how the domain-expert would represent them as, so they could even write them. Yes, this is just one scenario, but a powerful one for existing static language developers. This was the last part of my Seattle CodeCamp talk -- how to host the DLR in your C# Silverlight application.

Starting with an existing C# Silverlight application that just takes some input and echos it back, I'll extend it to run the code through IronRuby and print the result. First, open the solution, and hit F5 to see that the app just echos what you type in the grey area. This requires you to have installed the Silverlight Tools.

image

Now add references to the DLR and IronRuby (in the Dependencies folder):

image

Let's write a little wrapper class run Ruby code. Open App.xaml.cs and add the following class to the SilverlightDLRDemo namespace:

class RubyEngine {
  private ScriptEngine _engine;

  public RubyEngine() {
    var runtime = new ScriptRuntime(
      DynamicApplication.CreateRuntimeSetup()
    );
    _engine = Ruby.GetEngine(runtime);
  }

  public object Execute(string code) {
    return _engine.Execute(code);
  }
}

Note: this exact code won't work on the Desktop; you'd have to just give the ScriptRuntime constructor no parameters. Here I use the DynamicApplication.CreateRuntimeSetup() to use the same ScriptRuntimeSetup object that Microsoft.Scripting.Silverlight uses, which knows how to map File system access to the XAP file, which is useful for dynamic languages to depend on other files. Of course, it's your decision to allow this or not.

You'll also need to add the following "using" statements:

using Microsoft.Scripting.Hosting;
using IronRuby;
using Microsoft.Scripting.Silverlight;

And that's it! That's all we need to run IronRuby code. Now let's hook it up to the page. Open Page.xaml.cs and add an instance variable to the Page class, and initialize it in the Page constructor:

// add to Page class
private RubyEngine _ruby;

// add to Page constructor
_ruby = new RubyEngine();

Lastly, replace the "Result.Text = ..." line with this, which prints the typed code, and then the result computed by the RubyEngine wrapper we just wrote:

Result.Text = "\n\n" + 
  ">> " + Code.Text + "\n" +
  (_ruby.Execute(Code.Text).ToString()) + 
  Result.Text;

Now hit F5 again, and type some Ruby into the TextBox, hit enter, and boom, you're C# Silverlight application is running IronRuby code.

image

In fact, this is exactly how AgDLR, aka the dynamic language integration with Silverlight, works -- a C# application (Microsoft.Scripting.Silverlight.dll) which hosts the DLR and runs a script file (app.rb or app.py). Take a look for yourself.

I hope that shows you how easy it is to host the DLR from a C# Silverlight application, and think twice when writing those complex rule engines. =)

"console=true": REPLs in Silverlight

At Seattle CodeCamp v4.0 today, I talked a lot about REPLs, or "Read, Evaluate, Print Loops". They are the true "minimalist" view of programming; type a line, run a line. Most of them are no frills, only a terminal window and a blinking cursor, though they themselves could be really rich development environments. Also, REPLs are a vital tool for runtime-compilation languages, since the methods/variables/classes/etc are only *really* known to exist at runtime.

I started my talk with a Ruby REPL showing off how you can use IronRuby to explore .NET.

ruby-browser-repl

Ah, the beauty of two worlds colliding. You can use Ruby-idioms to explore the .NET types, starting with an A, B, or C, in the System namespace, just like they were Ruby classes to begin with. Call .NET methods, even with Ruby method naming conventions; IsInterface as is_interface.

The lurking awesomeness here is this REPL is running inside the browser! This is a HTML-based Silverlight application, which provides an IronRuby REPL. It accomplishes this by using the Dynamic Language Runtime (DLR) hosting APIs, but don't get hung up on the details of how that works, I'll explain later.

Monkey patching

This is nothing *new* in my world. DLRConsole has been around for a while now, and lets you write code in the browser to manipulate a Silverlight canvas. Both REPLs are self-contained, as in they only work against code manually loaded into them, like the previous screenshot shows with loading in the clock.rb and drag.rb files. This is fine for trying small things out, but becomes very cumbersome when trying to interact with a live application.

To interact with a live application seamlessly, the bare minimum would be to have a REPL available directly in the application itself. And that's what I've done:

silverlight-repl

If you build the latest bits, you can add a new initParam option called "console" to enable a REPL in any application:

<object ... >
  ...
  <param name="initParams" value="console=true" />
</object>

This will inject a HTML-based REPL into whatever web page your app is running on. The language of the REPL is set to whatever language your start script is. To make the console pretty, add this stylesheet to your page. Eventually this stylesheet will be included in the templates script/sl produces.

In the screenshot above, I did not type/click anything on the UI; the code I typed into the REPL set the search term and "clicked" the search button. This type of integration with your application could easily produce Waitr-like automation, for testing and whatnot. I'd really like to see Waitr ported to IronRuby. =

But there's plenty more to-do: this console is very simple.

  • It only supports Ruby currently; though simple Python statements will work (white space is a bitch =P).
  • It supports single and multi-line statements, but since the text input is implemented on top of a <input> tag, browser history gets in the way =P
  • History works, but never resets itself.
  • If you make a typo, and it's not clear that you've intended for the statement to be completed (like typing "class <enter>"), you'll have to force the console to run the command with <ctrl>+<enter>

Please, play around with this new "usefulness" and let me know what you think. I'd prefer you to leave comments on github, so everyone can participate in the discussion. The code for the REPL lives in Console.cs, so if you want to fix something on the list above, or see something else broken, fix it! If you find more bugs, please post them to Codeplex under the 0.x.0 release.

Hope this little feature makes your live a bit easier!

agdlr: Silverlight + DLR + Open Source

The "Silverlight Dynamic Languages SDK" Codeplex project has existed since March 2008, with signed binary releases and source code drops every month or so. Though it's a good ship vehicle for the Silverlight+DLR integration, it's not really an open source project -- mainly as it lacks a public source repository. That changes today.

AgDLR Source Repository

This repository will contain the sources to Microsoft.Scripting.Silverlight.dll and Chiron.exe, as well as Ruby/Python libraries for writing Silverlight applications. Any "feature" work on those pieces of code will be committed to the public repository first, and eventually make its way into MIcrosoft's internal source control so the DLR/Iron* languages don't break it. This repository takes a binary dependency on the Iron* languages as well as the DLR, since this isn't the place to change that code. The source code for IronRuby, IronPython, and the DLR are available elsewhere, but releases on the Codeplex page for this project will still contain source drops of everything.

The repository is hosted on http://github.com, which is a collaborative development site based around git, a "fast, efficient, distributed version control system ideal for the collaborative development of software". You can browse the sources on the website, look at commits, fork your own version of the repository, or just download a snapshot. If you're new to git, just install it (for windows, see here, and here). If you'd like to learn more about Github, or Git, Github guides is a good place to start.

If you'd like to contribute to AgDLR, fork your own version of the repository, commit your changes to your version, and send me a pull request on github. We'll take it from there.

I've already started to work on a new feature which I talked about at Seattle CodeCamp, but that's the next post.

Sunday, November 16, 2008

Seattle CodeCamp v4.0

I just finished speaking at Seattle CodeCamp v4.0 about dynamic languages in Silverlight, titled Browser, Meet Ruby and Python. Here's my abstract:

People entrenched in Visual Studio all day [sometimes] forget how powerful a command-line and a text-editor can be. Remember, these are the *tools* that built and continue-to-build the web. With nothing else up my sleeves (I wear short sleeves) I'll build a cool web applications with IronRuby, IronPython, ASP.NET MVC, and Silverlight, and show you why scripting/dynamic languages are powerful and productive tools.

Of course, that didn't end up being my exact talk, but close enough. I talked about REPL's, IronRuby, Silverlight, and Hippies. Here are the slides (rename it to pptx since my web server is reporting it as a zip mime-type), but I'll be making subsequent posts about the specific things I showed. Stay tuned!

Wednesday, October 15, 2008

Dynamic Languages in Silverlight 2 RTW!

Silverlight 2 shipped yesterday! And, better yet, there's a new release of dynamic languages for Silverlight!

 

Download the SDK!

Note: it's the same version number as the RC0 release (0.4.0)

 

Since this post is devoid of content, here's a bunch of other posts I've made that are more interesting. Here are some announcement blog posts:

For more interesting posts/walk-throughs:

Wednesday, October 01, 2008

Dynamic Languages in Silverlight 2 RC0

I've just released the Silverlight Dynamic Languages SDK with the newest DLR, IronRuby, IronPython, and JScript binaries and sources to work against Silverlight 2 RC0!

 

Download the SDK!

 

This release works with Silverlight 2 RC0. Keep in mind this is a developer release, so no "end-user" runtime exists. This is why the "not-installed" experience doesn't take you directly to the download, but to a page where you can install the tools.

As usual, report any issues on the Issue Tracker, and feel free to ask any questions on the Discussions tab.

This release has slightly refactored Microsoft.Scripting.Silverlight, adding two new types: "Package" and "Configuration". You can use "Package" to access files inside the XAP, and "Configuration" can be used to detect languages available in Silverlight.

Hosting

In past releases, if you wanted to host the DLR you needed to create your own ScriptRuntimeSetup which uses Microsoft.Scripting.Silverlight.BrowserScriptHost to tell your hosted scripts about how Silverlight. Your code would look like this:

using Microsoft.Scripting.Silverlight;
using Microsoft.Scripting.Hosting;

//...

var setup = new ScriptRuntimeSetup();
setup.HostType = typeof(BrowserScriptHost);
var runtime = new ScriptRuntime(setup);

//...

Now, since the ScriptRuntimeSetup we use to run user code is public, you can simply this code to:

using Microsoft.Scripting.Silverlight;
using Microsoft.Scripting.Hosting;

//...

var runtime = DynamicApplication.Current.Runtime;

// or if you wanted to create your own runtime, reuse the setup

var runtime = new ScriptRuntime(DynamicApplication.Current.Runtime.Setup);

//...

Future

Blah, blah, blah, I always talk about the future. Has anything happened? Nope. Well, it will eventually. Just keep pestering. If you have no idea what I'm talking about, take a look at my last post.

Tuesday, September 30, 2008

Compiling the DLR, IronRuby, and IronPython for ANY version of Silverlight

swan2008 (1)

I know you feel like this sometimes when trying to solve a problem. I do. Almost all the time. Even when I'm not angry ... but I digress.

Silverlight 2 RC0 was released this past Thursday, but anyone wanting to use the DLR in it was surprised ... no new binary release of the DLR bits for Silverlight 2 RC0 yet. As I said on Twitter, it would be delayed until today, but that shouldn't stop anyone from taking the sources and compiling them against the new SIlverlight build, right?

Of course! Everything should just work, since there were no major breaking changes in Silverlight that affect the DLR between Beta2 and RC0. So, you hacked up the csproj files to point at mscorlib.dll, system.dll, etc in the new Silverlight install directory (C:\Program Files\Microsoft Silverlight\2.0.30923.0), compile, and it builds fine. Then you try to run an app ...

"InitializeError- Failed to load the application. It was built with an obsolete version of Silverlight"

Poof! What the hell happened? That's a really bad error message, but what it means to say is:

"The application's AppManifest.xaml has a RuntimeVersion <= 2.0.30523.00, which is Silverlight 2 Beta 2's version number, so Silverlight 2 RC0 won't load this application."

So you see, the XAP file that was produced by Chiron is still for SL2 Beta2. But that's an easy fix;

  1. Make sure Chiron.exe isn't running.
  2. Go to your custom build, and edit Chiron.exe.config
  3. Find the <AppManifest.xaml> section, and where it says "RuntimeVersion" make it's value be "2.0.30923.0" (anything with the first three version numbers being greater than the current will do, but be save and use the actual version.)
  4. Re-run Chiron.exe, navigate to your Silverlight application, and .... it works!

Welcome to the wonderful world of versioning in Silverlight. :)

Tuesday, September 23, 2008

ASP.NET Dynamic Language Support Refreshed!

party_time_top

Today, the IronPython team and the ASP.NET team released ASP.NET Dynamic Language Support on the ASP.NET Codeplex site!

 

Download it here!

 

Package

ironpython-webforms-sample.zip: running IronPython ASP.NET website. Either dump this in IIS or open with Visual Studio as a website project.

ironpython-mvc-sample.zip: and IronPython ASP.NET MVC website, so you can get a feel for how dynamic languages can integrate into MVC. However, this just shows IronPython working in Views, not Controllers or Models yet. This requires MVC to be installed to open the project in Visual Studio. Open it with Visual Studio, build, and run your shiny IronPython ASP.NET MVC app.

aspnet-dlr-docs.zip: Documentation on how to use all this stuff. Open intro.html and have fun. :)

 

Many Thanks!

This is a project that me, David Ebbo, and Phil Haack have been working on for a bit, and I'm so happy that the ASP.NET team is taking the DLR and committing to making dynamic languages work well on ASP.NET. Phil actually announced this on his blog as well, and I'm sure will be talking about this much more in the future. In short, a big thanks to David and Phil for getting this project kick-started again.

 

Walk-through: WebForms

Back in June I talked about this day coming, but I didn't even have a piece offering, other than my whit. To make up for that, I'm going to walk you through using IronPython in ASP.NET.

Note: I'm going to walk you through using Visual Studio to open the website and make changes. However, you can simply drop this directory into your IIS wwwroot and simply edit the files with a text-editor of your choice.

1. Extract ironpython-webforms-sample.zip, open Visual Studio, and then open a website project (File > Open > Web Site ...). Navigate to where you extracted the webforms sample, and click open; now you should see the following.

merlinweb-start

2. Take a look at the code in Default.aspx and Default.aspx.py. The aspx page has a asp:Literal control, with the id "messageLiteral", and the py file sets the text of that asp:Literal control.

<!-- Default.aspx -->
<%@ Page Language="IronPython" CodeFile="Default.aspx.py" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Literal id="messageLiteral" runat="server" />
        </div>
        </form>
    </body>
</html>
# Default.aspx.py
def Page_Load(sender, e):
    messageLiteral.Text = "Hello Dynamic World!"

3. Hit Ctrl+F5 (Start without debugging), and the app will run. If you are not using Visual Studio, simply navigate to Default.aspx in your web browser.

merlinweb-hello-dynamic-world

4. Awesome, our app runs! Now let's make it do something. Replace the inside of the <div /> with a Label, TextBox, and a Button control (Note: you can also open the Toolbox in Visual Studio and drag these in).

Enter your name: <br />
    <asp:TextBox ID="TextBox1" runat="server">
    </asp:TextBox>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    <br /><br />
    <asp:Label ID="Label1" runat="server" Text="Label">
    </asp:Label>

5. Open Default.aspx.py and change the Page_Load method to be the following:

def Page_Load(sender, e):
    if not IsPostBack:
        Label1.Text = "...Your name here..."

6. Now add the following code to Default.aspx.py to handle the button's Click event:

def Button1_Click(sender, e):
    Label1.Text = Textbox1.Text

7. Switch back to Default.aspx.py and make the Button handle the event:

<asp:Button ID="Button1" runat="server" Text="Button"
     OnClick="Button1_Click"/>

8. Now navigate back to your browser, and refresh the page. Enter any text in the textblock, click the button, and it'll appear in the label below.

merlinweb-name

Yeah, I know, not very useful, but it gives you an idea of how things work. Look through the "ASP.NET Dynamic Language Runtime Support Documentation" on the downloads page for more walk-throughs with IronPython and ASP.NET WebForms.

 

Go make awesome stuff!

I'm so happy that this finally got out, so hopefully I'll hear about people starting to use IronPython in ASP.NET much more. Consult http://codeplex.com/aspnet for any questions about roadmap or tutorials, and feel free to ask me questions as well.