Luke Hoban's Blog

  • LukeH's WebLog

    The C# Compiler in Orcas


    I started working on the C# compiler team a little more than a year ago, right around the time that we started development on the Orcas C# compiler.  It's been a great project to work on, and it's good to see folks starting to use the new compiler in the recently released March CTP.  I thought it might be interesting to share some of the background on how we approached the scheduling aspects of the development of the compiler.

    We had the great benefit of starting Orcas with a prototype C#3.0 compiler already built and released as part of the LINQ CTPs.  This had allowed us to get great in-depth feedback on the language features early, and has enabled a large community of developers to work with LINQ over the last year and a half.  Although this prototype compiler was great for many projects, there were a number of significant known limitations, which were a result of fundamental implementation decisions, and so the senior developers on the team decided that we would need to implement the C#3.0 language features more-or-less from the ground up to get to a ship-quality implementation.  This process also helped us to clarify the design for many of the features, and to make changes or improvements to the design where necessary.

    Here's a quick summary of how we scheduled our work to build the C#3.0 compiler for Orcas. 

    Milestone 1

    Our first goal was to get the most fundamental new language features implemented, so we could begin building LINQ applications with the Orcas compiler as early as possible.  Many of the features in this first set were also chosen because they were pre-requisites for implementing some of the later language features.  For example, lambdas were important to get in early, because the conversion of lambdas to expression trees depended on this.  Here's what we built first:  

    • Local Variable Type Inference (var)
    • Lambdas
    • Object Initializers
    • Extension Methods (usage)

    Milestone 2

    For our second milestone, our goal was to replace the C#3.0 prototype compiler that we had shipped with the May 2006 CTP.  When we finished this milestone, we actually moved all of the teams internally who were using C#3.0 over to use the Orcas C# compiler.  This required implementing:

    • Lambdas bound to Expression Trees
    • Extension Methods (definition)
    • Collection Initializers
    • Anonymous Types
    • Query Expressions

    Milestone 3

    The third milestone was shorter, and our goal for this milestone was to get to a good state for the first Beta.  The results of this milestone are what you'll see in the Orcas February/March CTP and the first Orcas Beta.  We also implemented one of the most requested language features in the history of C# - auto-implemented properties!

    • Auto-Implemented Properties
    • Enhancements to Collection Initializers
    • Non-language features, such as debuggability improvements

    Milestone 4

    We're now working on the last feature milestone for Orcas.  We're finishing off with one more language feature and a lot of work to improve compiler fundamentals, such as error messages and performance.  Note that this work won't make it into the first Beta:

    • Partial Methods
    • Compiler Error Message Improvements
    • Compiler Performance
    • Compiler Generated IL Performance
  • LukeH's WebLog

    Using LINQ to solve puzzles


    A couple months ago, I had a great time participating in Microsoft's PuzzleHunt event along with our team "Cup<T>".  Normally, the puzzles in puzzle hunt are designed to limit the value of writing programs to help solve them.  But this year, I did end up writing some code to help with one of the puzzles - and it happened to be a simple LINQ query that helped.  Since this is an example of using LINQ in a problem domain that's pretty different than the usual querying examples, I thought it might be worth sharing.

    The Puzzle

    Here's a puzzle similar to the one in the puzzle hunt.  The diagram below is a bunch of weights (A-M) hanging from a system of bars.  Each weight has an integer value between 1 and 13, and the goal is to figure out what each weight must be for the the diagram below to balance correctly as shown: 

                  |                    |
                  |                    |
               +--+--+--+--+--+        |
               |     L        M        |
               |                       |
      +--+--+--+--+--+--+     +--+--+--+--+--+
      H              |  I     |  J        K  |
                     |        |              |
            +--+--+--+--+--+  |     +--+--+--+--+--+
            E              F  |     G              |
                              |                    |
                  +--+--+--+--+--+  +--+--+--+--+--+--+
                  A              B  C                 D

    The rules for this kind of puzzle are: (1) The weights on either side of a given pivot point must be equal, when weighted by the distance from the pivot, and (2) a bar hanging beneath another contributes it's total weight as through it were a single weight.  For instance, the bar on the bottom right must have 5*C=D, and the one above it must have 3*G=2*(C+D).

    A First Solution

    Here's what I tried first.  Note that it's not really much different than a bunch of for loops with an if statement inside:

    using System;
    using System.Linq;
    class WeighsAndMeans
      static void Main(string[] args)
        var solveForWeights =
          from a in Enumerable.Range(1, 13)
          from b in Enumerable.Range(1, 13)
          from c in Enumerable.Range(1, 13)
          from d in Enumerable.Range(1, 13)
          from e in Enumerable.Range(1, 13)
          from f in Enumerable.Range(1, 13) 
          from g in Enumerable.Range(1, 13)
          from h in Enumerable.Range(1, 13)
          from i in Enumerable.Range(1, 13) 
          from j in Enumerable.Range(1, 13)
          from k in Enumerable.Range(1, 13) 
          from l in Enumerable.Range(1, 13)
          from m in Enumerable.Range(1, 13) 
          where (4 * a == b)
             && (5 * c == d)
             && (3 * e == 2 * f)
             && (3 * g == 2 * (c + d))
             && (3 * (a + b) + 2 * j == k + 2 * (g + c + d))
             && (3 * h == 2 * (e + f) + 3 * i)
             && ((h + i + e + f) == l + 4 * m)
             && (4 * (l + m + h + i + e + f) == 3 * (j + k + g + a + b + c + d))
          select new { a, b, c, d, e, f, g, h, i, j, k, l, m, 
    Total = a + b + c + d + e + f + g + h + i + j + k + l + m };
    solveForWeights.ToList().ForEach(result => Console.WriteLine(result)); } }

    A More Efficient Solution

    Part way through writing the code above, I recognized that it wasn't going to be very fast.  It's not too hard to see that it'll execute the body of the where clause 13^13 times.  That's more than 300 trillion times!  Turns out this is exactly what join can help with, and in contrast to the for loop case, it's pretty easy to turn the query above into one which uses joins.  The following code solves the puzzle right away:

    using System;
    using System.Linq;
    class WeighsAndMeans
      static void Main(string[] args)
        var solveForWeights =
          from a in Enumerable.Range(1, 13)
          join b in Enumerable.Range(1, 13) on 4 * a equals b
          from c in Enumerable.Range(1, 13)
          join d in Enumerable.Range(1, 13) on 5 * c equals d
          from e in Enumerable.Range(1, 13)
          join f in Enumerable.Range(1, 13) on 3 * e equals 2 * f
          join g in Enumerable.Range(1, 13) on 2 * (c + d) equals 3 * g
          from h in Enumerable.Range(1, 13)
          join i in Enumerable.Range(1, 13) on 3 * h - 2 * (e + f) equals 3 * i
          from j in Enumerable.Range(1, 13)
          join k in Enumerable.Range(1, 13) on 3 * (a + b) + 2 * j - 2 * (g + c + d) equals k
          from l in Enumerable.Range(1, 13)
          join m in Enumerable.Range(1, 13) on (h + i + e + f) - l equals 4 * m
          where (4 * (l + m + h + i + e + f) == 3 * (j + k + g + a + b + c + d))
          select new { a, b, c, d, e, f, g, h, i, j, k, l, m, 
    Total = a + b + c + d + e + f + g + h + i + j + k + l + m }; solveForWeights.ToList().ForEach(result => Console.WriteLine(result)); } }


    It turns out this is an example of using LINQ to solve integer constraints problems.  In the general case, special purpose libraries built to solve these problems are almost certainly more efficient, but the LINQ example using joins is sufficiently quick at least for this case.  More importantly, the LINQ solution is not too hard to arrive at, and doesn't require knowledge of some special purpose Integer Programming framework.  I see this as an example of one of the great benefits of LINQ - that I can do all sorts of query and transformation in C# without resorting to special purpose frameworks for each different domain I need to work with.

    kick it on

  • LukeH's WebLog

    Simplified Build Configurations (or Why Can’t I Change Build Configurations in Express?)


    I spend a lot of time on the Express Edition Forums, and there are a few questions I see often enough that they probably deserve some more in depth answers here.  One of these is the category of questions about Build Configurations in the Express Editions (C# Express in particular).  Specifically, many folks on the Forums have asked questions along the lines of:

    • “Why can’t I change build configurations in Express?”
    • “How do I build Release in Express?”
    • “Can I create new build configurations in Express?”

    The quickest answer to these questions is to go to Tools->Options->Projects and Solutions->General and check “Show advanced build configurations”.  Doing this will bring back the configuration chooser combo-boxes and dialogs that VS2003 developers are likely familiar with.

    So why is this option off in Express?  Well, you can start by considering how you typically use build configurations in your personal development cycle.  If you are like most developers (especially hobbyist developers) we watch, you don’t change build configurations very often (if ever!).  When you do change build configuration, it’s probably right before you want to release a version of your app out to the community or to a friend.

    Since this pattern is fairly predictable and common, we thought we could take some of the complexity out of the product in this area by controlling your build configuration automatically.  We call this Simplified Build Configurations.  Here’s what we do behind the scenes:

    • When you F5 we build Debug and then run in the debugger
    • When you  Build (ctrl-shift-b) we build Release

    This lets us do the “right thing” for you based on the task you are doing (F5 vs. Build).  Of course, this affects a few other areas of the product as well.  For instance, Project Properties don’t allow you to choose which build configuration they apply to.  Instead, the setting you provide is applied to either both or just Release depending on the setting.  Typically this just accomplishes the “right thing” and allows you to not worry about configurations at all.  But there are a couple “gotchas” if you expect the same behaviour you had in VS2003.

    • On the Build page, conditional compilation symbols will apply to both configurations; but the checkboxes for individual symbols will apply only to Release.
    • Settings like “Output Path” use the Release configuration.  

    The overriding motivation behind this is the same one that motivates the Express Editions in the first place: We want to create a small, lightweight, approachable and easy to learn developer tool for beginners, hobbyists and students.  By removing some of the complexity around build configurations we hope to have pushed the product in this direction.  For those of you who are comfortable with the complexity of build configurations and who have a need to manually manage configurations, feel free to flip the tools|options setting to go back to the VS2003-like behaviour.

  • LukeH's WebLog

    C# is verbose. Verbose is good.


    On ScottWil’s blog recently, Thomas Eyde commented on C#, saying “Basically I think C# is too static, complex and verbose. There [is] so much you have to type which does not add value.”  I am admittedly biased, but I think that C#’s verboseness is a good thing. 


    On the face of it, being able to express the same idea in fewer lines or characters of code sounds like a useful trait in a language.  But there are a couple of reasons why I don’t think this is as good of a goal as it sounds like.


    The first is that far more time is spent reading code than writing it.  If writing code in a particular language takes twice as many lines or characters, but this causes the reader to spend half as much time trying to understand it, the tradeoff is very likely worthwhile (since the code will be read more times than it was written).  This is the same argument that is made to explain why it’s important to use descriptive variable names.  Using variable names that don’t carry any connotations forces the reader to follow the entire flow of the variable through the code to understand what it represents.  On the other hand, variable names that carry connotations about their meaning can help a programmer convey information about the variable, so that the reader can just read a snippet of code and have a good idea what it is doing.


    The second is that tools, like intellisense, can help make the number of characters typed far less than the number of characters of code that are generated.  As a simple example of this, take the following block of code:


    foreach (Item<T> item in state.Items)


      if (item.Index >= item.Production.Right.Count)


        foreach (Terminal<T> follow in Follow(item.Production.Left))


          ActionTable.Add(state, follow, new Reduce<T>(item.Production));



    }                                    (233 keystrokes)


    This can be written in the Visual Studio C# editor with approximately half as many keystrokes as produced characters, by typing the following sequence of characters.


    fore(It<T> item in sta.I)




    f(Te<T> follow in Fol(it.P.L))


    ActionT.A(s,follow,new Re<T>(i.P));



    }                                    (122 keystrokes)


    Or even better, you could take advantage of code snippets, and write the same code in even fewer keystrokes (“” represents a tab):





    ActionT.A(s,follow,new Re<T>(i.P));  (107 keystrokes)


    Of course, the characters typed in above are clearly unreadable, and so the presentation (and persistence) of these as the original C# program helps readability and maintenance of the code for future readers.  But the end result is that in relatively few keystrokes, a programmer can create code that is verbose enough to be easy to read by the next programmer who needs to modify it.  This gives a sort of “best of both worlds”, which feels like a good thing to me.  What do you think?

  • LukeH's WebLog

    It’s been a long time…


    I don’t think it’s that I haven’t had anything interesting to say for the last 7 months, but somehow I haven’t gotten around to blogging about any of it.  So I’m going to try to get back on the horse and put a post up tonight.  Hopefully you’ll see posts more regularly than once every 7 months going forward, but for now, here goes…

  • LukeH's WebLog

    What is in Visual C# Express?


    So far, the first two comments I’ve gotten on my blog have been asking essentially the same question, “What is C# Express?”  This seems like a good indication that I should try to explain what you are getting when you go and download C# Express.


    First off, Visual C# Express is only for writing Windows applications in C#.  For web applications, you can use Visual Web Developer Express, and for other languages, there are Visual Basic Express, Visual J# Express and Visual C++ Express. 


    That said, here is a rundown of some of the things you’ll find in C# Express.  Please note that this is a beta , so by the time the Express products are released, there may be some new features added, and there may be some features trimmed down to enhance the experience.


    C# Editor


    C# Express includes almost all the cool editor features you’ll find in higher end Visual Studio products.  For instance:

    -         Support for the C# 2.0 language, including new language features like generics.

    -         Full IntelliSense, including all the new IntelliSense features that have been added in the 2005 version.

    -         Code Snippets, a new 2005 feature that lets you insert common blocks of code instantly, for instance property definitions.

    -         Some Refactorings, such as intelligently renaming a field or extractinging a method.  There are a few additional refactorings which are not available in C# Express.

    -         And so many more…




    The debugging environment has been streamlined a little to provide a simpler and easier to use debugger without all the windows that you are likely to never use. For instance, we have taken the disassembly window out, and cut back to having only one watch window instead of four.  C# Express does have all of the debugging features you use (or will use) all the time like:

    -         Breakpoints

    -         Watch window

    -         Call stack

    -         Data Tips (hover over your code while in debug mode to see what these are)

    -         Visualizers (click on the little magnifying glass in the watch window to see what these are)

    -         And many more…


    Windows Forms Designer


    The Windows Forms designer in C# Express is the fully functional designer from other versions of Visual Studio.  All of the form layout and databinding features are available in C# Express along with some of the new features in 2005 like:

    -         Snaplines

    -         Smart tags to help you do common tasks with your controls.

    -         A bunch of new controls

    -         Strongly typed resources

    -         Settings designer

    -         And many more…


    Data Connectivity

    With the included SQL Server Express, you can write applications that connect to a local database.  See the VSData team’s blog for details about this.  And with full support for consuming webservices, you can easily write applications that talk to Amazon, Google, or any of the other thousands of webservices out there.


    Some Things You Won’t Find in C# Express

    Although it is a very full featured environment, there are some things you won’t find in C# Express that you would find in other Visual Studio products. 

    -         Source control

    -         Add-ins and Macros

    -         Class Designer

    -         ClickOnce deployment

    -         Remote debugging

    -         Mobile development

    -         Unit testing


    If these are features you use a lot, C# Express probably won’t be the right development tool for you.  However, if you are looking for a great small tool for writing C# Windows applications, C# Express will be a great choice.


    But why trust me, go download the beta and see for yourself!  Then come back here and let me know what you think.

  • LukeH's WebLog

    C# Express RSS Screensaver


    One of the cool projects I’ve worked on as part of working on C# Express is the “starter kit” that we added to the C# Express product.  Dan and Shaykat have both blogged about the starter kit, but I’ll try to go into some more detail about what these starter kits are.


    What is a starter kit?

    This is a question we get all the time.  The answer is that starter kits are like samples, but with better documentation and with clear ideas for extending the application to add new features.  They can be used as just a cool application, as an example of how to use some new language features (generics) and .NET framework APIs (strongly typed resources), or as a starting point for playing around with a small application.  They are also integrated closely into the environment by being added to the File->New->Project… dialog box.


    What is the RSS Screensaver starter kit?

    The starter kit we have in the C# Express beta is an RSS Screensaver.  Dan has some great screenshots here.  The documentation that’s included with the starter kit has lots of information about how it works.  There is also a section at the end with some possible ways to extend the screensaver.


    What is cool about the RSS Screensaver starter kit?

    1)      It’s a fully functional screensaver.  You can set it to be your screen saver so you can always be up to date on the latest C# info!

    2)      You can use the source to learn about C#, the .NET frameworks and how to use the Visual Studio environment.

    3)   You can learn about lots of neat GDI+ tricks, like using transparency and writing formatted text to the screen.

    3)      It has a set of classes included that can parse RSS feeds.  You can use these as a starting place for writing your own applications that use RSS feeds.


    How do I get the RSS Screensaver starter kit?

    Download the C# Express Beta from here, and look in the File->New->Projects… dialog box.


    How do I report a bug or a suggestion for the starter kit?

    You can use the MSDN Product Feedback Center to report any bugs or suggestions you have.  You can also post your experiences here.  And if you have extended the screen saver in a cool way, tell us about it.

  • LukeH's WebLog

    Intro + C# Express


    Hi, my name’s Luke and I am a program manager on the C# team at Microsoft.  I’ve wanted to start up a blog for awhile now, so here goes...

    I’m pretty new to Microsoft, but since I’ve been here I’ve had a chance to be involved in some really fun work.  I’m on the C# team, and in particular the C# IDE team.  That means I get to work a lot with Cyrus, Anson, Joe, JayBaz, and all the other folks on the IDE team.  It also means I get to work on some really interesting projects.

    The project that I’ve been working on for most of my time at Microsoft is the Visual C# Express Edition.  So as you can probably guess, I’m really excited that the betas of the Express editions are now available for download.  It’s been really great seeing all the feedback we’ve already received on the Express idea after less than 48 hours.  It sounds like people are really excited about the Express products.


    So go grab an Express product, and let us know what you think!

Page 2 of 2 (33 items) 12