Scott Hanselman

Amazon Kindle

February 26, '08 Comments [40] Posted in Reviews
Sponsored By

DSC_0031UPDATE TWO MONTHS LATER: Now that I've had the Kindle for two months, I still think it's horribly ugly, but I use it EVERY DAY. I subscribe to the NYTimes, to Newsweek and a few blogs. I've purchased 12 books so far and converted/downloaded 20 free ones. The battery life is very good as long as you only turn on the Wireless when you need it. Additionally, I've started using the Kindle as my primary Audible audiobook device and love it. I just slapped a 2gig SD card in and I've got 50+ hours of audio. It's the only device I need for long plane rides.

A year ago I had a Sony Reader for a month and reveled in its awesome screen. It's true, in case you haven't heard, e-ink looks like paper. At least, as close to paper as anything that's not paper can look.

I finally broke down and got an Amazon Kindle for my birthday.

If you are already bored with this post and want to stop here, here's the conclusion. I love it.


The Good Stuff

This device exists for one reason and one brilliant reason only, for Amazon to more easily extract money from my wallet. It's an entire device built around the concept of "One Click" ordering. You do get a second chance if you accidentally order a book, but it's designed for the impulse buyer. If I hear about a book on NPR or The Daily Show, I can get it immediately. If I read a nice book cover at the Airport bookstore on a long layover, I can buy it.

Once you realize its purpose and accept it and are OK with it, you'll like this as well. I like the "any book in the world in one minute or less" (and Bezos is not kidding, the books show up FAST) that I'm disappointed when a book isn't available.

The screen interface is clean, if slow to redraw (because of the e-ink), with just a few obvious usability things that I'm sure they'll fix with regular updates.

DSC_0032I was also thrilled to see that it integrates with Audible, so I popped a two gig SD card in and grabbed a gig and a half of books (about 2 weeks of audio) from my Audible subscription. Why not use a MP3 player? I have had a love/hate relationship with my iPod and consequently have faded away from using it. I find myself listening to XM Radio more often, or using a Zune with the All You Can Listen To Zune Pass, so my iPod has kind of laid fallow. At this point, I just really like the idea of all my books, audio or otherwise, on this one device. It also has a surprisingly loud speaker so I can listen to books without headphones which surprised me.

DSC_0034The Kindle also has an experimental mobile web browser. I say Mobile, because you should consider the Kindle like a really slow Mobile Phone with a slow to redraw grayscale screen. My blog recognizes the Kindle as a mobile device and renders nicely, even with pictures.

This discovery was just an added benefit. I can also check email (painfully) with Gmail's mobile interface. This alone justified, to me, the Kindle's keyboard that I'd previously written off as silly. The Kindle has the potential to be quite the handheld computer if Amazon allows it. For now, I'll just bookmark my new Mobile Home Page and be happy.

It works great with PRC Mobile eBooks (a standard) and as such the whole Baen Free Library (and many other similar ones) are available to me.

The Kindle has its own email address so I can send myself PDFs for 10cents and they'll show up pretty nicely. No, I haven't done PDFs with big images or code, but I can tell you that technical books looked lousy and hard to read on the Sony Reader, and I have no reason to think that the Kindle would be better.

There's a collection of newspapers available, so I got a trial subscription to the NYTimes. I love it. It shows up every day and it's got pictures and everything. Reading the newspaper has naturally fit into my day much more cleanly now, and I'm not in front of a browser for 30 minutes reading. It's more linear in that respect and I prefer it.

It's also got blogs, but they cost a buck or two and I'm not in there so phooey on them. ;)

When you're in an EVDO coverage area, the wireless is surprisingly fast.

The "Meh" Stuff

The Next Page buttons run almost the length of both sides of the thing so I keep accidentally turning pages. Also, I've fallen asleep holding the buttons at least twice and found myself with a dead battery and on the last page.

It's ugly. From a design perspective, it's just not sexy. That said, the Sony Reader wasn't exactly clever either. If I were Amazon I would have gotten the iPod designers on board to help. I will say that it's design is more thoughtful than the Sony Reader's and after a few days I stopped caring. It just works.

The screen is paperback book sized, and I wish it were about 30% larger. There's just too much bezel framing it.

It's still $150 more than I'd like it to be, but I bought it anyway because I KNOW I'll use it. I use it every day to read the newspaper, which was also a surprise. (see above)

DSC_0034 DSC_0033 DSC_0032 DSC_0031

Do be warned, there isn't coast-to-coast coverage. If you live outside the US, or outside a decent-sized city, you won't have coverage. That said, I still live an hour outside of Portland and I have coverage and I likely will have coverage everywhere in the US that I'd visit on a business trip.Be sure to check the Kindle Coverage Tool.


I'm thrilled with the purchase, overall. The wireless ability is the key. I didn't want YET another device to dock to my machine. I am so sick of syncing things and looking for tiny USB cables. I even think I could get a device like this for an elder relative and they'd be able to use it without trouble. I suspect that the Kindle will have me reading more often (and I already read a lot). Recommended.

Related Posts

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

LINQ to Everything - LINQ to XSD adds more LINQiness

February 23, '08 Comments [11] Posted in LINQ | Programming | XML
Sponsored By

It's funny when you work at a company that has as many small projects as it has big ones. I hear one of two things:

"Is _______ dead? I haven't heard anything in a month from _____ team's blog! It must be dead.


"Can you just stop with the 99 different ways to do _______? There's more happening that I can handle."

I'll try to help with the latter in the coming months. Even though we hear about technologies like LINQ to SQL and LINQ to Entities or ASP.NET MVC and WCF and get confused about if they are complementary, there is (usually) a plan behind the whole stack, even if that plan isn't very well-communicated. I'll do a diagram or two to help soon.

But first, looking at the Is ____ dead? question. It'd be cool if someone just dropped a blog post as a "ping" every few weeks like "We're still here! Nope, not dead!" kind of like an Out of Office Response, but for blogs.

For example, LINQ to XSD was mentioned in June of 2007, looked rockin' sweet, and then went silent. However, small teams like this continue to move the ball forward, but we (the outside world) don't hear from them. I'll try to find those projects and ping for the people.

Just yesterday, LINQ to XSD surfaced (I actually had a video call with them on Weds) with a new release.

LINQ to XSD creates .NET classes with much better fidelity than what's created with (the aging) XSD.exe. Now, of course, XSD.exe makes classes for XmlSerialization, while LINQ to XSD makes classes that use an XDocument (not XmlDocument) as the backing store, so we are comparing Apples to Carburetors, but if your goal is to get Objects that come from an XML source, you should take a look at LINQ to XSD.

For example, if I take one of the goofiest schemas, OFX, a financial services schema (disclosure, I was the Vendor Committee Chair for OFX for a few years so I'm to blame a bit) and run it through LinqToXml.exe, here's some differences.

For example, in the XSD for OFX there's some types like "Amount" that have Restriction Facets. The type is a string, but it must match a certain regular expression, like:

<xsd:simpleType name="AmountType">
    <xsd:restriction base="xsd:string">
        <xsd:maxLength value="32"/>
        <xsd:minLength value="1"/>
        <xsd:whiteSpace value="collapse"/>
        <xsd:pattern value="[\+\-]?[0-9]*(([0-9][,\.]?)|([,\.][0-9]))[0-9]*"/>

However, when that's turned into generated code via XSD.exe and XmlSerialization, we get:

private string amountField
public string AMOUNT {   
get {        
return this.amountField;    
set {        
this.amountField = value;    
} }

Which kind of sucks, from a fidelity point of view. We've lost information, the restriction is gone and the Type is gone.

Here's the same thing generated with LINQ to XSD:

public sealed class AmountType {     
public static Microsoft.Xml.Schema.Linq.SimpleTypeValidator TypeDefinition =
new Microsoft.Xml.Schema.Linq.AtomicSimpleTypeValidator(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String),
new Microsoft.Xml.Schema.Linq.RestrictionFacets(((Microsoft.Xml.Schema.Linq.RestrictionFlags)(46)), null, 0, 0, null, null, 32, null, null, 1,
new string[] { "^(([\\+\\-]?[0-9]*(([0-9][,\\.]?)|([,\\.][0-9]))[0-9]*))$"}, 0, XmlSchemaWhiteSpace.Collapse));    
private AmountType() {} }

...and...then the accessor:

public string AMOUNT {     
get { XElement x = this.GetElement(XName.Get("AMOUNT", ""));        
return XTypedServices.ParseValue<string>(x, XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).Datatype);     }
    set { this.SetElementWithValidation(XName.Get("AMOUNT", ""), value, "AMOUNT",;     } }

Note that this is generated, so don't judge it on aesthetics, it's about the experience as a consumer of the API. This is cool because we don't lose anything, the mapping between CLR type and XSD type is clean enough, you get a real type, but you can still access it as a string. If you set a value it's validated on the fly.

Remember again, this is an interesting, if biased, comparison as LINQ to XSD uses an XDocument as the backing store and its properties access the DOM, while XSD.exe/XmlSerializer makes copies using dynamically generated temporary helpers and XmlReaders/XmlWriters to make Objects out of your Angle Brackets.

Another good example of a quiet team that still has cool stuff coming is LINQ to SQL as they update for SQL 2008.

Dear Reader, what's the best way for a team to tell you they are not dead?

Related Posts

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 101 - Dr. Michio Kaku on the Physics of the Impossible

February 22, '08 Comments [26] Posted in Podcast
Sponsored By

Physics of the Impossible: A Scientific Exploration into the World of Phasers, Force Fields, Teleportation, and Time TravelMy one-hundred-and-first podcast is up. Last week I was at an internal Microsoft conference and Dr. Kaku was speaking. I reached out to him personally and was able to interview him at 6 in the morning between his keynote rehearsal and his actual talk, just before he flew back to New York. Needless to say, he's a busy guy and I really appreciated his willingness to chat with me.

Dr. Michio Kaku is a theoretical physicist, best-selling author, and popularizer of science. He's the co-founder of string field theory (a branch of string theory), and continues Einstein's search to unite the four fundamental forces of nature into one unified theory. His book tour starts March 18th and the new book ships March 11th.


In this show, Scott talks with theoretical physicist and futurist Dr. Michio Kaku about making what was once considered impossible technology into reality. This is the topic of his new book, Physics of the Impossible: A Scientific Exploration into the World of Phasers, Force Fields, Teleportation, and Time Travel.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate about Telerik is their commitment to completeness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Weekly Source Code 16 - Duct Tape Edition

February 21, '08 Comments [18] Posted in Source Code
Sponsored By

duct-tape-roll A few weeks ago I interviewed Steven Frank (blog), co-owner of Panic and a Mac Developer (who I went to college with). After that interview I stumbled upon the very recently release NSDuctTape project. First, how can you not like a project named after Duct Tape. Second, whenever I hear that some code will bridge to completely incongruent and unbridgeable things, I gotta check it out. What can I say, if there's a freak somewhere that promises to tape two things together, I want to see it! ;) (And I mean freak in the most positive way!)

NSDuctTape is niche, to be clear, but if you want to write .NET code using Mono on the Mac and you want access to the Objective C Cocoa libraries, this is your one-stop shop. (NOTE: If you do download his source, you'll likely have to pull the files out one at a time because there's Mac files in the zip with the same names as folders and Windows doesn't like it.)

And so, Dear Reader, I present to you sixteenth in a infinite number of posts of "The Weekly Source Code." Here's some source I was reading this week.

Dave, the author, hasn't check on Mono's support for Linq, but he uses C# 3.0 features to create his own LINQ-lite helper methods. I found this to be a clever "punt."

internal static class Enumerable
	public static IEnumerable Select(IEnumerable list, Converter convert)
		foreach (TInput value in list)
			yield return convert(value);

	public static IEnumerable SelectMany(IEnumerable list, Converter> convert)
		foreach (TInput value in list)
			foreach (TOutput converted in convert(value))
				yield return converted;

	public static IEnumerable Where(IEnumerable list, Predicate predicate)
		foreach (T value in list)
			if (predicate(value))
				yield return value;

	public static List ToList(IEnumerable list)
		List result = list as List;
		return result ?? new List(list);

	public static T[] ToArray(IEnumerable list)
		return ToList(list).ToArray();

Because he's "thunking" (not the technically accurate word, but I like saying it) down into unmanaged code that needs to have handles allocated and deallocated, he creates an HGlobal wrapper class using my most favorite .NET BCL pattern, IDisposable. Classic stuff, simple and works great.


public void Dispose()
	if (_hGlobal != IntPtr.Zero)
	_hGlobal = IntPtr.Zero;

private DisposableHGlobal(IntPtr hGlobal)
	_hGlobal = hGlobal;

public static DisposableHGlobal StructureToHGlobal(T value)
	where T : struct
	DisposableHGlobal result = new DisposableHGlobal(Marshal.SizeOf(value));
	Marshal.StructureToPtr(value, result.ToIntPtr(), false);
	return result;

Finally, in his application managed "wrapper" he spins through his chosen System.Types and registers each of them with ObjectiveC. This interop is one way, meaning that he's choosing to expose his .NET types as Objective C classes.

public static void Run(string nibFile, IEnumerable exposedTypes)
	ObjectiveCClass nsAutoReleasePoolClass = ObjectiveCClass.GetClass("NSAutoreleasePool");
	IntPtr autoReleasePool = nsAutoReleasePoolClass.Instantiate();
	ObjectiveCMethods.SendMessage(autoReleasePool, ObjectiveCMethods.SelectorFromString("init"));
		IntPtr process = IntPtr.Zero;
		GetCurrentProcess(ref process);
		TransformProcessType(ref process, ProcessType.ForegroundApplication);
		SetFrontProcess(ref process);


		foreach (Type type in exposedTypes)
			ObjectiveCNameAttribute attribute = MemberInfoUtility.GetCustomAttribute(type);
			Registrar.RegisterClass(attribute != null ? attribute.Name : type.Name, type);

		ObjectiveCClass nsBundleClass = ObjectiveCClass.GetClass("NSBundle");
		IntPtr name = NativeString.StringToNativeString(nibFile);
		ObjectiveCClass nsDictionaryClass = ObjectiveCClass.GetClass("NSDictionary");
		IntPtr key = NativeString.StringToNativeString("NSOwner");
		ObjectiveCClass nsApplicationClass = ObjectiveCClass.GetClass("NSApplication");
		IntPtr sharedApplication = ObjectiveCMethods.SendMessage(nsApplicationClass.ToIntPtr(), ObjectiveCMethods.SelectorFromString("sharedApplication"));
		IntPtr nsDictionary = ObjectiveCMethods.SendMessage(nsDictionaryClass.ToIntPtr(), ObjectiveCMethods.SelectorFromString("dictionaryWithObject:forKey:"), sharedApplication, key);
		IntPtr zone = ObjectiveCMethods.SendMessage(sharedApplication, ObjectiveCMethods.SelectorFromString("zone"));
		ObjectiveCMethods.SendMessage(nsBundleClass.ToIntPtr(), ObjectiveCMethods.SelectorFromString("loadNibFile:externalNameTable:withZone:"), name, nsDictionary, zone);

		ObjectiveCMethods.SendMessage(sharedApplication, ObjectiveCMethods.SelectorFromString("run"));
		ObjectiveCMethods.SendMessage(autoReleasePool, ObjectiveCMethods.SelectorFromString("release"));
		autoReleasePool = IntPtr.Zero;

It's inside the RegisterClass where he creates Objective C classes for each .NET class, lazily making class definitions, and poking values into them. He's using "reflection" on both sides...reflecting over the .NET types, methods, etc and dynamically creating the same types, methods, etc on the ObjectiveC side.

Freaky and fun!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Learning Languages Fast - Can you Flush the Toilet in Zulu?

February 20, '08 Comments [80] Posted in Musings
Sponsored By

Tim Ferriss has a penchant for languages. His post How to Learn (But Not Master) Any Language in 1 Hour got me thinking because he gives eight sentences that you can use to get a really good understanding of how a particular language is constructed.

The apple is red.
It is John’s apple.
I give John the apple.
We give him the apple.
He gives it to John.
She gives it to him.
I must give it to him.
I want to give it to her.

Tim uses these sentences because they show how verbs are conjugated between speaker and subject, they show gender, number, direct and indirect objects, negations and tense. Fantastic.

Interestingly, if you ask two speakers of the same language, you might get different answers.

Here's my wife's answers for the first 6 sentences in isiNdebele:

I ephuli libomvu.
Li ephuli likaJoni.
Nginika uJoni i ephuli.
Simnika i ephuli.
Ulinika uJoni.
Ulinika yena.

And here is the same from her sister.

I apple leli libomvu
Ngelika Johane.
Ngipha uJohane i apple.
Siyamupha i apple.
Uyalipha uJohn.
Uyalipha yena.

There's a few things interesting about this, other than two sisters will never agree on anything. Deconstructing isiNdebele (isiZulu), we see:

  • Nouns start with a vowel as in iapple or iephuli or uJohn. (There are many noun classes, not every one starts with i.)
  • The prefix si- indicates we and ya- is present tense, so siyamupha is we (are giving) give
  • Mo uses ukunika to say "to give" and her sister says ukulipha meaning "to hand over" but they really both mean to give. (From Then her sister goes an uses ukulipha in her 3rd example, so get good examples!
  • There's no gender in the last two, so uyalipha can mean both he gives and she gives.
  • I can see how some verbs are conjugated as in ngipha (I give) and uyalipha (he/she gives)

If there are borrowed words in the language that resonate with me (meaning, I can easily remember them) like imota (car) or ifoni (phone) I can now put together sentences like Imota kaScott (It is Scott's car) or if I learn a few basic infinitive verbs like ukufuna (to want), ukufunda (to learn) or ukucela (to request) I can assemble sentences like:

  • ngicela imali - I want (request) money
  • ngifuna ukufunda isiZulu - I want to learn Zulu

What do you think of Tim's sentences? While you'll not become fluent, it seems to me that this a fun an effective way to learn more than just memorized phrases. You'll certainly build a nice base to build on if your brain works this way.

I know I have a very international readership, and I love travel, so I'd love it if you'd all add in the comments the native translations of these eight sentences in the format:


As an aside, Richard Sprague once said that if you really want to know if someone who says they know a language is really fluent in that language, you should ask them how to say "Flush the toilet." Why that phrase? Because most folks who've cobbled together an understanding of a language from High School or phrase books might be able to assemble an awkward sentence that sounds like "push the button to make the water come" rather than the colloquial or commonly used phrase. For example, in French, "tirer la chasse" translates to the English "pull the chain." Only a person who has lived in a country and gained some fluency knows these kinds of colloquialisms. So the next time your office mate says he knows six languages...find out in how many he can say flush the toilet.

Related Posts

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.