July 2006 - Posts

Notice on the end of NDoc
I think this says something about Open source as a business model

Kevin Downs, the force behind NDoc is dropping work on Open Source Software.  He sent an email to many of the members of the NDoc project. 

It was posted here:

http://weblogs.asp.net/bhouse/archive/2006/07/26/NDoc-2.0-_2D00_-R.I.P.aspx

First, my own confession:  like many others, I used Ndoc and paid diddly.  On the other hand, I fixed a couple of issues, and helped publicize the project in a couple of magazines.

If you read the letter, there are two very interesting points, if you are considering OpenSource as a business model

First, the number of people that actually supported the project was much, much, smaller than the number of people that used the project.  If you are creating a business model built on Open Source, that should be factored into your plans.

Second, the reaction of some of the NDoc community has been, well, immature at best. After announcing that he was dropping support, he was email-bombed to the point where his ISP suspended his account.  Some people seemed to feel that unlimited, never-ending, free upgrades were their right.  I don't know how to factor that into a business plan, but an extremely cranky, immature customer base that will extract revenge if you try and make money is certainly a risk.

Thoughts from others?  Has anyone made an Open Source model work (for a small or micro ISV)?



Atlas at GANG last week
Joe Stagner, from the ASP.NET product team comes to the big D
First, I want to thank Drew Robbins for all his hard work to help bring Joe Stagner to GANG. Joe spent the evening giving us a wealth of information about Atlas. See the links for his blog entry where you can download the slides and the demos.
Second, and more importantly, I want to thank Joe for all the time he spent with our members to discuss Atlas, and its strengths and weaknesses vs. other technologies (both web and smart client).  We got a great overview of the Atlas architecture, its strengths, and its weaknesses.  He made me think more about how the line between web applications and smart clients has been blurred again (until WPF gets released, but that’s next month).
But, even better than the presentation was the discussion period at the end.  Joe had a lengthy list of questions for us, as developers and customers. That was fantastic. We got to tell him everything Good, Bad, and Ugly about .NET. And, he participated in the discussion and openly discussed the areas where .NET needs improvement. The discussions included CAS, Ruby, python, LAMP, AJAX vs. Atlas, and ASP.NET vs. smart client and client / server technologies.
I hope Drew has other product team contacts to bring out for us.


Joe Stagner's slides and demos
Along with a great picture of Drew
My thoughts on 12 Windows Principles
It's better to develop for a widely used platform than a small niche player

Last week, Microsoft announced their 12 Windows Principles to promote competition. You can read the announcement, the principles, and some other press coverage at the links below. Rather than recap all the information, my goal in this short post is to give you my opinion, from a developer standpoint.
The 6th principle is the most important for developers: APIs. It says (I’m paraphrasing) that any API used by a Windows components (browser, media player, etc) that are delivered by the OS will be public. Note that doesn’t mean you will be able to get at the ring level 0 apis used by the internal OS components. But, it does mean that anything used by Office, Media Player, or even Notepad, will be a documented, and supported API. I think this has generally been true, but was not always followed. Also, it should mean that any ISV looking to compete in those spaces will be on an equal footing with the internal MS groups.
I like this better than the anti-trust wrangling about whether or not a browser can be part of an OS. (Anti-trust regulation has a horrible way of living well beyond its useful lifetime.  You’ll note that there are regulations preventing an auto dealer from carrying more than one of the Big 3: GM, Ford, Chrysler  nameplates, but no similar restrictions on foreign nameplates. That may have made sense in the 50s, but no longer. Similarly, any legal definition of what constituted an OS made more than a decade ago would create a useless product today). This principle means any ISV should be able to compete against any non-core OS component, and do so on an even ground. That should help attract competition, VC or angel funding, and the like.
The other three principles for developers are more business-oriented. But, they do make important assertions about Microsoft’s stance on products aimed at the Windows platform: MS won’t use Windows to harm the Windows ecosystem.
That last statement is the one reason to believe MS. It’s not that they want someone to build a better media player, or office product. But, MS is smart enough to know that an OS with no applications is not going to enjoy market popularity. (NeXTStep anyone?) While I’m sure that MS will continue to improve any product that is threatened by a competitor, and I’m sure that MS will continue to enter new markets, they are not going to kill the Windows ecosystem just to make sure your product doesn’t succeed. It’s not smart business. Windows would lose too much market share to linux, Apple, and other competitors if there weren’t the rich application choices for Windows.



Brad Smith on Windows Principles
The full transcript
The 12 Principles
This one goes to 12, which is one more than 11
CNet Story
Anne Broache's analysis

Posted 26 July 2006 09:38 PM by wwagner | no comments
Filed under:
Join Together
Cross Join, Group Join (the final core LINQ entry

Believe it or not, this is the last entry on the core LINQ samples. (Of course, that still leaves LINQ to SQL and LINQ to XML (the technologies formerly known as DLinq and XLinq). 
This entry covers the Join extension method and keywords. ‘join’ does a simple Cross Join between two disparate sequences.  For example, this method builds a list of products and categories based on a list of chosen categories:

public void Linq102() {
    string[] categories = new string[]{
        "Beverages",
        "Condiments",
        "Vegetables",
        "Dairy Products",
        "Seafood" };
    List<Product> products = GetProductList();
    var q = 
        from c in categories
        join p in products on c equals p.Category
        select new { Category = c, p.ProductName };
    foreach (var v in q) {
        Console.WriteLine(v.ProductName + ": " + v.Category);
    }
}

The results show the product name and the category:

Chai: Beverages
Chang: Beverages

Aniseed Syrup: Condiments
Chef Anton's Cajun Seasoning: Condiments
Chef Anton's Gumbo Mix: Condiments

Queso Cabrales: Dairy Products
Queso Manchego La Pastora: Dairy Products

Ikura: Seafood
Carnarvon Tigers: Seafood
Röd Kaviar: Seafood


That’s useful as far as it goes, but chances are you’d prefer having the products grouped.  That’s a simple matter of using a projection to create a new sequence of categories, each with a sequence of products.  That’s a group join:

public void Linq103() {
    string[] categories = new string[]{
        "Beverages",
        "Condiments",
        "Vegetables",
        "Dairy Products",
        "Seafood" };
              
    List<Product> products = GetProductList();
    var q = 
        from c in categories
        join p in products on c equals p.Category into ps // note grouping
        select new { Category = c, Products = ps };
    foreach (var v in q) { // q is a list of categories 
        Console.WriteLine(v.Category + ":");
        foreach (var p in v.Products) { // that contains products
            Console.WriteLine("   " + p.ProductName);
        }
    }
}

The (abbreviated) results are:

Beverages:
   Chai
   Chang
   …
Condiments:
   Aniseed Syrup
   Chef Anton's Cajun Seasoning
   …
Vegetables:
Dairy Products:
   Queso Cabrales
   Queso Manchego La Pastora
   Gorgonzola Telino
   …
Seafood:
   Ikura
   Konbu
   …

Notice that there are no vegetables.  I’ll come back to that in a minute. But first, suppose you want to combine the cross join with a group join to create a single sequence.  It’s a little more verbose, and the results are the same as the first query:

public void Linq104() {
    string[] categories = new string[]{
        "Beverages",
        "Condiments",
        "Vegetables",
        "Dairy Products",
        "Seafood" };
    List<Product> products = GetProductList();
    var q = 
        from c in categories
        join p in products on c equals p.Category into ps
        from p in ps  
        select new { Category = c, p.ProductName };
    foreach (var v in q) {
        Console.WriteLine(v.ProductName + ": " + v.Category);
    }
}

Abbreviated results:

Chai: Beverages
Chang: Beverages

Chef Anton's Gumbo Mix: Condiments
Grandma's Boysenberry Spread: Condiments
Northwoods Cranberry Sauce: Condiments

Queso Manchego La Pastora: Dairy Products
Gorgonzola Telino: Dairy Products
Mascarpone Fabioli: Dairy Products
Geitost: Dairy Products

Ikura: Seafood
Konbu: Seafood
Carnarvon Tigers: Seafood

And finally, you can use LINQ to create an outer join. Note that here, all the left side elements are included at least once, even if there are no matching elements in the right side. That’s the “No Products” entry for vegetables. The code works similar to the earlier examples, but note the second from clause. If ps is empty, the from clause returns null. Then, the select clause adds “No Products” instead of p.ProductName.

public void Linq105() {
    string[] categories = new string[]{ 
       "Beverages", 
       "Condiments", 
        "Vegetables", 
        "Dairy Products", 
        "Seafood" };
               
    List<Product> products = GetProductList();
    var q = 
        from c in categories
        join p in products on c equals p.Category into ps
        from p in ps.DefaultIfEmpty()   
        select new { Category = c,
ProductName = p == null ? "(No products)" : p.ProductName };
    foreach (var v in q) {
        Console.WriteLine(v.ProductName + ": " + v.Category);
    }
}

The results are:

Chai: Beverages
Chang: Beverages

Aniseed Syrup: Condiments
Chef Anton's Cajun Seasoning: Condiments

 (No products): Vegetables
Queso Cabrales: Dairy Products
Queso Manchego La Pastora: Dairy Products

Ikura: Seafood
Konbu: Seafood

I’m not sure that Join is as important as it has been in the past. The select and projection operations can solve many of the same problems.  But, Join has become a common operation, so it’s good to know it’s still there.
Next, we’ll start examining DLINQ and XLINQ.



Part 1
The general Query Syntax
Part 2
The one where I discuss Object and Collection Initializers
Part 3
The one where I finish restriction operators
Part 4
Begining to discuss projections
Part 5
Anonymous types and projections
Part 6
Discussing indexed, filtered, and compound queries
Part 7
Finishing up the projection items
Part 8
Projection operators and extension methods
Part 9
OrderBy, ThenBy, and Descending, oh my
Part 10
Grouping operators and building nested groups
Part 11
Set Operations, you bet
Part 12
Conversions: caching collections
Part 13
Where U at item, where U At?
Part 14
Boolean tests on sequences
Part 15
Aggregation operators: Sum, Product, Averages, and more
Part 16
Concatenation and EqualAll
Part 17
Do it now, or do it later
Posted 13 July 2006 01:36 AM by wwagner | no comments
Filed under: ,
The obligatory post-vacation blog entry
Although I'm trying to stay on point

On the Wright brothers.

The entire family was on vacation last week in the Outer Banks (NC).  I’m not one of those folks that will blog about the vacation, because it’s just not that interesting, and I hope I’m not that vain. But, one of the sites we saw had some interesting content for all us engineering folk: The Wright Brothers National Park in Kill Devil Hills (not Kitty Hawk).  http://www.nps.gov/wrbr/  While I’m sure everyone is familiar with the main points of the story, some of the details have lessons for all of us in a scientific or engineering field. In 1901, the brothers came to NC to test a glider that would prove their in-air control (steering) mechanism.  It was a resounding failure. The problem was that much of their data on lift appeared to be false. So, the brothers built their own wind tunnel and produced their own data. The museum has some of the prototype wings, and the notebook that held all the data. The brothers produced more than 100 wing types, and tested those types at a variety of wind speeds. All that data is still preserved. Once they learned as much as possible about the way wings acted in the wind tunnel, they built a new glider, returned to NC in 1902, and validated the design. They flew more than 600 glider flights in the new design (and modified the design as they tested).

Then, they returned to Ohio to work on the power for the aircraft. Once again, they turned to their wind tunnel to try and create an efficient air prop. A years worth of data was collected, and they had the airplane ready to fly in December of 1903.

The lesson(s) are threefold:  First, judge yourself harshly, and fix what you can as early as possible. It’s your best chance of success.  When the brothers’ glider failed in 1901, they questioned everything about their design. That questioning led them to increasingly better designs.

Second, never learn a lesson more than once. When you find a failure, learn as much as you can, collect copious notes, and move forward. The Wrights flew more than 1,000 glider flights in 1901 and 1902. Every one of those flights taught them something about control, lift, and stability in flight. The notes and prototypes and tests helped them learn more quickly then trying to commit everything to memory.

Third, subdivide a problem and attack it in parts.  The wind tunnel helped them validate wing and propeller designs. The gliders helped them validate control and stability designs, and the final powered flights introduced the engines.

It’s interesting that these amateur engineers (the Wrights had no formal engineering education) followed a more strict engineering methodology than many of my colleagues. (And truth be told, I fall short as well, but I do carry my notebook just about everywhere I go).

How about you?



Posted 07 July 2006 04:50 AM by wwagner | no comments
Filed under:

Search

Go

Blog Group Links

Nascar style badges