Reminder: Atlanta Geek Dinner Tomorrow Night

Silverlight Logo

Just a reminder that I am holding a Geek Dinner in Atlanta on January 7th, 2009.  Please RSVP so we can reserve the right number of places.

5 Seasons Brewery

5600 Roswell Rd NE
Atlanta,GA 30342
USA
(404) 255-5911

What is all the fuss about how you can write DSLs in Lisp?

Silverlight Logo

Chris Sells and Craig Andera are trading blogs about what is and isn't a DSL.  Craig has issue with the following from Chris' blog:

Here’s what he says, abridged:

(when (and (< time 20:00)
                   (timing-is-right))
      (trade (make-shares 100 x)))

IMO, that's not a DSL -- that's just a set of function calls in an existing language.

Craig answered back (a section, possibly completely taken out of context):

A set of function calls in an existing language is generally preferable to a completely separate language. Particularly if it’s the language that you’re using to write the rest of your system.

While the concept of domain specific languages is different things to different people, I fundamentally think that the "Little Languages" (Jon Bentley, Little languages, Communications of the ACM, 29(8):711--21, August 1986.) philsophy applies. As far as I am concerned that means the languages should be simple enough to write by hand and clear enough that non-technical stakeholders can understand them. Why? Because for my money, a DSL is useful when it can help you ensure that the intent of a system is the same as the code that runs a system.  And you cannot be sure of intent unless someone can assert the rules are correct.

I am sure I am missing some of the point of DSLs and feel free to educate/flame me, but for me the gain of building a DSL (even a very simple one) is that it can be validated against requirements much easier than typical code. In fact, it should be editable by stakeholders as well (perhaps not all stakeholders, but some).

If your DSLs are all based on language semantics (e.g. internal versus external DSLs I think its referred to by Fowler) then it makes them only readable to developers.  Sounds like the use-case was for a rules-engine not a DSL

 

 

Atlanta Geek Dinner - January 7th, 2009

Silverlight Logo

I am holding a Geek Dinner in Atlanta on January 7th, 2009.  We will be meeting at 5 Seasons Brewing at 6:30pm.  Please RSVP so we can reserve the right number of places.

5 Seasons Brewery

5600 Roswell Rd NE
Atlanta,GA 30342
USA
(404) 255-5911

MSchema: An Example - Part 3

Silverlight Logo

In Part 1 of this series I showed you how to create database schema with MSchema. Then in Part 2 I showed you how to use MGraph to create data to store the in the database along side database schema. In this last part, I will show you how to use the M tools to put the schema and data in the database.  I use these tools to build my database during a build script.

The first thing we need to do is to compile the schema. You can do this with the m.exe tool that ships with the Oslo SDK. While many of the demo's I've seen have pushed the data into the Repository, I want to push it into a generalized database. (My site isn't ready to be build on top of Oslo since its going to be released quite soon so I am just using the MSchema stack to help me build the database). When we compile the schema we can tell the tool type of target we're going to aim for.  In our case we will target TSQL instead of the repository.  So the first call in my database build script is to build the schema like so:

m.exe students.m /p:image -t:TSQL10

This tells the m.exe compiler to build an image (in this case an .mx file) based on our schema (the students.m file). This stop only builds the database, we now want to push it  into the database. We do this with the mx.exe tool:

mx.exe /i:students.mx /db:Training /ig /f /verbose

This part of the script uses the compiled version of the schema (the student.mx file created by our last step and insert it into a database called Training.  We could specify a server and security credentials but since I am building it with the local database and integrated security, we didn't need to specify these.  The /ig tells the database to ignore missing dependencies and try to build the database from the schema from scratch.  The /f flag says force the schema (including deleting existing elements with the same name).  Now we have the schema in the database.  But what about the data we created? 

To insert the data, our studentsdata.m file doesn't know about the schema so we need to hint it to the compiler:

m.exe studentsdata.m /p:image -r:students.mx -nologo -t:TSQL10

This call looks the same as the first except we reference our compiled schema file with the -r flag. Like before this creates a compiled version of the data we're putting in the database.  So you probably have already guessed that we use the mx.exe tool to insert the data into the database:

mx /i:studentsdata.mx /db:Training /ig /f /verbose

This looks just like our schema database insertion, but we're going to use the compiled data file instead. Because we compiled it with the reference to the compiled schema file, the new .mx file has everything it needs to insert itself into the database as rows in the database.

Hopefully this series has helped you understand how the M languages and the tools can work together to manage schema creation for projects. There are a lot of other features that we haven't discussed (like versioning) that are supported but i'll leave that for another day.

Do you think you'll use MSchema on any upcoming project?

MSchema: An Example - Part 2

Silverlight Logo

If you have read Part 1 of this series, you have seen how to create types, collections and constraints using MSchema. Along with most database schemas, I find the need to create some amount of data to go along with those schemas. For my current project (our new web site), I wanted to have some small set of data that included some basic workshops and locations.

To create the data we can use the MGraph language. MGraph is related to MSchema but is a way of describing concrete instances of data. To create an instance:

module Training
{
  Workshop
  {
    {
      Name = "Silverlight Workshop",
      Description = "A three day workshop to teach Silverlight 2.",
      Length = 3,
      MaxAttendees = 16,
      DefaultPrice = 1800.00
    },
    {
      Name = "Advanced Silverlight",
      Description = "Two-day course teaching advanced Silverlight topics.",
      Length = 2,
      MaxAttendees = 16,
      DefaultPrice = 1200.00
    }
  }
}

The syntax looks similar to a mix between the C# object initialization syntax and JSON. The module matches the same module that the schema was defined in. Then it is the extent name (Workshop in this case) then an array of objects (notice the types defined inside curly braces). This can be used to generate insert statements. That's easy to do with actual insert statements, so why learn this format at all? 

Foreign keys are what make this fun. If we wanted to add an event (who has a reference to a Workshop) we would need to be able to tell the MGraph language how to make the reference. I innocently thought of this approach:

  Event
  {
    {
      WorkshopId = 1,
      EventDate =  2009-02-04     
    }
  }

I assumed that I could set the id's manually then use them...to my surprise MGraph handles that better that I guessed.  how so?  The creation of the instances can be named.  So if we change the workshop creation to use names like so:

  Workshop
  {
    SilverlightWorkshop {
      Name = "Silverlight Workshop",
      Description = "A three day workshop to teach Silverlight 3.",
      Length = 3,
      MaxAttendees = 16,
      DefaultPrice = 1800.00
    },
    AdvancedSilverlight {
      Name = "Advanced Silverlight",
      Description = "Two-day course teaching advanced Silverlight topics.",
      Length = 2,
      MaxAttendees = 16,
      DefaultPrice = 1200.00
    }
  }

Now that the workshops are named, we can define our events with the names:

  Event
  {
    {
      WorkshopId = Workshop.SilverlightWorkshop,
      EventDate =  2009-02-04     
    }
  }

Now when we create the event, we can use the workshop (notice the Workshop is prefixed) to say that the workshop for this event is the one we created above.  M takes care of the rest. 

In the next part, we will show the command-line tools you can use to store the schemas and data in the database.

MSchema: An Example - Part 1

Silverlight Logo

As most of you know, I run a small training company. We are in the midst of a re-write of our main website to allow for more cohesive registration and information about our classes. For this project, I am completely re-creating my database schema (as the old one was a bit 'off the cuff'). What a great opportunity to try out MSchema to build the new schema.

I am going to show you some features in three parts.  In this first part I will show you how to define some interesting data types in MSchema. In the second part I will show you how to define your static or test data in MGraph that can be inserted into the database along with your schema. Then finally in the third part I will show you how to use the command-line tools to build your schema from the M files.  Onto the first part!

I'll admit, I hate visual editors. In fact, in his PDC talk, it was as if Doug Purdy was talking to me when he said we have an emotional connection to our text editors. I have spent some time with emacs.NET IntelliPad and so far I am impressed. It is taking some getting used to but the extensibility is pretty impressive.

I like the way that MSchema forces me to create a type then push it into an extent (e.g. to make it a table). For example, I started with a Workshop type that defined a training topic:

module Training 
{
  type WorkshopDef
  {
    WorkshopId : Integer32 = AutoNumber();
    Name : Text#100;
    Description : Text?;
    Markup : Text?;
    Length : Integer32;
    MaxAttendees : Integer8;
    DefaultPrice : Decimal19;
  } where identity WorkshopId;
}

I start with a module which just creates something like a namespace for our types and extents.  This module will become the Schema in SQL Server for our tables and views. Next, I created a type with the fields I wanted.  You notice that I post-pended "Def" on the type. This is mostly just a convention I made up so that I could name the collections singular (we'll see more about that later when we see the generated schema). You can see the fields for my type and the constraints I am specifying (e.g. Text#100 is the same as saying Text where value.length <= 100). Like in C#, the question mark says that the field is nullable. Finally, I specify that the type has an identity using the field(s) that make up my primary key.

At this point all I have is a type, no tables or view or anything really. I need to extend this into a collection:

  Workshop : WorkshopDef*;

This extent simply says create some place to hold things that look like WorkshopDef and call it Workshop.  The asterisk at the end of WorkshopDef implies zero or more (like in regular expressions). This set of schema would yield a small amount of SQL:

create schema [Training];
go

create table [Training].[Workshop]
(
  [WorkshopId] int not null identity,
  [DefaultPrice] decimal(19,6) not null,
  [Description] nvarchar(max) null,
  [Length] int not null,
  [Markup] nvarchar(max) null,
  [MaxAttendees] int not null,
  [Name] nvarchar(100) not null,
  constraint [PK_Workshop] primary key clustered ([WorkshopId])
);
go

You can see the schema created closely matches our type definitions. That's the cool factor for me.  Let's do something more interesting. For each Workshop I have a list of Topics (and eventually sub-topics). These are bullet point items that show what is covered in a workshop. So I can add a new type like so:

type TopicDef
{
  TopicId : Integer32 = AutoNumber();
  WorkshopId : WorkshopDef;
  Name : Text#100;
} where identity TopicId;

Note that when I define that I want a WorkshopId to be a reference to another type, I specify it as the type I am referring to. This means in our extent for Topics we can create the foreign key like so:

Topic : TopicDef*
  where item.WorkshopId in Workshop;

This essentially says that we want topics, but be sure that WorkshopId are in the Workshop table (the foreign key). The next thing to show is the real power of constraints. If you saw the Doug Purdy talk you probably saw that you could create a constraint for simple data like so:

  type AttendeeDef
  {
    AttendeeId : Integer32 = AutoNumber();
    FirstName : Text#50;
    LastName : Text#50;
    MiddleName : (Text#50)?;
    DateRegistered : Date;
    HasCancelled : Logical = false;
    Phone : (Text#50)?;
    Email : (Text#100)?;
    TShirtSize : Integer32 where value <= 5;
  } where identity AttendeeId;

In the TShirtSize, notice how I am constraining the value to a range of numbers from zero to five. This may be a magic way of translating from small to 3x. The SQL actually works as it creates a check constraint:

create table [Training].[Attendee]
(
  [AttendeeId] int not null identity,
  [DateRegistered] date not null,
  [Email] nvarchar(100) null,
  [FirstName] nvarchar(50) not null,
  [HasCancelled] bit not null default 0,
  [LastName] nvarchar(50) not null,
  [MiddleName] nvarchar(50) null,
  [Phone] nvarchar(50) null,
  [TShirtSize] int not null,
  constraint [PK_Attendee] primary key clustered ([AttendeeId]),
  constraint [Check_Attendee] check ([Training].[Check_Attendee_Func](
    [AttendeeId], 
    [DateRegistered], 
    [Email], 
    [FirstName], 
    [HasCancelled], 
    [LastName], 
    [MiddleName], 
    [Phone], 
    [TShirtSize]) = 1));
go

The Check_Attendee_Func is a generated function to test for constraints (including the size of TShirtSize. But that is making TShirtSize a magic number.  I don't like magic numbers.  Let's create something like an enumeration instead:

  type TShirtSizeEnum
  {
    "Small",
    "Medium", 
    "Large",
    "X-Large",
    "2X",
    "3X"
  };

  type AttendeeDef
  {
    AttendeeId : Integer32 = AutoNumber();
    FirstName : Text#50;
    LastName : Text#50;
    MiddleName : (Text#50)?;
    DateRegistered : Date;
    HasCancelled : Logical = false;
    Phone : (Text#50)?;
    Email : (Text#100)?;
    TShirtSize : TShirtSizeEnum;
  } where identity AttendeeId;

The new TShirtSizeEnum type can be used to constrain the value of the TShirtSize field.  How do we do that?  We simply tell MSchema that we are going to store a TShirtSizeEnum in that field and it creates it in the generated SQL.

Caution when Eager Loading in the Entity Framework

Silverlight Logo

UPDATE: Roger Jennings correctly stated, I meant to say that Include is *not* a guarantee.

When I am using the Entity Framework for a project, I have gotten into the habit of using eager loading via the Include syntax. In case you're not familiar it, the Entity Framework has a different philosophy than other data layers (e.g. NHibernate). In the Entity Framework, relationships have to be manually loaded when they are lazy loaded (so developers never have network round-trips without explicitly knowing about it). Whether you agree or not with this philosophy, understanding how it works is helpful when you're working with the Entity Framework.

The Entity Framework supports eager loading of the data as well using the Include syntax.  For example:

var qry = from w in ctx.Workshops.Include("Topic")
          orderby w.Name
          select w;

By amending the source of the query with the Include method, you can eager load relationships.  The problem is that these are really hints to the Entity Framework to load the relationships, but not a guarantee.  Depending on the query, these Includes may be dropped. The two scenarios I see this most often are the grouping and subselects:

// Drops the Include
var qry = from e in ctx.Events
                       .Include("Workshop")
          where e.EventDate >= DateTime.Today
          group e by e.EventLocation.Region into r
          select r;

I ran into a good post on the forums on the subject:

In that post, Diego Vega says that Include only makes sense in the following scenarios:

  • Include only applies to items in the query results: objects that are projected at the outermost operation in the query, for instance, the last Select() operation (in your query, you tried to apply Include to a subquery)
  • The type of the results has to be an entity type (not the case in your query)
  • The query cannot contain operations that change the type of the result between Include and the outermost operation (i.e. a GroupBy() or a Select() operation that changes the result type)
  • The parameter taken by Include is a dot-delimited path of navigation properties that have to be navigable from an instance of the type returned at the outermost operation

To alleviate the problem in some scenarios, you can use the EFExtensions Include Extension method to add includes on the complete query like so:

using Microsoft.Data.Extensions;
// ...
var qry = from e in ctx.Events
          where e.EventDate >= DateTime.Today
          select e;

List results = qry.Include("Workshop").ToList();

You can find the EFExtensions at the MSDN Code site here:

Has this bitten you before?

When is a ASP.NET Project Not an MVC Project?

Silverlight Logo

I am working on a hybrid ASP.NET MVC and MVC Dynamic Data project. To work on it I started with the MVC Dynamic Data project assuming this would be a Dynamic Data Project and an MVC project. As Scott Hanselman recently posted, you can mix and match pretty easily so the code was working but I was missing an important piece of functionality in Visual Studio:

My project wasn't being showing these items (or other menu options specific to MVC apps). I suspected it was some magic in the project file so I opened it up in my favorite editor:

<Project ToolsVersion="3.5" 
         DefaultTargets="Build" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">
      Debug
    </Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30729</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{F7526D86-12B4-434F-8355-20592CFC4937}</ProjectGuid>
    <ProjectTypeGuids>
      {603c0e0b-db56-11dc-be95-000d561079b0};...
    </ProjectTypeGuids>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Foo.Web</RootNamespace>
    <AssemblyName>Foo.Web</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  </PropertyGroup>

The missing bit was a special ProjectTypeGuid: {603c0e0b-db56-11dc-be95-000d561079b0}. You need to add this to the existing ASP.NET project's ProjectTypeGuid list in the project file and magically the project item types appear.

HTH

Using Closures to Simplify Asynchronous Programming

Silverlight Logo

When I teach Silverlight, some of the students lament at the requirement to make all network requests in an asynchronous manner. While I explained my opinion on the manner back in March of this year, I didn't get into how to make this easier. Lambdas and closures are the key to simplifying that code in my opinion. 

Quick caveat!  This does not work in Visual Basic (yet). VB10 has announced support for closures and lambdas that do not return values (e.g. Sub() instead of Function()), if you are using Visual Basic, I can't help you make it easier until VB10 ships.

Let's take the example of making a call to a simple web service.  I will show you two examples to try and get my idea across.  First we have a simple web service that returns a list of Game objects based on a single criterion (the genre).  Calling this service is simply a matter creating the client, registering the event handler and calling the asynchronous method:

// Create the client
GamesClient client = new GamesClient();

// Register the handler
client.GetGamesCompleted += 
  new EventHandler<GetGamesCompletedEventArgs>(client_GetGamesCompleted);

// Start the operation
client.GetGamesAsync("Shooter");

In the event handler we can just check the errors and set the result to our UI:

void client_GetGamesCompleted(object sender, GetGamesCompletedEventArgs args)
{
  // Complete the operation
  if (args.Error == null && !args.Cancelled)
  {
    theList.ItemsSource = args.Result;
  }
}

This code is pretty simple but we can use a lambda to avoid littering our code with unnecessary methods:

// Create the Client
GamesClient client = new GamesClient();

// Handle the event with a Lambda
client.GetGamesCompleted += (source, args) =>
{
  if (args.Error == null && !args.Cancelled)
  {
    theList.ItemsSource = args.Result;
  }
};

// Execute the Service Call
client.GetGamesAsync("Shooter");

Using the lambda (=>) creates an inline anonymous method for handling of the event.  Since this will only be used by our client and the client is short-lived (see issues with anonymous methods and long-lived objects here), this works well to simplify the code. 

This code becomes more difficult if you have to pass it data as developers tend to move that data to instance level (e.g. class level) variables to share it with the resulting code.  In other places (like AsyncCallback objects), they allow you to pass in a payload of data.  But this ends up with pretty ugly code.  For example, lets use the HttpRequest style of this same code;

// Interface to the HttpWebRequest-style interface
Games request = new GamesClient() as Games;

// Make the request
request.BeginGetGames("Shooter",
                      new AsyncCallback(OnGetGamesComplete), 
                      request);

In this style of the request, you would use a AsyncCallback to specify a method to callback and then pass in some state (in this case the request we made so we can use it in the callback. This results in the callback having to do some casting to get our object back;

void OnGetGamesComplete(IAsyncResult result)
{
  // Cast the passed in state
  Games theRequest = (Games)result.AsyncState;

  // Get the games
  IEnumerable games = theRequest.EndGetGames(result);
}

This grabbing of the state always annoyed me, but I figured it was necessary.  Or is it.  In this case our use of a lambda allows us to use a feature called closures.  With closures you can see local variables declared outside the anonymous method inside the method. For example:

// Interface to the HttpWebRequest-style interface
Games request = new GamesClient() as Games;

// Make the request
request.BeginGetGames("Shooter",
  new AsyncCallback(
    (result) =>
      {
        // Get the results
        IEnumerable<Game> games = request.EndGetGames(result);
      }
    ), null);

In this example we can use the request object create outside the anonymous method because the closure allows this.  This really simplifies the code. In fact, since the HttpRequest style is called on a non-UI thread, we can nest the lambdas and closures to call to the UI thread (using the Dispatcher, see my post on that here):

// Interface to the HttpWebRequest-style interface
Games request = new GamesClient() as Games;

// Make the request
request.BeginGetGames("Shooter",
  new AsyncCallback(
    (result) =>
      {
        // Get the results
        IEnumerable<Game> games = request.EndGetGames(result);

        // Use another Lambda and closure to update the list on the UI thread!
        Dispatcher.BeginInvoke( 
          () =>
            {
              theList.ItemsSource = games.ToList();
            }
          );
      }
    ), null);

Hopefully, this will help you in using the asynchronous model that is required in Silverlight 2. Note that this is the same as it is for non-Silverlight projects, but I find it really useful for students that have not had the opportunity to do asynchronous communication in their desktop applications.

You can download the code and play with it yourself.  Each of these methods are show in the project's page.xaml.cs file (see the #defines at the top of the file to switch between different versions):

AsynchronousClosures.zip

Silverlight Tour Now includes Coverage of the Silverlight Toolkit

Silverlight Logo

We are proud to announce that starting with our January 5th class, the Silverlight Tour will now cover the Silverlight Toolkit. This coverage will include examples of using the "Stable" band controls as well as charting and theme support.

This is the last big change to the Silverlight Tour before we start teaching our new Silverlight 3 when it is announced. Keep an eye here for news about changes coming in the next version of Silverlight!

The Silverlight Tour is a three-day workshop covering the basics of design and development on the Silverlight platform including XAML, managed code, control development, data access and server interactions.

More Rants