The Command History in PowerShell

Link. February 28, 2008. Comments [0]. Posted in: PowerShell

Sometimes you're executing a series of commands when using the PowerShell console and have to go back and forth repeating commands you've used before. Sometimes, just using the up/down arrow keys is enough (or their close cousins: F7, F8 and F9).

However, sometimes it isn't enough. One of the issues with up/down and friends is that this really isn't implemented by PowerShell (or whatever PowerShell host you're using), but by the Windows Console Subsystem in CRSS.EXE. And sometimes it can also be a drag.

Fortunately, PowerShell has some pretty useful things that I had not played with much before, but they turn out to be pretty useful.

Get-History

PowerShell keeps track of the last N commands you've executed in the "History", where N == 64 by default. You can modify how many commands the history will contain by setting the $MaximumHistoryCount variable in your profile scripts.

Technically speaking, exactly what gets stored here depends on the Host application, but the default ConsoleHost pretty much does what you'd normally expect.

You can check your history using the Get-History command, which by default is aliased as 'ghy', 'h' and 'history'. Go on and give it a try!

One interesting thing is that each entry in the history is given an Id, which you can use later on to refer to that specific entry in the command history.

Repeating a Command

You can repeat (i.e. execute again) an arbitrary entry in the command history by using the Invoke-History command and passing it the Id of the entry to execute again:

Invoke-History 45

If you don't provide an Id, then the last entry in the history will be executed again (or you can also pass in a string with the first few characters of the command and the history is searched backwards for the first match).

This is pretty handy also, because Invoke-History is by default aliased as 'r' and 'ihy'. So you can simply repeat the last command using "r<enter>".

One thing to watch out for is that Invoke-History will first write to the console the command it is going to execute, so keep that in mind when looking at the output.

Notice that when you use Invoke-History, the Invoke-History command itself will not go into the command history. However, the command executed as a result of the use of Invoke-History will indeed get appended to the history!

The Last Command

Another interesting thing is that, PowerShell will store the last command executed into the $^ variable. So an easy way to check what the last command executed was is to simply type $^ at the prompt:

tomasr@arcano {~\scripts} $^
cls

Let me reiterate something: The $^ variable stores the last command directly executed, not the last command in the history. That means that if you call Invoke-History, then $^ will contain your Invoke-History command, not the actual command executed as a result.

It does provide for some funky stuff. For example, you can repeat the last executed command (yes, even redo an Invoke-History command) using:

tomasr@arcano {~\scripts} &$^

  Id CommandLine
  -- -----------
  89 $ExecutionContext.SessionState
  90 $ExecutionContext.SessionState.Host
  91 $ExecutionContext.Host

A discrepancy

There's another interesting difference between $^ and the history. For example, let's say you execute a compound command like "ls; echo done".

If you immediately check the history, you'll see that the last entry in the list is indeed the entire thing ("ls; echo done"). This means that history really keeps track of entire pipelines executed.

However, if you immediately check the value of $^, you'll notice that it only contains the first part of the pipeline ("ls"); not the entire thing. In fact, $^ only stores the first command in the pipeline executed; so if you execute, say, "ls | sort", still only "ls" is stored; which is certainly a lot less useful (but still interesting).

Add-History

There's also an Add-History command you can use to push stuff into the history without actually executing it first. In theory, this would seem to be aimed primarily at making it possible to persist the history across sessions. All you need to do is save the contents of your history to a file and then read it back and feed it to Add-History.

This is unfortunately less than useful, because it is not done automatically for you. You can partially automate it, but since it requires you to explicitly use a command to close your session, well, little chance of our fingers and brains getting used to it (and even if you do, what happens if you accidentally close the window instead of typing the right command?). Looks like V2 might help here; would be nice.

Have fun!

Filenames Starting with a Dot

Link. February 25, 2008. Comments [8]. Posted in: Vista

In Unix, it's common to name files and folders with names starting with a '.' to make them "hidden". This convention is not really needed in Windows, since there's a file system attribute for that, but still interesting.

See, a few tools ported from Unix that relied on this convention use a different one in Windows, replacing the '.' with a '_'. So, for example, your Vim settings file will be "_vimrc" instead of ".vimrc" and so on. Seems pretty obvious they did this because at some point in time file/folder names could not start with a dot.

Windows 9x probably had this limitation, and probably still lives on in FAT-based file systems (but I don't have one anywhere to test this assertion, nor do I particularly care about it). However, modern Windows and NTFS have no such limitation. Almost.

See, NTFS certainly let's you create a folder named ".vimfiles" or a file named ".txt" for that matter. You can do so programatically using the standard file handling APIs. You can do it from the command line using mkdir/echo.

But you can't do it using Windows Explorer. For example, Vista and WinServer2k8 will complain that "You must type a filename" if you attempt to name a folder/file with a dot as the first character in the name.

Why Explorer explicitly disallows it, I'm not sure, but seems pretty funky. There are probably thousands of applications or utilities out there that might get confused with a file or folder named like that, though.

More Music

Link. February 25, 2008. Comments [0]. Posted in: Personal

Here's some music I've recently gotten my hands on:

  • Dokken: From Conception - Live 1981. Dokken playing live at its best. It's also my second Dokken live album, as I already owned their Live from the Sun album.
  • Edguy: Hellfire Club. Edguy's always a fun band; several good tracks in this one like "We don't need a Hero", "King of fools" and my favorite, "Navigator".
  • Kamelot: Ghost Opera. A solid album, as most of previous Kamelot works.
  • Diabolique: Black Sun Collection. This is a double album combining their Wedding the Grotesque and The Black Flower albums, though the second one is far more polished and a lot better overall (I particularly liked songs like "Dark Rivers of the Heart", "Yesmine" and "Play in the dark". I also own their Butterflies album which is one of my favorites around.
  • Freedom Call: Eternity. It's an ok album, but clearly not their best.
  • Iron Maiden: No Prayer for the Dying. I had a copy of this album many many years ago and lost it, and ran into it a couple of weeks ago at Tower Records and got it. The only reason they're carrying this stuff is because Iron Maiden is giving a concert in Bogota soon, though I won't be attending :-(.
  • Winger: IV. Didn't really expect to get this one, given that I was never really a Winger fan, but it actually has a few really good songs, like "Four Leaf Clover".
  • David Shankle Group: Ashes to Ashes. Interesting album, though somewhat of a mixed bag. So far I'm liking "The Widow's Peak" the best.

Can't Remove Drive on Vista SP1

Link. February 24, 2008. Comments [0]. Posted in: Vista

I haven't noticed many issues with Vista SP1, despite some stuff I've read around; though overall haven't really noticed any significant performance difference besides file operations using Windows Explorer.

That said, I've noticed one nasty issue: I use an external USB drive that has a bunch of virtual machines, my music and other stuff. I'm usually very careful and always use the "Safely Remove Hardware" icon in the system tray to remove the drive before disconnecting it from the computer or turning it off.

However, ever since installing SP1, this operation fails about 50% of the time, saying the volume is in use and cannot be removed, even though there are no applications open that could be using the drive at all.

The past few times it's happened, I've fired up Process Explorer to try and locate what is holding on to the drive, only to find that the only process that has file handles opened in the drive is the "System" pseudo-process:

EjectDrive

No idea which driver is holding on to the handles, but based on the file names, I might guess it has something to do with the Kernel transaction manager and NTFS transactions. Why those handles are being kept there, I have no idea; but once this happens, those don't get released, meaning I have to shut down the drive improperly. Not good.

Ast.ComplexCallHelper()

Link. February 21, 2008. Comments [0]. Posted in: DLR

Something I ran into yesterday: There are two variants to Ast.ComplexCallHelper() in the DLR: One takes a MethodInfo and the other a Delegate as the invocation target.

The MethodInfo variant does not check for the presence of a CodeContext argument, while the Delegate version handles this correctly. Not quite sure why the discrepancy between the two, but sure looks like using the Delegate variant is a better choice for now.

Simple Is Beautiful

Link. February 21, 2008. Comments [3]. Posted in: Vista
WinServer2k8

Am I the only one that thinks the Windows Server 2008 logon screen, with it's very simple blue background, is so much better looking that Vista's ugly and distracting "aurora" background?

There's just something highly appealing to me about keeping things simple and elegant...

PipelineUtil.CloneMessageContext()

Link. February 20, 2008. Comments [0]. Posted in: BizTalk

BizTalk Tip of the Day: If you're writing a custom BizTalk Pipeline Component (particularly a receive one), and you're creating a new message from scratch to return from your component, don't forget to copy the original message context into your new one.

And the right way to do this is using the CloneMessageContext() method of the PipelineUtil helper class included with BizTalk. Rolling your own and doing it incorrectly can result in really weird errors later on.

Watch out for ':' in PowerShell

Link. February 20, 2008. Comments [3]. Posted in: PowerShell

Here's something that tripped me the other day in a Windows PowerShell script. Let's say that you have to variables $user and $machine, and want to print a string with the value of both of them separated by a colon (':').

You can obviously do it using string concatenation:

$user = 'tomasr'
$machine = 'arcano'

write ($user + ':' + $machine)

That works, but doesn't PowerShell support that nice string interpolation feature? Why, yes it does! So why don't we just rewrite it like this:

write "$user:$machine"

But wait! If you run that last line, all you get is the value of the $machine variable... where did $user go?

The answer is that the colon has a special meaning in PowerShell variable names: It's used to associate the variable with a specific scope or namespace. There are a few scopes defined by PowerShell, such as script and global; so for example a global variable might be named $global:var.

But haven't we also seen that syntax elsewhere? Sure, how about $env:PATH? Same thing; except here env isn't a scope by itself, but a PSDrive. So the part before the ':' can either be either an actual scope defined by PS or a PSDrive. Heck, you can even try something like "${c:autoexec.bat}" and watch the magic happen!

So the problem with our string interpolation is that when PowerShell sees "$user:$machine", it expects to find a scope/psdrive named 'user' and expects a variable name to follow the ':', but '$' isn't valid, and 'user' isn't a scope or a PSDrive either, which confuses PowerShell a bit. But since he's too much of a gentleman he just fixes it up as best as he can and ignores everything up to this point and just dumps $machine without complaining. Nice of him, but it can really trip you up if you don't expect it!

Can we avoid this? Yes, we can, by simply delimiting variable names exactly for PowerShell by using '{}', like this:

write "${user}:$machine"

Section 5.8 on page 141 of Bruce Payette's excellent Windows PowerShell in Action covers the topic of variables in PowerShell and gave me the clue to work around this issue.

DLR Notes 5

Link. February 19, 2008. Comments [2]. Posted in: DLR

Here's one interesting issue I ran into while trying a few things out: Conversions.

Given the dynamic nature of the DLR and the languages implemented on top of it, and the statically typed nature of the CLR and most .NET languages, you need to be able to ensure that the right type conversions happen at the right places.

This involves, among other things, ensuring that the right casts and boxing/unboxing operations happen, as well as ensuring that language-specific conversions can be applied (such as, say, converting an arbitrary object to a CLR string through an explicit method call).

The DLR does a bunch of these automatically in a number of places, like variable writes and assignments, call return values and so on. Most of these can be made to follow language-specific behaviors because the conversion expressions are generated through calls to your language ActionBinder implementation (like the RubyBinder class in the case of IronRuby).

For example, many of these scenarios will generate calls to your ActionBinder.ConvertExpression() method. Here's one case I found where this does not happen, making it a bit more tedious:

Today I was debugging some code because of an InvalidCastException getting thrown. Indeed, the problem was that I had a method call that required converting one of the parameters, and it was a set of types I had not tried before. In this case, the necessary conversion was language specific, so I added the rule into my ActionBinder.ConvertExpression() implementation and made sure as well that ActionBinder.CanConvertFrom() handled the case as well.

But it was still not working. After a bit of debugging, I realized that in this particular case, the ActionBinder wasn't getting involved at all for the conversion! What was the deal?

The issue turns out to be that the call was being done through one of my IDynamicObject implementations. In particular, this one handled a Call action by generating a rule target containing a call to the target delegate using the DLR"s Ast.ComplexCallHelper() method.

The problem is that ComplexCallHelper() doesn't really deal with language-specific conversion needs at all. Instead, it relies on Ast.Convert() to convert the actual argument values to the types declared in the target method/delegate signature.

The problem with Ast.Convert() should be obvious by now: All Ast.Convert() and Ast.ConvertHelper() do is insert an explicit Cast expression into the code.

This works great if all that is needed is a box/unbox operation or an upcast/downcast, but not enough in our case, so it is something to watch out for! I still haven't decided yet how to best work around the issue

WinSxS

Link. February 15, 2008. Comments [0]. Posted in: Vista

Size of %WINDIR%\winsxs:

  • Clean Windows Server 2008 Enterprise installation: 2.6GB
  • Used Windows Vista SP1 installation: 6.52GB

I know that Side by Side installation is important for compatibility and serviceability, but this might just be going a bit overboard....

Vista SP1 Installed

Link. February 15, 2008. Comments [0]. Posted in: Vista

Service Pack 1 for Vista is now available for download from MSDN (I guess the Windows Update rollout will still wait to march or something). For some reason, though, it is a 434MB, 5-language pack.

I downloaded it last night and installed it this morning without too much fuss, except for Windows Live Messenger now keeps triggering Windows Installer on startup and failing (but it works after that, funky).

Haven't really noticed many improvements yet, though moving/copying stuff around in explorer seems quite bit faster (that alone might be worth it).

Programming with Large Fonts

Link. February 14, 2008. Comments [4]. Posted in: Development

Every once in a while someone voices their surprise when they try out one of my Visual Studio Color Schemes and find that all those very large fonts I leave by default on most of them [1].

I've been using Damien Guard's excellent Envy Code R font, usually at 15pt size, which I'm sure looks huge on some screens. It took some time for me to get used to it, as well, but I wouldn't change it now.

 VSFonts

The reason I started using large fonts when writing was readability. I've been mostly a laptop user for a number of years now, but a couple years back I started using one with a high-resolution (1920x1200) screen.

Having that much screen real state is fantastic, particularly on a large screen, but it can be a bit hard on a 15.4" laptop screen because most things will look pretty tiny. I have good eyesight, but looking at really small text for prolonged hours can really make your eyes (and your brain!) sore.

Instead of just fiddling around with the Visual Studio fonts, the ideal solution would've probably been to adjust the screen's DPI settings accordingly (120 DPI), but the truth is that, right now, that's not really an option on windows if you don't want a lot of applications to (a) look like crap or (b) become unusable because not all the controls fit into the display. Unfortunately, most Windows applications aren't really ready to work with high DPI settings and/or large system fonts, so this isn't as good an option.

However, it turns out that you don't really spend most of your time looking carefully and closely at all applications were text might be small. Instead, you spend most of your time in a few key applications, and simply increasing the font size for those can really make a difference in how you feel at the end of the day.

In my case, those applications are Visual Studio, Vim, Console and Firefox. The first three are easy to set up, and that's why most of my VS settings files include large font sizes for all the key elements (the editor and tool windows).

Tip: If you like/need large fonts in VS, increasing the font size of your tooltips can also make a big difference. This is something I used to do but always forgot to change and make sure my theme files included this setting. The screenshot above uses 11pt Tahoma for the tooltips.

Firefox is a bit harder to set up right, because changing the default fonts used can break a bunch of sites. Fortunately most of the web sites I visit regularly are very friendly to the use of Ctrl-+ to increase the font size.

The downside of using large fonts

There's obviously a downside of using large fonts when programming: You can fit less lines on a screen. Usually, the increased width of text doesn't matter much, particularly on a screen with wide format because there's so much horizontal space. Vertical space, however, is a different matter because it means you can display a lot less lines at at time.

For example, on a full screen VS session using Envy Code R, I can view 55 lines at a time at size 10pt, but only 40 at 15pt. That's 27% less lines!

It's not that I write methods with hundreds of lines, mind you. It's just that even if all your methods are short, sometimes you do have to deal with longer code files. It might be that you have classes with a lot of short methods, or maybe you're dealing with legacy code that's not so nicely factored.

Having a large screen with smallish fonts can make it a lot easier to work on these kinds of scenarios, because navigating and making certain changes/refactorings is a lot easier (even with automated tools for that). For example, one scenario were I really wish I had a larger screen is when dealing with source files that have several shorter classes defined in it (not all people are fans of the "one class per source file" convention).

The solution, of course, is to get a larger screen. For this reason, one of my goals for this year is to get a new desktop machine (after several years desktop-less) with a decent, large LCD. I'm aiming for a 24" display so that I can keep using the 1920x1200 resolution. The downside, of course, is that they are pretty expensive around here, so I still need to save some money before I can afford one alongside with a decent desktop machine.

[1] If you were also surprised about the "15pt Courier New" font; look closely and make sure you install the right font, or replace by your favorite :-)

DLR Notes 4

Link. February 13, 2008. Comments [0]. Posted in: .NET | DLR

I thought I'd use a few posts to talk a bit about some interesting ways that IronRuby does things. To do this effectively, we need to have a way to look at the code that IronRuby generates, as just browsing the code isn't going to do much good if you don't know where to start!

Fortunately, the DLR has our backs covered! As I've mentioned in the past, the DLR allows as to see the ASTs used for code generation as well as the Rules used to execute actions, and this is an invaluable tool both to debug our own language implementations, as well as to see what other implementations are doing.

Looking at both ASTs and Rules is easy if you're using the DLR Console either to execute a script in a file or in REPL mode, using the /X:ShowASTs and /X:ShowRules switches, like this:

.\rbx /X:ShowASTs test.rb

Creating .NET Objects

One of the strengths of IronRuby is that it allows us to work against not only all the Ruby goodness, but also access a lot of the functionality already available in the .NET Framework [1].

For example, I could create an instance of System.Text.UTF8Encoding like this:

x = System::Text::UTF8Encoding.new(false)

So what happens when we do this? The current implementation of IronRuby will generate an AST that looks like this:

.return (.bound x) = (Object).action (Object) InvokeMember new(
    (RubyOps.GetConstantExplicit)(
        (RubyOps.GetConstantExplicit)(
            (RubyOps.GetGlobalConstant)(
                .context,
                (SymbolId)System,
            ),
            .context,
            (SymbolId)Text,
        ),
        .context,
        (SymbolId)UTF8Encoding,
    )
    (Boolean)False
);

There are several interesting things about this tree. As you can see, the qualified class name is translated to an object through a series of calls to methods in the RubyOps class. The first two calls return RubyModule objects corresponding to the "System" and "System::Text" namespace, while the last one returns a RubyClass object representing the type for the UTF8Encoding class. Then an InvokeMember action is built to call the "new" method in this RubyClass object, which will return the new instance of the UTF8Encoding class.

However, if you go and look at the code for the RubyClass and RubyModule classes, you won't find a "new" method anywhere. What gives?

The trick is, of course, in the IDynamicObject implementation of RubyClass/RubyModule, which receives the InvokeMember action and generates the right set of rules for this case. The method doesn't need to exists, as long as we can resolve the call and build a StandardRule whose target involves the right action/call being executed at runtime. In our simple example, this should mean creating a new instance of UTF8Encoding, which we can see

//
// AST Rule.Test
//

((((.bound $arg0) == (RubyClass)Ruby.Builtins.RubyClass) && ((RubyClass)Ruby.Builtins.RubyClass.Version ==
15111)) && (Boolean)True)
//
// AST Rule.Target
//

.return .comma {
    (.bound val) = .new UTF8Encoding(
        (.bound $arg1),
    )
    (.bound val)
}

The process through which IronRuby builds new instances (or rather, derives the right set of rules for a new expression) is actually fairly complex; even for this simple case. However, in the end, you can think of this process in a simplified way:

  1. The GetRule() implementation resolves the "new" method call in the RubyClass object by based on a fairly complicated set of lookups around the underlying .NET type and its superclasses and their corresponding RubyClass objects. What matters to us is that, at some point, IronRuby realizes that it really means "create a new instance",
  2. RubyClass.SetRuleForCreateInstance() is invoked, which will configure the rule correctly for this case.
  3. Within this, IronRuby notes that UTF8Encoding isn't a class defined in Ruby, but actually a CLR type.
  4. The set of candidate constructors of the CLR type is evaluated to find the right constructor to use.
  5. A New Expression (Tree.Ast.New()) is provided as the target of the rule.

So this is how our original InvokeMember action is converted into a new expression! Actually, this is a pretty simple case as far as IronRuby goes, because UTF8Encoding doesn't something corresponding in the Ruby language. To see a different scenario try creating an ArrayList (or other object that implements IList) and you will see a lot more interesting things going on to make the object and its class act ruby-like.

What about my language?

Does this mean you have to do it the same way when implementing your own language on the DLR? Certainly not. There are many ways you can choose to implement it and the DLR actually provides a few ways for that.

For example, in this particular scenario IronRuby is relying on an InvokeMember action, but the DLR also has a Create action which provides another way to represent your object construction. You still need to provide a callable object (IDynamicObject) to provide the rule, but it might not necessarily be very complicated once you resolve the typename to a CLR type.

Of course, the trick is finding out the right constructor to invoke for a given expression, and fortunately, the DLR provides some help to do this with the MethodBinder class. Here's a pretty minimal (not particularly efficient) implementation  you could start with:

private void SetCreateRule(StandardRule rule, ActionBinder binder, CodeContext context, object[] args) {
   rule.AddTest(
      Tree.Ast.Equal(rule.Parameters[0], Tree.Ast.Constant(this))
      );

   Type[] argTypes = new Type[args.Length-1];
   for ( int i=0; i < argTypes.Length; i++ ) {
      argTypes[i] = CompilerHelpers.GetType(args[i+1]); 
   }

   ConstructorInfo[] all = ClrType.GetConstructors();
   MethodBinder methodBinder = MethodBinder.MakeBinder(binder, ".ctor", all);
   BindingTarget target = methodBinder.MakeBindingTarget(CallType.None, argTypes);
   if ( target.Success ) {
      Tree.Expression[] actualArgs = ArrayUtils.RemoveFirst(rule.Parameters);

      rule.Target = rule.MakeReturn(
         binder,
         target.MakeExpression(rule, actualArgs)
      );
   } else {
      rule.Target = rule.MakeError(
         Tree.Ast.Call(
            GetType().GetMethod("InvalidArgs")
         )
      );
   }
}

[1] The examples in this post assume you're 'require'-ing mscorlib.dll.

BizTalk Send Adapters and Failures

Link. February 12, 2008. Comments [0]. Posted in: BizTalk

I've spent part of the weekend playing with some code for a BizTalk 2006 Send adapter, and while looking at the failure handling code, remember something that always struck me a bit odd about the model.

BizTalk supports a several different ways of implementing a send adapter, depending on the complexity of the adapter and the capabilities it provides. An adapter can made to handle a single message at a time (but with likely multiple messages in parallel), or handle batches of messages. An adapter can also handle messages synchronously or asynchronously.

Synchronous adapters are not really very desirable in general terms, unless the adapter itself doesn't do much work (like my Null Send Adapter, which does no work at all!). The reason for this is that a synchronous adapter will do its message processing directly in the thread provided by the BizTalk Messaging engine, thus blocking the thread temporarily and getting in the way of the Messaging Engine itself. Since the messaging engine threads are usually CPU bound, and the primary function of an adapter is to do I/O, this isn't a very desirable scenario.

However, there's something interesting about how the messaging engine accommodates synchronous adapters. When BizTalk wants to send a message through an adapter, it will call the adapter's IBTTransmitter.TransmitMessage() implementation [1].

TransmitMessage() has a boolean return value. If the adapter returns true, it means that this was a synchronous send operation, and the message has been sent successfully. If an exception is raised, then the send operation will be failed. In either case, the messaging engine will do the right thing and process the message accordingly. If the adapter returns false, however, it means that the adapter will handle the message asynchronously and it's responsible for telling the messaging engine what [eventually] happened with the message.

In practice, the last part is a lot harder than it sounds. Basically, a synchronous adapter is pretty worry free: It simply needs to return true or throw an exception, and the messaging engine does all the hard work. However, an asynchronous adapter has to do all the hard work itself, which includes:

  • Deleting the message from the message box when it has been successfully sent.
  • Submitting messages for retries according to their retry counts and retry intervals as configured in the send port configuration.
  • Moving messages to the secondary transport configured in the send location if the retries have been exhausted.
  • Suspending messages that could not otherwise be sent.
  • All of this needs to be retried until the messaging engine acknowledges the operation successfully!

As you can see it's a lot of responsibilities for the adapter developer; particularly the last part. See, if you tell the engine to delete a message, it might tell you that it couldn't do it (maybe there was contention on the message box); it's your responsibility to keep trying until it succeeds. Same story for all of the operations mentioned above. Getting all this right can be a bit tricky, as you can imagine (though the adapter framework in the SDK can help a bit here).

Is this unnecessary? Not at all; it is quite required particularly for batched and transaction aware adapters, and it actually is quite flexible. It also allows adapters with special needs to make decisions about what the right action might be. For example, maybe your adapter must suspend a message without trying the secondary transport (ordered delivery requirements, maybe).

The downside of this is that, if you were not interested in creating a batched adapter (or couldn't!), but did want to make it relatively efficient by not doing your work on the messaging engine threads, it's a whole lot of complexity you have to deal with. You can't simply tell the messaging engine "I'm done with this message" and have the right things happen anymore; instead you need to actually handle batches (containing a single message, but batches nonetheless) and implement the required semantics all on your own.

Simple synchronous adapters are still useful though. It's an easy way to get started with your send adapter, verify that your core adapter logic works, and then move on to support asynchronous processing and batches, if you can support those.

[1] If the adapter supports batching, it will implement IBTBatchTransmitter instead of IBTTransmitter and the workflow will be different, but let's forget about that for now.

Windows Server 2008 on MSDN

Link. February 11, 2008. Comments [0]. Posted in: Development

I had seen the RTM announcement but no mention on when it might be in MSDN. Took a look yesterday, and it was already available, cool :-). At least the Datacenter/Enterprise/Standard DVD for x86 and x64, Itanium (those are still around?) and Web Server seem to be available.

I'll need to spend some time installing it on a VM to take a good look.

PowerShell Editors and Other Not-So-Fascinating Stuff

Link. February 8, 2008. Comments [4]. Posted in: PowerShell | Tools

Scott Hanselman just mentioned using the PowerShellPlus editor as an IDE for PowerShell. You can always trust good old Scott to point out cool new tools!

Anyway, I was already aware of PowerShell+ (and its closely related product, PowerShell Analyzer), and I find the idea appealing in general and a it's probably a very useful tool to have around. That said, I don't have plans to install PowerShell+ anytime, for a few reasons:

  1. I've had little need of such a tool until now. Granted, if I need to create a lot more complex scripts than what I've been doing until now, then having a something like the PowerShell+ debugger would sure be useful.
  2. From the screenshots, at least, it looks like a fairly busy UI, a mix of a console, office and Visual Studio strung together. I understand the technical reason for having the dual UI mode (console + editor), but it seems like forcing such disconnected experience between the two modes to be disconcerting as a user.
  3. It's currently in beta (at least that's what the web site says).
  4. Right now the site mentions it is "free for non-commercial use"; didn't find any obvious references to what the cost of a full version will be. I don't object to such deals (indeed, it's a good way to promote your products to enthusiasts), but I'm not quite sure I see how it can apply all that easily to a tool like PowerShell. What exactly constitutes a non-commercial use of an editor for a scripting language [aimed at systems administration]?

Related to (2), I've fallen back into working under more minimalist environments since a few months ago. I found that it helps a lot my concentration and productivity and leads to far better use of my screen real state.

Does this mean I dislike IDEs and other complex environments? not at all; it just means I don't want my editor to flaunt all its features in my face all the time demanding my attention. Like John Lam, I run my Visual Studio in an almost clean environment: All tools windows set in auto-hide, and almost no toolbars visible (unlike John I do keep one toolbar around, but not the standard one). I  works great for me.

For PowerShell, I'm pretty happy using Vim + Console; seems to do the trick, and actually has forced me to learn more about PowerShell than I had done previously. One of the things I love about PowerShell was that it includes commands for exploring itself right for the beginning (i.e. alias, get-command, get-help and so on).

PowerShell V2

While on the subject of PowerShell, I've been reading a bit about the features coming in PowerShell V2, and there are some pretty cool things there.

The "Graphical PowerShell" tool looks cool and I'm sure it will be very useful to a lot of people, but personally, I wish this would become a separate download and not part of the core PowerShell installation (might as well wish I would win the lottery; that probably has better changes of happening).

On a related note, out-gridview gives the the shivers.

Side Note: Is it just me that finds it ironic that PowerShell V2 brings several UI-related features when the big thing about V1 was creating a fantastic shell scripting language? Just food for thought.

(And yes, I'm aware of PowerShell's hosting API, and it's great. In fact, I've used it to embed PowerShell capabilities into three different projects, so I'm pretty well aware of how sweet it is.)

Formatting Source Code For Blog Posts

Link. February 7, 2008. Comments [4]. Posted in: Blogging | Tools

I've struggled quite a bit over the past few months trying to come up with a good way of including code snippets in my blog posts. The problem, of course, is making the code look good both when browsing the website as well as in the RSS feed. It's not the first time I've ran into this issue, either.

As I've mentioned in the past, one of the things making it hard is my blog engine, as the dasBlog build I'm currently running doesn't properly respect whitespace in the original HTML code. Because of this, posting code is a big pain in the neck, as you need to format the code in HTML manually since using good old <pre><code></code></pre> tags will render the code unreadable in the RSS feed.

Beyond just having the spacing and indentation right, there's also the matter of posting syntax highlighting. There are several options I've tried over the years:

  • CopySourceAsHtml: This is an OK tool, though I've had to build a custom build to make it work on my machine (which has some weird clipboard issues at times; not sure why). I'm not 100% satisfied with it, though. For one thing, it generates pretty ugly HTML. It's also not very useful for posting code in a language not supported by Visual Studio itself, which I occasionally do (example: PowerShell snippets).
  • CodeHTMLer: An online site for converting code snippets to HTML, supporting a bit more languages than CopySourceAsHtml. I've used this one extensively, and it usually does a good job, provided I explicitly check the "convert whitespace" option as well as "Inline Tags" for formatting. You don't get much choice in how the code is formatted, though. I believe there's a Windows Live Writer plugin based on this somewhere, but I always forget where so it's more convenient for me to just use the web application.
  • Syntaxhighlighter: A Javascript Library for formatting code snippets. Looks nifty, but only usable on the website and not RSS feeds, I think. It also seems to rely heavily
  • Iris: This is an interesting project, based on the VIM syntax highlighting. It actually does a pretty good job, though I haven't tried using it yet directly on my blog. The Ajax interface is slick, though there's also a version you can download to use on your own desktop. It only seems to support using CSS for the syntax highlighting, though.
  • TOhtml: I've also been experimenting lately with using Vim's :TOhtml command. This can actually provide very nice HTML if you set up the right options, and given the breath of syntaxes supported by Vim, you can pretty much use it to pretty print almost any code snippet you can think of.
    Another nicety of TOhtml is that it will use the colors in your selected Vim colorcheme, so the generated HTML looks exactly like it does in Vim. It can also generate the formatting using CSS or inline tags.
    As a sample, this is what I used in my last PowerShell post, with the options html_use_css, html_no_pre and use_xhtml. The color scheme I was was using was the black variant of the recently updated moria scheme, aided by Peter Provost's excellent PowerShell syntax files.

I'm sure there are many other options out there. I know there are some very nice plugins for other blogging platforms (like wordpress, from what I've been reading), but for obvious reasons that's not very useful.

Another issue that can be a bit bothersome with code formatting is the choice between using CSS rules or using inline tags.

In an ideal world, using CSS rules would be much more preferred, particularly if you can keep them in an external CSS file. One obvious benefit of this is that if you later decide to change your formatting preferences, your color scheme, or simply change your blog's layout and colors and want your code to match them, it becomes a whole lot easier (though this isn't all that possible for someone like me with 6 years of past blog posts with all kinds of code formatting used).

The downside of using CSS is that it's pretty much a website-only option, so it's not very useful for formatting code in your RSS feed. At least, my experience has been that most RSS generators and/or consumers will strip any inline CSS rules found in blog posts (this was, in fact, what happened to my last PowerShell post mentioned above).

I know of no way to easily reference an external CSS for this, but if anyone knows of a way, I'd sure appreciate knowing about it!

So that pretty much leaves, for now, the only option of not using <pre> tags and resorting to inline tags. Yuck! So, what's the secret sauce others are using for this?

DLR Notes 3

Link. February 7, 2008. Comments [0]. Posted in: .NET | DLR

Last time I talked a bit about Call Actions; now let's talk a bit about another kind of action: InvokeMember actions. As their name implies, these are useful for calling instance methods on .NET objects.

I struggled a bit with InvokeMember actions because they are act a little differently than Call actions. In particular, I was confused why sometimes InvokeMember actions seemed to require an extra expression in the argument list to work, when compared to Call actions. Fortunately, Dino Viehland clarified the reason for this, though it took me a lot of trial and error for his explanation to finally "click". I'll explain this in a moment.

To create a new InvokeMember action, you need the name of the method to invoke, the result type (like with a Call action, typeof(object) might suffice), the CallSignature and a list of expressions to use an arguments.

The CallSignature structure is interesting, because it can be used to provide information about how to interpret the call arguments. For example, it can be used to point out if an argument is the instance expression, if it's a named argument and so on (check the ArgumentKind enumeration for all the options). Filling in the CallSignature correctly is key to getting the correct behavior.

Here's what initially confused me about how InvokeMember works. Consider two different scenarios of how an InvokeMember action can be used to call a regular instance method:

  1. You create a simple CallSignature that does not have an argument with ArgumentKind.Instance. In this case, building an InvokeMember action is very similar to building a Call action: first the "target" expression (which evaluates to the object on which to invoke the method), followed by the expressions representing the actual arguments to the call.
  2. You build a CallSignature with an explicit Instance argument (usually the first one). Now, the call arguments need to be a bit more complex, defined as:
    1. The callable object (an expression evaluating to it, actually).
    2. The target expression evaluating to the object on which to invoke the method.
    3. Zero or more expressions representing the actual arguments to the method.

The reason this can be confusing is because this "Callable object" should not appear in the CallSignature you create to build the InvokeMember action: It really is a "hidden" parameter, so if you're calling a method requiring 3 arguments, you'd create a CallSignature listing 4 arguments (instance + actual args) but provide an expression array containing 5 expressions as the arguments to Ast.Action.InvokeMember().

But what is this Callable object? If you are thinking that it must be similar to what I called "Callable Object" when using Call Actions, you'd be right. Basically, the callable object argument can be used to provide a helper object that can help either make the actual call at runtime or, if it implements IDynamicObject, build the rule used by the DLR to invoke the actual method. [1]

Notice however, that unlike our sample last time, your GetRule<T> implementation will need to create a rule for DynamicActionKind.InvokeMember instead. One thing that is confusing is that you can use scenario (2) above but simply provide the target object as the first expression (that is, pass it twice), then the call will work as well directly, matching the behavior of scenario (1) [2].

In either way, the ability to use a Callable Object provides an easy way to hook the member invocation process to tweak how the call is made, which is a very useful capability in a dynamic language.

For example, IronRuby implements IDynamicObject in its built-in module and class objects (RubyModule and RubyClass, respectively) and are used to resolve method calls to ruby objects; you can look at how the default rule for InvokeMember actions is created inside MakeRuleForInvokeMember() method of the RubyBinder class. If I understand the code correctly, IronRuby takes advantage of this capability to implement method_missing. You can also check how calls to real .NET methods/properties are resolved to the original methods in RubyClass.TryGetClrMember().

[1] By now you can realize this pattern applies to all types of actions, not just Call and InvokeMember.
[2] In this case, a default rule is provided by the ActionBinder.MakeRule<T>() method, which you can also override and customize in your language binder implementation.

Naming Your Computers

Link. February 6, 2008. Comments [3]. Posted in: Personal

There's a thread going on at reddit regarding an old FYI RFC about computer naming conventions. This made me think a bit about how I name my machines, and realize I don't really have a convention at all. Or, rather, I've had several over the years ranging from places/characters from books (from the traditional Lord of the Rings lore to science fiction) to famous scientists.

The machines I'm currently using are named like this:

  • My main Windows laptop is currently named arcano.
  • My other laptop running ubuntu is named isengard.
  • My main development virtual machine, running WinServer2k3, is named newton (after Sir Isaac Newton, of course).

Some other names I've used previously include kepler (in honor of Johannes Kepler), caladan (from Frank Herbert's dune), copernico (the Spanish spelling for Nicolaus Copernicus), radiant, arrakis (again, a dune reference), lothlorien, and colossus (a reference to the computer, not the comic superhero). There are probably plenty others I've forgotten over the years :-).

Another common choice seems to be using letters from the Greek alphabet. That was the convention at my college. I still remember our first account used to be in delta, which turned out to be an old Sun workstation hosting email, web and shell access to the CS department (and later decomissioned).

What do you name your computers?

Have Script, Will Backup

Link. February 6, 2008. Comments [2]. Posted in: PowerShell | Tools

A few days ago, I mentioned I did simple backups using the SyncToy powertool, and mentioned I might try replacing it with Robocopy. The end result is a simple PowerShell script that drives Robocopy. It simply backs up a specific set of directories and my VPC data virtual hard drive (.vhd) into a new folder with the current date, and leaves a log of the entire process.

The script also makes it easy to specify for each folder a set of file extensions to ignore. For example, I don't want to include object files when backing up my source code trees.

Anyway, it's not fancy, but it does the trick. Here's the script:

function script:filename([string] $path) {
   return [System.IO.Path]::GetFileName($path)
}
function stars {
   return (new-object string ('*', 80))
}

$BASE = 'g:\backups'
$today = [datetime]::Today.ToString("yyyyMMdd");

$dest = "$BASE\$today"
$log = "$dest\log.txt"

if ( -not (test-path $dest) ) {
   mkdir $dest
}

#
# write header
#
write (stars) >> $log
write "Backup procedure starting at " `
      ([datetime]::Now.ToString()) >> $log
write (stars) "`r`n`r`n" >> $log

#
# stop CVS services
#
net stop cvsnt >> $log
net stop cvslock >> $log

#
# backup our set of folders
#
$folders = (
   ('e:\CVS', ''),
   ('e:\devdeo', ''),
   ('e:\home', '*.swp'),
   ('e:\projects', '*.swp *.obj *.exe *.dll *.pdb *.pch *.idb'),
   ('e:\opensource', '*.swp *.obj *.exe *.dll *.pdb *.pch *.idb'),
   ('e:\tools', '')
)

$folders | %{
   $name = filename($_[0])
   $excludes = $_[1].Split(' ')
   robocopy $_ "$dest\$name" *.* /E /ZB /NP /XF $excludes >> $log
}

#
# backup our VPC data file
#
robocopy 'E:\vpc\' $dest 'datos.vhd' /NP >> $log

#
# restart CVS services
#
net start cvsnt >> $log
net start cvslock >> $log

#
# write footer
#
write "`r`n`r`n" (stars) >> $log
write "Backup procedure finished at " `
      ([datetime]::Now.ToString()) >> $log
write (stars) >> $log

write "Backup done. Check log file for details."
write $log

Here's the source as well.

DLR Notes 2

Link. February 5, 2008. Comments [0]. Posted in: .NET | DLR

This time I'm going to talk a bit as to how to implement function calls in the Dynamic Language Runtime. Last time, I mentioned that I had initially had implemented function definitions as simply returning a raw CodeBlockExpression. This works, but it doesn't give you many options to add custom language-specific behaviors.

A more useful approach in many cases is to wrap your function into an actual object, at runtime, which can then be used for different purposes (including actually invoking the function). So instead of simply moving the CodeBlockExpression around you create a subtree that creates a new object with the CodeBlockExpression as an argument (among other things) and return that instead (with possibly other actions around it, like putting it into a variable).

This is how both IronRuby and ToyScript do it (and I imagine, IronPython). If you look at ToyScript's Def class (the language-specific AST node for a function definition), you will this in action:

Ast.Assign(
  tg.GetOrMakeLocal(_name),
  Ast.Call(
      typeof(ToyFunction).GetMethod("Create"),
      Ast.Constant(_name),
      Ast.NewArray(typeof(string[]), names),
      Ast.CodeBlockExpression(block, false)
  )
)

As you can see, it will generate a Call expression to ToyFunction.Create(), which is a static method that returns an instance of the ToyFunction class. At runtime, ToyFunction.Create() will receive the name of the function, the names of the method parameters and a Delegate instance that can be used to actually invoke the code later on. That last part is the interesting bit.

So later on, you want to invoke your function. You already have a variable somewhere that evaluates to a Function object at runtime (in the case of ToyScript, a ToyFunction object as we mentioned). In more general terms, what you will have is an expression that will evaluate to the function object; it really could be anything (like another function call that returns another function). But how do you actually invoke it?

Turns out there are several ways you can implement this, with varying degrees of performance characteristics and needs.

Generating Calls

In the case of invoking a standalone (local or global) function you already defined in your language, the most obvious choice is to use a direct Call expression, via Ast.Call(). We already saw an example in the short snippet above, but for a different use.

Ast.Call() takes a System.Reflection.MethodInfo object (the method to execute) and a params array of expressions to use as arguments to the call (there are other overloads available). If the MethodInfo object points to a non-static method, then the first expression in the arguments list will be the instance [target] object on which to actually make the call.

This is pretty useful if you want to call methods you're aware of at compile/parse time, such as a built-in function like ToyFunction.Create() above, but it's not useful at all to do what we want: Invoking a CodeBlock we created somewhere else.

For this we need to turn to generating a Call action, using Ast.Action.Call():

public static ActionExpression Call(Type result, params Expression[] arguments);

The first parameter is the type of the return value of the call; which can be typeof(object) unless you have more advanced information about what the call will return. The second argument is the list of parameter values you want to pass to the function.

...So how do you tell Call() what to actually invoke?

Yep, that tripped me up as well. Turns out that a CallAction expression expects that the first expression in the arguments list evaluates to a callable object. At least that's how I think of it. But what's a callable object? As I understand it, it means that it references an object that either:

  1. Implements IDynamicObject, or
  2. Has a public instance method with the following signature:
    object Call(CodeContext context, params object[] arguments);

The current ToyScript incarnation follows path 2. Here's the implementation of the Call() method:

[SpecialName]
public object Call(CodeContext context, params object[] arguments) {
   ParameterInfo[] parameters = _target.Method.GetParameters();
   if (parameters.Length > arguments.Length) {
       if ((parameters.Length > 0 && parameters[0].ParameterType == typeof(CodeContext)) ||
           (_target.Target != null && _target.Method.IsStatic && parameters.Length > 1 && parameters[1].ParameterType == typeof(CodeContext))) {
           arguments = ArrayUtils.Insert<object>(context, arguments);
       }
   }
   return ReflectionUtils.InvokeDelegate(_target, arguments);
}

The code can look a bit convoluted, but it's actually quite simple: It simple checks the actual arguments supplied to the call to see if the CodeContext has already been included explicitly in it; otherwise it adds it as the first argument, and then uses ReflectionUtils.InvokeDelegate() to actually invoke the ToyScript function represented by this instance of ToyFunction (_target is a field containing our Delegate instance). It's easy, but I think it doesn't have the best performance.

IDynamicObject

A slightly more complex implementation would instead implement IDynamicObject. This what IronRuby's Proc class does, and it's what I currently have working on my own language implementation. The core of the IDynamicObject idea is that, unlike with the special Call() method above, our function object is no longer responsible for actually doing the call on the target function. Instead, we're merely responsible for providing the DLR with a rule it can use to invoke it. This is exactly what you do inside your GetRule<T>() implementation.

In our case, what we really want is to respond with a new rule for the Call dynamic action, which is the only one we're interested in it. My current (simplistic) implementation works like this:

public StandardRule<T> GetRule<T>(DynamicAction action, CodeContext context, object[] args) {
   switch ( action.Kind ) {
      case DynamicActionKind.Call:
         StandardRule<T> result = new StandardRule<T>();
         ActionBinder binder = LanguageContext.Binder;
         SetCallRule(result, binder, result.Parameters);
         return result;
      default:
         return null;
   }
}

private void SetCallRule(StandardRule result, ActionBinder binder, IList<Tree.Expression> args) {
   // args[0] == this
   result.AddTest(
      Tree.Ast.Equal(
         args[0],
         Tree.Ast.Constant(this)
      ));

   Tree.Expression[] expr = new Tree.Expression[args.Count-1];
   for ( int i = 0; i < expr.Length; i++ )
      expr[i] = args[i+1];
   result.Target = result.MakeReturn(binder, Tree.Ast.ComplexCallHelper(Target, expr));
}

As you can see, we create a new StandardRule but a very simple one:

  • The test part of the rule simply checks that the target object on which to invoke the call is the same as our instance. This is what tells the DLR if the call should or should not be made. Here's I'm simply doing an identity test, which seems to work fine in my unit tests. IronRuby, for example, instead uses a unique ID assigned to each Proc instance for the call test.
  • The second part will create a new array with the actual arguments to the call (i.e. without the first 'this' argument) and use that to build the call using Ast.ComplexCallHelper().

One we return the rule, the DLR can cache that information to make following calls more efficient, for example.

Something to watch out for here and that really confused me at first: If you read the above code carefully, you'll notice that the DLR Actually gives us an object[] to GetRule<T>(). This will contain the actual values of arguments to the call (not expressions that evaluate to them), so you can examine them to decide how to best to create your rule. Notice however that I don't actually use them. Instead I use the already existing expressions in StandardRule<T>.Parameters, which will be already populated with the expressions for your call arguments.

The reason for this is that, as it turns out, is that if you used the original values to build your own Expressions to create the test (and possibly parameters) for the call, you will run into an issue that can cause the DLR to go into an infinite recursion of nested DynamicSite.Invoke() calls. Not fun to debug, and looking at the rules or AST dumps won't tell you why it's failing. I think the relevant issue is mentioned in a comment in the DLR source code that reads "The test should be such that it does not become invalid immediately. Otherwise, ActionBinder.UpdateSiteAndExecute can potentially loop infinitely."

Anyway, once you realize how Ast.Action.Call() works and what it expects from you, it all starts making a lot more sense.

ActionBinders

It is also important to note that already in these simple scenarios your language's ActionBinder implementation starts to kick in. In particular, you need to ensure that it implements the required type conversions so that the DLR can make any conversions necessary between the actual argument values to a call and the types of the parameters as declared in the CodeBlock (through ActionBinder.ConvertExpression()).

Next time I'll talk a bit about InvokeMember actions.

DLR Notes 1

Link. February 4, 2008. Comments [1]. Posted in: .NET | DLR

One of the first things I tried to get working on my simple programming language was being able to define functions. Initially I started just with global functions, and then with local (i.e. nested) functions.

For the most part, this is easy in the DLR. You create a new function by creating a CodeBlock, which has a bunch of properties and methods such as the function name, the local variables it has, any parameters it takes and what the type of the return value is. It also has a Body, which is an Expression (normally a Block expression which contains a list of expressions). You create an empty CodeBlock using Ast.CodeBlock() and then you can fill in the rest using its properties.

Currently, a CodeBlock isn't directly part of the AST itself, that is, it isn't directly a node in the tree. Instead, you build a CodeBlockExpressions out of it (using Ast.CodeBlockExpression(), naturally) and use that as a reference to your function. In fact, at runtime, a CodeBlockExpression eventually becomes just that: a delegate instance.

My initial function implementation was extremely simplistic, meaning that functions weren't really handled using any language-specific object (like [Iron]Ruby's Proc or ToyScript's ToyFunction classes). Instead, I was directly storing CodeBlockExpressions in variables and using them instead. also didn't implementing function calls initially.

To test that my function definitions were working, I instead opted for simply returning the CodeBlockExpression directly. My tests (built using NUnit) make use of the ScriptEngine.Execute() method to parse and evaluate a script and return the result (my language has implicit returns, so all expressions evaluate to something). So what comes out when I evaluated a variable containing a CodeBlockExpression? Yep, a delegate, which I could call directly from the outside to validate it was working!

It's worth saying that the delegate you get directly from such a simple construct might have a bit of an unexpected syntax: The first parameter will always be of type CodeContext, after which the actual parameters you defined in the CodeBlock will appear (many times it's safe to simply pass null for this).

Variables

One of the things that I ran into while implementing this was getting variable definitions right. Creating and defining variables on the DLR isn't really hard:

  • Global variables are somewhat supported (though at least from some comments in the source this might go away. What's not very obvious is that global variables don't need to be "defined" anywhere; they are just names. You manipulate them using Ast.Read(), Ast.Write() and Ast.Assign(), using the variants that take a SymbolId as argument.
  • Local Variables are associated with a specific CodeBlock, so they actually do need to be defined, which is done using the CodeBlock.CreateLocalVariable() method.
  • Parameters are much like local variables, but you create them using CodeBlock.CreateParameter() instead.

Obviously, keeping track of variable definitions and their scope is your responsibility. For local and parameter variables, you need to keep track of the Variable objects returned by CreateLocalVariable()/CreateParameter(), since that's how you reference the variable when reading/writing to it using Ast.Read()/ReadDefined()/Write()/Assign() and friends.

If you somehow set up things incorrectly, then some debug asserts in the DLR might get triggered at runtime when you try to use the variables (surprisingly enough things still seemed to work after ignoring the asserts, but that was probably a fluke).

Building On The DLR

Link. February 4, 2008. Comments [1]. Posted in: .NET | DLR

I've been playing for some time now with the Dynamic Language Runtime. At first I started simply playing around with its hosting interfaces, but later I realized I really wanted to check more closely how it worked, so I started building a very simple language on top of it.

My intention isn't to build a full fledged language out of it, but simply use it to explore interesting aspects of the DLR. It's been a bit complex and frustrating at times because there really isn't much documentation yet [1] on how the DLR works (and how to build on it), but it's been a lot of fun, too!

Fortunately, there's plenty of source code to study when you're looking at the DLR. On the small scale, there's the DLR version of LOLCODE! as well as the ToyScript sample included with the DLR in the IronPython 2.0 alpha bits.

Much larger samples are obviously both the IronPython 2.0 and IronRuby source code, but they are complex enough that it can be difficult to understand how they are using the DLR sometimes (I'm starting to get a feel for how IronRuby does it, but that probably will only last until the next big changeset is merged into the SVN repository :-)).

Note: I don't know if the LOLCODE! sample has been recently updated, but the DLR has changed quite a bit since then, so it might require a few changes around to get it to build.

A most interesting source of current information on the DLR can be found in Martin Maly's blog, and it is definitely recommended if you're interested in targeting the DLR. It took me a bit to finally grok what he was talking about but after that it helped quite a bit!

Note: Do take everything I mention here with a large grain of salt. After all, I'm just a hobbyist playing with the DLR, not someone implementing a real language on it.

Targeting the DLR

There are several reasons why building an interpreter/compiler on top of the DLR makes sense, and obviously the most significant one is that it takes an awful lot of work of your hands. The DLR provides you with:

  • Most of the hosting infrastructure needed to build a script interpreter. It also provides you with a common API (the hosting API) you can use to use your language from different applications and uses.
  • An MSIL code generator: You hand it an Abstract Syntax Tree and it will take care of generating the necessary MSIL.
  • Dynamic behaviors: To a large degree, you can build a language on top of the DLR where you don't have to care about what the expressions you're manipulating evaluate to at runtime. This makes building a bunch of stuff fairly trivial for you, and actually makes it a lot easier to get up and running with something that works (for some definition of work).
  • Bunch of other stuff

Indeed, the DLR takes care of a lot of the grunt work off building a working compiler/interpreter.

So how do you actually target the DLR?

Turns out that getting started with the DLR isn't all that hard. First you need to get your hands on a copy of the DLR, which you can do either from the IronPython 2.0 alpha bits or from the IronRuby SVN repository. Personally, I've been going with the IronRuby bits since it's more convenient.

Then you need to write the code. There are a few things you need to get this up and running:

Connect: You need provide a way for the DLR to know about your language: How to parse it and how to generate code for it. In the current incarnation of the DLR [2] this is done by implementing a LanguageContext derived class.

You can start with a pretty simple implementation of this, which just creates the ActionBinder (more of this in a minute) and that implements the ParseSourceCode() method.

It may be that at some point in time you'll want to make your language known to the DLR so that you can use conveniences like the Script class to quickly parse/compile/evaluate scripts in your language. This can be easily done by using the RegisterLanguageContext() method of the ScriptDomainManager class.

Binding: You'll also need to implement an ActionBinder derived class and override the methods from it that are relevant to your language. As I understand it, the binder is responsible for making a bunch of language-specific decisions about how the DLR should generate code for your language, like for example which type conversions are supported (and how they should be implemented). Again, you can start with a pretty minimal binder class and then grow it as needed.

Generating Code: With this in place you can actually get to the good stuff. You're responsible for actually parsing scripts in you're language. Normally, you'd write your lexer and parser using whatever compiler writing tool you like (or by hand), and then use them to build an Abstract Syntax Tree that represents constructs in your language.

This means that you can build a high-level AST that's close to the concepts and semantics your language needs, but even then it doesn't need to be very complex to start with (and in some cases, it can be fairly thin). Then, you translate it to a DLR AST, which is basically a tree of nodes in the Microsoft.Scripting.Ast namespace.

There are tons of lower-level constructs in the core DLR AST, ranging from creating type and member definitions to operators and method calls. Most of what you actually deal with here are expressions (almost everything is, naturally, an expression), which you can create using the methods of the Ast class (yes, there's both an Ast namespace and an Ast class), like Ast.Call() or Ast.Assign().

This brings me back to the ParseSourceCode() method: What you return here is, in fact, a DLR tree of what should be executed, as a node of type CodeBlock (basically, a function). As long as you build the right AST, things should mostly work.

How I'm using the DLR

I started writing my simple language using the Garden Points Parser Generator (GPPG) as it's fairly simple to use and my syntax is also pretty simple. I haven't had much trouble with this yet (took me a bit to remember the lex/yacc-like syntax from my college days), but then again, my needs are simple.

Right now, I've used it to explore very specific parts of the DLR, mostly code blocks and method invocation [3], so naturally the functionality currently implemented is very limited:

  • I can define both named and un