<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-464390995524552962</id><updated>2010-09-03T17:25:23.467-04:00</updated><title type='text'>I don't have time for this</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default?orderby=updated'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-414316750291690006</id><published>2010-07-02T18:46:00.001-04:00</published><updated>2010-07-03T11:50:38.097-04:00</updated><title type='text'>Monads As I Have Known Them</title><content type='html'>&lt;h5&gt;Are you really writing yet another Monad tutorial!?&lt;/h5&gt;  &lt;p&gt;No. This is not a Monad tutorial. If this were a Monad tutorial, I would need to be accurate and complete in my description of Monads. I, a repentant, often back-slidden, imperative programmer, have a tenuous, ephemeral grasp on what Monads are and what they’re good for. If you started from where I came from, just consider this blog post a breadcrumb dropped on the path to Monadic enlightenment…or the path to insanity. I’ll let you know when I get there.&lt;/p&gt;  &lt;h5&gt;What is a Monad, anyway?&lt;/h5&gt;  &lt;p&gt;For a complete, correct and nearly incomprehensible (to me, anyway) definition of a Monad, please consult &lt;a href="http://en.wikipedia.org/wiki/Monad" target="_blank"&gt;Wikipedia&lt;/a&gt;. As far as I’m concerned, a Monad is principally a way to combine ‘monadic values’ with other ‘monadic values’, resulting in…other ‘monadic values’.&lt;/p&gt;  &lt;h5&gt;Ok, what’s a “monadic value”?&lt;/h5&gt;  &lt;p&gt;It’s the sort of thing that can be used with Monads. Ha ha, just playing! Well, I mean, that’s not wrong, but I can tell you some other things I’ve noticed about ‘monadic values’. Every monadic value I’ve come across has the following characteristics:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;You can get some number of other values from it. Note that the number of values could well be zero. &lt;/li&gt;    &lt;li&gt;You almost certainly have more than one monadic value with the same structure (i.e. the same way of getting values out of the monadic value). &lt;/li&gt;    &lt;li&gt;There is a sensible way to combine or sequence monadic values together in a single expression such that result of that expression will be another monadic value (of the same type or structure). &lt;/li&gt;    &lt;li&gt;There is a way to take an ordinary, non-monadic value and promote it or contain it as a monadic value. &lt;/li&gt; &lt;/ol&gt;  &lt;h5&gt;What the heck are you talking about?&lt;/h5&gt;  &lt;p&gt;Good question. Let’s try to find an example of a ‘monadic value’. Consider &lt;strong&gt;point #1&lt;/strong&gt;: I don’t know about you, but when I think of the sort of &lt;em&gt;thing&lt;/em&gt; (value, object, whatever…) that I can get other &lt;em&gt;things&lt;/em&gt; from, the first thing I think of is: Lists! And&amp;#160; considerning &lt;strong&gt;point #2,&lt;/strong&gt; I don’t know about you, but my life as a programmer is filled with lots and lots of lists! And I get values out of lists the same way you do, one leg…I mean one element at a time. &lt;strong&gt;And point #3?&lt;/strong&gt; Well, you’ve seen &lt;a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank"&gt;LINQ&lt;/a&gt;, right? And you’ve seen how you can combine two lists in a single LINQ query (with either a ‘join’ or multiple ‘from’ clauses)? Oh, you haven’t? Well, I know you’ve coded (or at least seen) nested ‘foreach’ loops and that, my friend, is combining two lists. Sure, it’s combining them in a dirty, shameful, imperative kind of way, but I’d expect no less of you. And finally, &lt;strong&gt;what about point #4?&lt;/strong&gt; Well, if you can’t figure out how to take a value into a single-element list, I think you should reconsider your chosen profession.&lt;/p&gt;  &lt;h5&gt;So Monads are Lists?&lt;/h5&gt;  &lt;p&gt;Not so good with the logic, I see. Let us review: If all slicks are snicks and all snicks are pricks then…No! Monads are not (necessarily) lists! On the other hand there &lt;em&gt;is&lt;/em&gt; a &lt;strong&gt;List Monad&lt;/strong&gt;. But it’s not the only one! For example, in Haskell there’s also the &lt;strong&gt;Maybe Monad&lt;/strong&gt; for combining values of the Maybe data type. If you’re a .NET programmer like me, you should know that the Maybe data type is quite similar to .NET “reference” types or &lt;a href="http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx" target="_blank"&gt;Nullable&amp;lt;T&amp;gt;&lt;/a&gt;. In other words, it’s a container that can either contain null/nothing &lt;em&gt;or&lt;/em&gt; a single value. The Maybe Monad combines Maybe values in such a way that if any of the combined values are null/nothing, then the overall expression is also null/nothing. What’s the value of the overall expression when all the values are &lt;em&gt;not&lt;/em&gt; null/nothing? Well, that’s up to you, but whatever you come up with has to be a Maybe value.&lt;/p&gt;  &lt;p&gt;There is also the &lt;strong&gt;State Monad&lt;/strong&gt; for sequencing computations that have access to and can possibly mutate some shared state. In effect, this allows you to return to your sinful imperative ways when the need arises…without break the rules of functional purity! Miraculous! There is the &lt;strong&gt;Reader Monad&lt;/strong&gt;, sequencing computations that have access to a (non-mutable) shared environment. And perhaps most famously, there is the &lt;strong&gt;IO Monad&lt;/strong&gt;, which solves the ‘problem’ of representing IO in Haskell in a rather clever and elegant fashion.&lt;/p&gt;  &lt;p&gt;This is hardly an exhaustive catalog of all the Monads there are. In fact, I’d guess there are many more that have yet to be invented!&lt;/p&gt;  &lt;h5&gt;Well, that’s nice, but I’ve gotten this far without Monads, so…&lt;/h5&gt;  &lt;p&gt;I know, and it’s very sad. Think of all the key-strokes wasted! Think of all the unnecessary heart-ache caused by errors in trivial “glue code”! You see, you can get along without Monads, but no one should have to live their life like that, writing the same code pattern over and over and over and…Monads are about writing that code once! And reusing it over and over and…Yes, I know, code re-use is what inheritance is for. But let me tell you something, in a programming language without functional-programming features, &lt;em&gt;this&lt;/em&gt; level of code re-use is somewhere between very difficult and impossible.&lt;/p&gt;  &lt;p&gt;Kind of makes you wonder if ‘objects’ are the right thing to build programs from, doesn’t it?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-414316750291690006?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/414316750291690006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=414316750291690006' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/414316750291690006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/414316750291690006'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2010/07/monads-as-i-have-known-them.html' title='Monads As I Have Known Them'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-6024209839593528643</id><published>2010-04-14T11:59:00.001-04:00</published><updated>2010-04-14T12:26:41.215-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IE9'/><title type='text'>Is Microsoft Taking the Right Approach with Internet Explorer 9?</title><content type='html'>&lt;p&gt;Microsoft has been making &lt;a href="http://blogs.msdn.com/ie/" target="_blank"&gt;some&lt;/a&gt; &lt;a href="http://channel9.msdn.com/tags/IE9/" target="_blank"&gt;noise&lt;/a&gt; lately about the upcoming version of Internet Explorer, IE 9. While it’s still way to early to pass final judgment, some of the things that folks at Microsoft &lt;a href="http://channel9.msdn.com/posts/Charles/IE-9-Standards-and-Interoperability/" target="_blank"&gt;have been saying&lt;/a&gt; about version 9 have me wondering if Microsoft is missing an opportunity.&lt;/p&gt;  &lt;p&gt;If you’ve heard anything Microsoft have said about IE 9, then you’ve probably also heard them say that the various &lt;a href="http://acid3.acidtests.org/" target="_blank"&gt;web standards&lt;/a&gt; and &lt;a href="http://www2.webkit.org/perf/sunspider-0.9/sunspider.html" target="_blank"&gt;performance&lt;/a&gt; benchmarks that everyone seems to care about do not necessarily reflect how browsers are used in the real world. Based on hearing this mantra stated repeatedly by various people and in various ways, I’ll be very surprised if IE 9 turns out to be very competitive in the aforementioned benchmarks.&lt;/p&gt;  &lt;p&gt;I can see two alternate conclusions that can be drawn from this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Microsoft is focused on delivering a browser that works well in the real world, and artificial benchmarks are at most a minor concern. &lt;/li&gt;    &lt;li&gt;Microsoft realizes that Internet Explorer will not be competitive with the likes of &lt;a href="http://www.google.com/chrome" target="_blank"&gt;Chrome&lt;/a&gt; anytime soon and all this “real world usage” talk is just spin. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Suppose that we give them the benefit of the doubt and assume that the first scenario is close enough to the truth. Can one really argue against being pragmatic? Would anyone be so foolish as to argue that Microsoft &lt;em&gt;should&lt;/em&gt; focus on artificial benchmarks, possibly at the expense of “real world” performance? Hi, my name is Daniel…&lt;/p&gt;  &lt;p&gt;The thing is, I think Microsoft has a bit of an image problem. I think many folks think “Microsoft” is synonymous with “moribund”. To be sure there is plenty of evidence that Microsoft is still trying hard and is still willing to take risks: Windows 7 is an unqualified success. The Microsoft Office UI reboot was a risk that seems to have paid off. &lt;a href="http://www.engadget.com/tag/WindowsPhone7/" target="_blank"&gt;Windows Phone 7&lt;/a&gt; looks fantastic (but we have yet to see if fantastic is good enough -- it wasn’t for Zune). Then there is &lt;a href="http://www.xbox.com/en-US/live/projectnatal/default.htm" target="_blank"&gt;Natal&lt;/a&gt;, which will either be awesome or become the next Segway (a product practically killed by its own hype-machine).&lt;/p&gt;  &lt;p&gt;On the other hand, there are also plenty of &lt;a href="http://www.youtube.com/watch?v=1cX4t5-YpHQ" target="_blank"&gt;reminders&lt;/a&gt; of that “other” Microsoft, the one that seems lazy and out-of-touch. And currently Internet Explorer is definitely one of those reminders. Considering that Microsoft is the largest software company in the world, and makes the very platform on which Internet Explorer runs and considering that Internet Explorer is a flagship product, the situation is a bit embarrassing, I think.&lt;/p&gt;  &lt;p&gt;The next version of IE is therefore an opportunity to surprise and impress, to convince the people still sitting on the fence that Microsoft, despite its occasional gaffes, is still a relevant, vibrant company…and sitting on the fence is darned uncomfortable anyway. One way Microsoft can do that is by making a browser that doesn’t have to apologize or make excuses for its performance or support for web standards.&lt;/p&gt;  &lt;p&gt;What do you think?&lt;/p&gt; &lt;script type="text/javascript"&gt;var dzone_url = 'http://www.danielgpratt.com/2010/04/is-microsoft-taking-right-approach-with.html';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_style = '1';&lt;/script&gt;&lt;script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"&gt;&lt;/script&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-6024209839593528643?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/6024209839593528643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=6024209839593528643' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6024209839593528643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6024209839593528643'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2010/04/is-microsoft-taking-right-approach-with.html' title='Is Microsoft Taking the Right Approach with Internet Explorer 9?'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-4529661185830134326</id><published>2009-02-15T21:52:00.001-05:00</published><updated>2009-02-15T22:00:16.878-05:00</updated><title type='text'>The Value of Commenting Code</title><content type='html'>&lt;h4&gt;Never Changing Constants&lt;/h4&gt;  &lt;p&gt;Our legacy product started life about 10 years ago, about a year ago before I started here. Not including “designer” generated stuff, the entire code base is about 500,000 lines of VB6 code, spread across 35 projects. Considering that those of us who worked on the project from the beginning did not have much combined experience making a Windows application of this size and scope, you can imagine that a lot of mistakes were made. I don’t think there is anything in the code base today that is worthy of &lt;a href="http://thedailywtf.com/" target="_blank"&gt;The Daily WTF&lt;/a&gt;, but that wasn’t always the case.&lt;/p&gt;  &lt;p&gt;I’ve seen many things in the code that made me laugh, cringe, or cry, but my favorite is probably this comment:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#008000"&gt;	'Never changing constants.&lt;/font&gt;
	&lt;font color="#0000ff"&gt;Public Const&lt;/font&gt; AUTO_ID_NAME &lt;font color="#0000ff"&gt;As String&lt;/font&gt; = &amp;quot;RecordID&amp;quot;&lt;/pre&gt;

&lt;p&gt;I guess the commenter wanted to distinguish the above from those constants that do change...&lt;/p&gt;

&lt;h4&gt;What Is Your Opinion about Code Comments?&lt;/h4&gt;

&lt;p&gt;I remember being asked about code comments in my interview to work here.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Interviewer&lt;/strong&gt;: What is your opinion about code comments?&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: Uh…they’re good?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I guess that’s what they wanted to hear. Since then my thinking around code commenting has become a lot more nuanced. I’ll summarize it this way:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Good comments are good. &lt;/li&gt;

  &lt;li&gt;Pointless comments are bad. &lt;/li&gt;

  &lt;li&gt;Bad comments are worse. &lt;/li&gt;

  &lt;li&gt;Most comments (in my experience) are not “good”. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It makes me wonder: What would have been the interviewer’s opinion of my &lt;em&gt;nuanced&lt;/em&gt; answer?&lt;/p&gt;

&lt;h4&gt;At Least It Has Comments&lt;/h4&gt;

&lt;p&gt;I recently came across &lt;a href="http://thedailywtf.com/Articles/The-How,-Not-the-Why.aspx" target="_blank"&gt;this post&lt;/a&gt; on The Daily WTF. Here’s the reader’s digest version: The code has been thoroughly commented, but the comments are pretty much the code translated to English. Helpful, I suppose, if you’re not familiar with the programming language being used. Oh well, we’ve all seen worse. Then I starting reading the comments (the comments responding to the post, not the code comments). There was this one:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“H*ll, at least it has comments...”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this one:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“More comments the better, even if they are &amp;quot;obvious&amp;quot; ones.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And a bunch more along the same lines. This was very enlightening for me. Apparently trying to write good comments about the intent of the code has been a waste of my time. I’m going to start littering my code with personal anecdotes in the comments. No…even better, I’m going to create a “Comment-ifier” that will automatically improve code quality through randomly generated comments. Patent pending, so don’t even think about it.&lt;/p&gt;

&lt;h4&gt;The Problem with the Software Development Industry…&lt;/h4&gt;

&lt;p&gt;I see a link between this attitude about code comments and the recent &lt;a href="http://www.codethinked.com/post/2009/02/11/Today-Ive-Realized-How-Far-We-Have-To-Go.aspx" target="_blank"&gt;kerfuffle&lt;/a&gt; about some heretical statements uttered by a one &lt;a href="http://www.joelonsoftware.com/" target="_blank"&gt;Joel Spolsky&lt;/a&gt; on &lt;a href="http://www.hanselminutes.com/default.aspx?showID=163" target="_blank"&gt;Hanselminutes&lt;/a&gt;. From the sounds of things, Joel doesn’t think much of the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" target="_blank"&gt;SOLID&lt;/a&gt; principles. Gallingly, Joel’s cohort, Jeff Atwood was right there to lend Joel some &lt;a href="http://www.codinghorror.com/blog/archives/001225.html" target="_blank"&gt;moral support&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m not ready to get on Jeff and Joel’s bandwagon (I do not wish to be excommunicated), but I think they have a point. &lt;strike&gt;Programmers&lt;/strike&gt; Human beings have a strong tendency to latch on to Ideas to make themselves a better &lt;strike&gt;programmer&lt;/strike&gt; human being. I put this down to intellectual laziness. Being better at anything requires continuous effort. Ideas are much easier to implement.&lt;/p&gt;

&lt;p&gt;Learning coding “best practices” &lt;em&gt;will &lt;/em&gt;(hopefully) make you a better coder, but that is not the key to &lt;em&gt;being&lt;/em&gt; a good coder. For one thing, I think it is vital to understand the “why” of those “best practices”. Thinking back to that WTF post, maybe if the person who wrote that code had ever thought about why commented code is important, he or she would’ve come up with some better comments.&lt;/p&gt;

&lt;h4&gt;The Secret to Good Code&lt;/h4&gt;

&lt;p&gt;So there are probably at least as many coding “best practices” or methodologies out there as there are fad diets. Do any of them work? All the time? Everywhere? Obviously not, otherwise why are we still talking about it. For what it’s worth, here’s what’s been working for me so far:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Care &lt;/li&gt;

  &lt;li&gt;Cheat &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Care means care about the quality of your code. Care about the next guy who has to use or maintain what you did. Care about whether your code still works after you’ve retired. Care about your future self, who will probably have to do the same thing again in a different project.&lt;/p&gt;

&lt;p&gt;Cheat means copy from the smart kids. Someone somewhere has succeeded at doing something very similar to what you’re working on right now. You just need to find it and copy it as best you can. Of course, to be a good cheat, you’ll need to get your eyes on as much good code or concepts as you can. Even if you don’t need it today, you may at some point in the future. A case in point: One of my all-time favorite books in my library is &lt;a href="http://www.amazon.com/Writing-Compilers-Interpreters-Ronald-Mak/dp/0471113530" target="_blank"&gt;Writing Compilers and Interpreters&lt;/a&gt; by Ronald Mak. I read* it so much, the book is now literally in pieces. Have I ever written a compiler or interpreter? No. Have the techniques outlined in the book helped me with other tasks? Absolutely yes, from simple things like how to properly handle CSV formats with embedded quotes to bigger ideas like how to take a relatively massive problem and break it down into manageable pieces.&lt;/p&gt;

&lt;p&gt;Honestly, I don’t think I can say enough about the value of being exposed to as many programming languages, frameworks, architectures, or projects as possible. This is good because:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You have a much better chance of knowing the right tool for the job. &lt;/li&gt;

  &lt;li&gt;Seeing the same problem solved in multiple different ways will expand your mind. &lt;/li&gt;

  &lt;li&gt;All those ideas bouncing around in your brain will eventually collide and stick together to make new ideas (not all of them will be good, of course). &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;font size="2"&gt;* “read” here is intended as past tense. Don’t you just love the English language?&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left; margin:0px; padding:4px 4px 4px 4px;"&gt;&lt;script type="text/javascript"&gt;var dzone_url = 'http://www.danielgpratt.com/2009/02/value-of-commenting-code.html';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_title = 'The Value of Commenting Code';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_blurb = 'The Value of Commenting Code';&lt;/script&gt;&lt;script type="text/javascript"&gt;var dzone_style = '1';&lt;/script&gt;&lt;script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"&gt;&lt;/script&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-4529661185830134326?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/4529661185830134326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=4529661185830134326' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4529661185830134326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4529661185830134326'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2009/02/value-of-commenting-code.html' title='The Value of Commenting Code'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-5766471805913993624</id><published>2009-01-18T14:25:00.001-05:00</published><updated>2009-01-18T15:30:07.115-05:00</updated><title type='text'>Comparing Functional and Imperative, Part 1: Context determines meaning</title><content type='html'>&lt;p&gt;Over the past year, I’ve taken a strong interest in functional programming. I’m not sure where it started, but it may have been Brian Beckman’s &lt;a target="_blank" href="http://channel9.msdn.com/shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads/Default.aspx?wa=wsignin1.0"&gt;Don’t fear the Monads&lt;/a&gt; on &lt;a target="_blank" href="http://channel9.msdn.com/"&gt;Channel 9&lt;/a&gt;. It went pretty much completely over my head, but my interest was definitely piqued. It has been in my mind to do a series of posts on functional programming once I became an expert on the subject. Well, I am &lt;em&gt;so &lt;/em&gt;not an expert at this point, but I’ve decided to consider that an advantage. Once something makes perfect sense to you, it’s often hard to remember why it didn’t make perfect sense before.&lt;/p&gt;  &lt;p&gt;Functional programming is an alternate universe of programming where hard things (e.g. concurrency) become easier and easy things (e.g. writing to a file) become at least a bit harder. Besides the fact that functional programming is just plain different from imperative programming, another challenge for an imperative programmer learning functional programming is the fact that the same or similar syntax is used to represent quite different things. Consider:&lt;/p&gt;  &lt;pre&gt;	a = 3
	b = a + 2&lt;/pre&gt;

&lt;p&gt;In an imperative language context, this would probably mean “assign the value 3 to variable ‘a’, then evaluate a + 2 and assign the resulting value to variable ‘b’”. In a functional programming language such as Haskell, ‘a’ and ‘b’ can be thought of as being functions. This may not technically be true, particularly in the case of ‘a’, but I think it works to think of them that way. Just to drive the point home, here is an equivalent definition in C#:&lt;/p&gt;

&lt;pre&gt;	int a() { return 3; }
	int b() { return a() + 2; }&lt;/pre&gt;

&lt;p&gt;One concept of functional programming that is quite different from imperative programming is the idea that once you define ‘a’, you can’t change it. Of course, if ‘a’ is actually a function, then this is to be expected. Even in imperative programming languages, the definitions of functions generally don’t change in a compiled program. The fact that ‘a’ is a function also explains something else that is at first peculiar about functional programming, which is the order in which statements get evaluated. Consider:&lt;/p&gt;

&lt;pre&gt;	a = 3
	b = a + 2
	c = b + 1&lt;/pre&gt;

&lt;p&gt;In an imperative program, the first line would be evaluated first, followed by the second line and so on. But what if ‘a’, ‘b’ and ‘c’ are actually functions? The equivalent C# code might look something like this:&lt;/p&gt;

&lt;pre&gt;	int a() { return 3; }
	int b() { return a() + 2; }
	int c() { return b() + 1; }&lt;/pre&gt;

&lt;p&gt;If there were some code that referenced the ‘c’ function, program execution would jump to function ‘c’, then to function ‘c’ and so on. Furthermore, if no other code in the program referenced functions ‘b’ or ‘c’, then neither of those functions would ever execute. So it is in functional programming. The point is that if we think of syntax like “foo = ...” as defining a function, it’s easier to grasp as opposed to thinking of it as a statement with special rules.&lt;/p&gt;

&lt;p&gt;When I learned that pure functional programming has no mutable variables and no “side-effects”, my first thought was “How can I actually &lt;em&gt;do&lt;/em&gt; anything?”. Well, Haskell (a pure functional language if there ever was one) &lt;em&gt;does &lt;/em&gt;have side-effects, depending on how you choose to define them. For example, there are functions that perform IO (reading and writing to file streams). On the other hand, these side-effects are definitely not incidental, as they are in imperative languages. In Haskell, you &lt;em&gt;know&lt;/em&gt; when a function may have side-effects. Generally, Haskell treats side-effecting code rather like nuclear waste, encapsulating it in a special container called a “Monad” and posting lots of scary warning signs around it.&lt;/p&gt;

&lt;p&gt;Can a pure functional programming language be useful &lt;em&gt;without &lt;/em&gt;side-effects? I think the answer is yes. I work for a company that creates LOBs (Line of Business apps) first and foremost. When you take all the layered architecture and technology concepts out of the picture, an LOB looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_lGpaqv0-roY/SXOCEdzR57I/AAAAAAAAACA/5wVNo6QSY7Q/s1600-h/image16.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_lGpaqv0-roY/SXOCEp446NI/AAAAAAAAACE/NtFdsc_KmbM/image_thumb10.png?imgmax=800" width="345" height="105" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That yellow arrow in the middle of the diagram is a &lt;em&gt;transformation&lt;/em&gt;. It &lt;em&gt;transforms&lt;/em&gt; the shape of the data as it comes from the user interface into the shape it has in the database. You could imagine that it’s a pipeline, of sorts, constructed of all manner of logical loops and branches. There is no reason that yellow arrow needs to have any mutable state within itself. In fact, for reasons of scalability and consistency, it would be better if that yellow arrow didn’t have any mutable state inside it. As such functional programs are uniquely suited to constructing this sort of pipeline.&lt;/p&gt;

&lt;p&gt;Continue to &lt;a target="_blank" href="http://www.danielgpratt.com/2009/01/comparing-functional-to-imperative-part.html"&gt;Part 2: Economies of Syntax&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-5766471805913993624?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/5766471805913993624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=5766471805913993624' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/5766471805913993624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/5766471805913993624'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2009/01/comparing-functional-and-imperative.html' title='Comparing Functional and Imperative, Part 1: Context determines meaning'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-4277982068099126602</id><published>2009-01-18T14:30:00.001-05:00</published><updated>2009-01-18T14:55:36.558-05:00</updated><title type='text'>Comparing Functional to Imperative, Part 2: Economies of Syntax</title><content type='html'>&lt;p&gt;This is part 2 of a series (consisting of at least two posts) comparing imperative programming languages with functional programming languages. Here is &lt;a target="_blank" href="http://www.danielgpratt.com/2009/01/comparing-functional-and-imperative.html"&gt;Part 1: Context determines meaning&lt;/a&gt;. By the way, &lt;a target="_blank" href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; is my prototypical functional language because it’s the purest functional language about which I know anything. &lt;a target="_blank" href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)"&gt;C#&lt;/a&gt; is my prototypical imperative language because I know it pretty well.&lt;/p&gt;  &lt;p&gt;It seems that functional algorithms and programs are quite a bit shorter than their imperative counterparts. For example, here is a possible definition of a function to calculate square values in Haskell:&lt;/p&gt;  &lt;pre&gt;	square x = x * x&lt;/pre&gt;

&lt;p&gt;For sake of comparison, here an equivalent function defined in C#:&lt;/p&gt;

&lt;pre&gt;	static double Square (double x) { return (x * x); }&lt;/pre&gt;

&lt;p&gt;The Haskell version is less than a third as long as the C# version. As far as I’m concerned, this is a win for Haskell. I much prefer a syntax that does not get in the way of what a program actually &lt;em&gt;does&lt;/em&gt;. This is mostly why I gravitated to C# even after several years of nothing but VB. VB syntax may be easier to learn for the beginner, but I find it slows me down because I have to read (or worse write) past a bunch of words before I get to the meaningful part. Of course, C# may be concise compared to VB, but it’s hard to imagine a more concise syntax than is afforded by Haskell.&lt;/p&gt;

&lt;p&gt;How can a functional language like Haskell get by with such an economy of syntax? One reason is that Haskell was designed to create functions, first and foremost. Do one thing and do it well, as the saying goes. Another reason is that Haskell is very good about inferring the types of things from other things. You &lt;em&gt;can&lt;/em&gt; give things an explicit type in Haskell, but often the only reason to do so is to help the compiler help you when you screw up. For example, Haskell knows that ‘square’ is a function that returns a numeric value. It knows this because it knows that the ‘*’ operator returns a numeric value. It also knows that parameter ‘x’ must be a numeric value, likewise from the definition of ‘*’. In other words, Haskell will not let you do something like this:&lt;/p&gt;

&lt;pre&gt;	y = square &amp;quot;foo&amp;quot;&lt;/pre&gt;

&lt;p&gt;Of course, it is possible to define a function in Haskell that does not, in its definition, imply a particular return type at all. In such a case, Haskell will define the function in a generic fashion. Think C# generics without all the syntactic fluff. Consider Haskell’s ‘foldl’ (fold left) function:&lt;/p&gt;

&lt;pre&gt;	foldl f z [] = z
	foldl f z (x:xs) = foldl f (f z x) xs&lt;/pre&gt;

&lt;p&gt;Basically, ‘foldl’ applies an operation to each item in a list, accumulating the result of the operation along the way. The accumulated value is the return value of ‘foldl’. As of version 3.5, the .NET Frameworks has a function that serves the same purpose: Enumerable.Aggregate. What does it look like? Hang on to your hat…&lt;/p&gt;

&lt;pre&gt;	public static TAccumulate Aggregate&lt;tsource  , taccumulate&gt;(
		this IEnumerable&lt;tsource&gt; source,
		TAccumulate seed,
		Func&lt;taccumulate  , taccumulate tsource,&gt; func)
	{
		if (source == null)
		{
			throw Error.ArgumentNull(&amp;quot;source&amp;quot;);
		}
		if (func == null)
		{
			throw Error.ArgumentNull(&amp;quot;func&amp;quot;);
		}
		TAccumulate local = seed;
		foreach (TSource local2 in source)
		{
			local = func(local, local2);
		}
		return local;
	}&lt;/pre&gt;

&lt;p&gt;Why is Haskell’s version so much shorter? One obvious answer is Haskell’s penchant for exceedingly short parameter names (something I don’t care for, actually). It’s much more than that, though. In Haskell’s version, there are no explicit types, no explicit generic parameters, and much less ‘punctuation’. Does this mean that Haskell is weakly-typed? Not at all. Haskell’s version is at least as strongly-typed as the .NET version. In fact, considering that Haskell will not let you pass invalid parameters to ‘foldl’, it can be considered to be &lt;em&gt;more &lt;/em&gt;strongly typed than the .NET function, and also eliminates the need for parameter validation in the body of the function.&lt;/p&gt;

&lt;p&gt;I’m not sure what part 3 of the series will be (or even if there will be a part 3), but I’m considering a post about why IO is a challenge for pure functional languages and how Monads make it much better.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-4277982068099126602?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/4277982068099126602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=4277982068099126602' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4277982068099126602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4277982068099126602'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2009/01/comparing-functional-to-imperative-part.html' title='Comparing Functional to Imperative, Part 2: Economies of Syntax'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-6565113210277588173</id><published>2009-01-01T08:57:00.001-05:00</published><updated>2009-01-01T08:57:44.090-05:00</updated><title type='text'>A Confession: I don’t have a degree</title><content type='html'>&lt;p&gt;I ran into a blogo-sphere &lt;a target="_blank" href="http://www.billthelizard.com/2008/12/education-vs-experience.html"&gt;discussion&lt;/a&gt; recently about the merits of having a CS degree. I found this particularly interesting because, well, I don’t have a degree. Shocking, I know, coming from someone who claims to be a “Software Architect” (well, that &lt;em&gt;is&lt;/em&gt; my job title). I’ll give you a minute to recover.&lt;/p&gt;  &lt;p&gt;To be very cathartically honest, I wish it were not true. I have a full-time+ job and a full-time+ family, but if I had an opportunity to pursue a degree, I’d seriously consider it. So there you have it. There is at least one non-degree-possessing person in this world who thinks having a degree is a good thing.&lt;/p&gt;  &lt;p&gt;On the other hand, a lot of what I read about the purported merits of having a degree is…just crap, in my opinion. I believe and accept the fact that a lot of people have learned a lot of things in a college or university setting, things that they would never learn in “real” life. I believe and accept the fact that for most people, there isn’t a better way to get a well-rounded education. I &lt;strong&gt;do not&lt;/strong&gt; believe those things are true for &lt;em&gt;me&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;It has been well established that there are at least a few different ways that people learn best. I think it is also reasonable to conclude that what any person has learned or been exposed to in his or her life is going to be unique to that person. For these and other reasons, concept “A” might really “click” with Alice, while Bob just doesn’t get it. For concept “B”, it may be just the opposite. In a classroom setting, the extra time it takes to teach concept “A” to Bob is a waste of time for Alice. The extra time it takes to teach concept “B” to Alice is a waste of time for Bob. This leads me to conclude that classroom learning is not particularly time-efficient.&lt;/p&gt;  &lt;p&gt;I think the primary benefit of learning in a college/university classroom setting is the fact that most people do not have the motivation or, in some cases, the ability to educate themselves.&lt;/p&gt;  &lt;p&gt;I love to learn. It might be more correct to say that I’m addicted to information…of any sort, really. Truly, I’m not sure I’ve ever encountered any subject matter or concept that didn’t interest me, at least a little bit. People have told me that they are intimidated to have a conversation with a subject matter expert concerning said subject matter. They’re afraid of asking an ignorant question. I can’t relate to that. I’ll happily make a fool of myself, asking that person a thousand stupid questions, just for the chance to learn something.&lt;/p&gt;  &lt;p&gt;One idea I often encounter is the idea that a self-educated person is going to have a “narrow” education. Maybe they can become competent in their field, but they’ll be weak in other areas, which might hamper their overall performance. I think this idea “rings true” with a lot of folks. It seems logical and fair-minded. On the other hand, I’ve never encountered “hard numbers” to support this idea.&lt;/p&gt;  &lt;p&gt;Of course, I can’t give you any hard numbers, either. In fact I can only offer one data-point: myself. If I were to be given a general knowledge test covering various aspects of Math, Science, History, English, etc., I feel confident that my score would compare very favorably with scores obtained by administering the same test to a random selection of college educated people.&lt;/p&gt;  &lt;p&gt;Having said all that, why do I wish I had gotten a degree when I had the chance? Two reasons: First, I did attend college for three semesters. It did not go well. I spent too much time in the computer lab when I should have been in the classroom or completing assignments. Basically, I feel that I failed at college and that bothers me. Second, “Perception Is Reality”. The vast majority of people I work with and, I would guess, the vast majority of people in my field have a degree. I would venture that the majority of these people “perceive” that having a degree is better than not having one (the example set by Bill Gates notwithstanding).&lt;/p&gt;  &lt;p&gt;I know of at least one case where I was not even considered for a position on the basis of not having a degree. I doubt that was an isolated case. If you’re dealing with an overwhelming glut of resumes, you may very well decide to trash all the resumes that don’t appear to “measure up” in all respects.&lt;/p&gt;  &lt;p&gt;This reminds me of the recent experience I had doing the initial interview of several candidates for a Software Developer position in my division. This was a first for me, and the experience was…fascinating. I am thinking of one candidate in particular. This person came with all the right credentials. Not only did this person know everything, but this person had been working for several years at a “big name” company, and before that another “big name” company (we verified this person’s employment history). This person had an MBA.&lt;/p&gt;  &lt;p&gt;On that basis, I was shocked, truly, at what this person did not know about Software Development. The point in the interview that I began to understand the situation was when I asked “It says on your resume that you have experience with technology ‘X’. Can you tell me more about how you used that technology?” This person’s answer was something along the lines of “Well, I didn’t use technology ‘X’ directly. My job was to review and approve other people’s work and send it up the chain.” Imagine several more responses along the same lines. Finally I asked this person to demonstrate how to solve a particular (fairly simple) problem using the language of their choice. Imagine a blank stare. I found myself describing the problem in simpler and simpler terms. The blank stare remained. I eventually realized that this person could not tell me what a “string” was. Yikes!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-6565113210277588173?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/6565113210277588173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=6565113210277588173' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6565113210277588173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6565113210277588173'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2009/01/confession-i-dont-have-degree.html' title='A Confession: I don’t have a degree'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-6809301551872550334</id><published>2008-12-19T13:40:00.001-05:00</published><updated>2008-12-19T13:54:06.483-05:00</updated><title type='text'>Oxite: A good example after all?</title><content type='html'>&lt;p&gt;I haven’t been doing much web development these days, but I’m anticipating that will change in the near future. Consequently, I’ve been keeping an eye on the progress of the various web development frameworks, including &lt;a target="_blank" href="http://www.asp.net/mvc/"&gt;ASP.NET MVC&lt;/a&gt;. When I heard about the &lt;a target="_blank" href="http://www.codeplex.com/oxite"&gt;Oxite&lt;/a&gt; project, I was &lt;em&gt;very&lt;/em&gt; interested. Most example projects I find are just that: examples. Oxite is running a &lt;em&gt;production&lt;/em&gt; &lt;a target="_blank" href="http://www.visitmix.com/"&gt;website&lt;/a&gt;. I immediately downloaded the project sources and…still haven’t even looked at them.&lt;/p&gt;  &lt;p&gt;In the meantime, the community response to Oxite has been…interesting. The general consensus seems to be that they got it all wrong. The last thing I’ve read on the topic (so far) is Glenn Block’s &lt;a target="_blank" href="http://codebetter.com/blogs/glenn.block/archive/2008/12/19/on-oxite.aspx"&gt;On Oxite&lt;/a&gt; post. Ouch! Right now I’m just picturing him running into the Oxite guys at the Microsoft Christmas party…&lt;/p&gt;  &lt;p&gt;Once upon a time, I was a minor presence in the MS NNTP forums. This situation reminds me of something I noticed back then: The surest way to get a relevant and &lt;em&gt;timely&lt;/em&gt; answer to your question would be to post a completely ridiculous solution, don your asbestos underwear, and wait for the responses to roll in.&lt;/p&gt;  &lt;p&gt;Which gets me back to the matter at hand. These days, you can expect that any framework you’d consider using is going to come with with plenty of samples, examples, and documentation. General guidance, especially in the area of “what &lt;em&gt;not&lt;/em&gt; to do”, is harder to come by. This is understandable. I’m sure most of us have had the experience of a customer (or co-worker) taking something we’ve done and use it in a manner that makes us cringe. It’s just very difficult to anticipate all the wrong directions that someone might go.&lt;/p&gt;  &lt;p&gt;I think this makes the Oxite project almost invaluable as an example. I’ve bookmarked &lt;a target="_blank" href="http://blog.wekeroad.com/blog/some-thoughts-on-oxite/"&gt;this post&lt;/a&gt; and you can be sure that if and when I get around to actually using ASP.NET MVC, I’ll read it again. Of course, this is no consolation for the Oxite folks, who probably feel a bit chastised at this point. No one wants to be thought of as the &lt;a target="_blank" href="http://www.imdb.com/title/tt0299930/"&gt;Gigli&lt;/a&gt; of…anything. Well guys, all I can say is thanks for sticking your neck out there on behalf of the rest of us.&lt;/p&gt;  &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.danielgpratt.com%2f2008%2f12%2foxite-good-example-after-all.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.danielgpratt.com%2f2008%2f12%2foxite-good-example-after-all.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-6809301551872550334?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/6809301551872550334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=6809301551872550334' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6809301551872550334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6809301551872550334'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/oxite-good-example-after-all.html' title='Oxite: A good example after all?'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-6869403088891193883</id><published>2008-12-18T12:01:00.005-05:00</published><updated>2008-12-18T12:25:27.940-05:00</updated><title type='text'>Why LINQ is better than SQL, Part 3: Query Composition</title><content type='html'>&lt;p&gt;A LINQ query is like a SQL view in at least two ways:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;No data is retrieved until you really need it. &lt;/li&gt;    &lt;li&gt;LINQ queries can be composed with other LINQ queries. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now I will show you that LINQ queries are &lt;em&gt;better &lt;/em&gt;than SQL views because LINQ queries are more &lt;em&gt;modular&lt;/em&gt; than views.&lt;/p&gt;  &lt;h4&gt;The Problem&lt;/h4&gt;  &lt;p&gt;Suppose that you are creating a dashboard for your business app (which happens to use the same database schema as Microsoft’s AdventureWorks sample database) and one of the data points you need is the sum of total sales by year and month.&lt;/p&gt;  &lt;h4&gt;A Solution Using SQL Views&lt;/h4&gt;  &lt;p&gt;If you implemented a SQL view for this purpose, it might look like this:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;view&lt;/span&gt; vSalesByYearAndMonth
&lt;span class="kwrd"&gt;as&lt;/span&gt;
    &lt;span class="kwrd"&gt;select&lt;/span&gt;
        &lt;span class="kwrd"&gt;SUM&lt;/span&gt;(so.SubTotal) SubTotal
        , DATEPART(yyyy, so.OrderDate) [&lt;span class="kwrd"&gt;Year&lt;/span&gt;]
        , DATEPART(m, so.OrderDate) [&lt;span class="kwrd"&gt;Month&lt;/span&gt;]
    &lt;span class="kwrd"&gt;from&lt;/span&gt;
        [Sales].[SalesOrderHeader] so
    &lt;span class="kwrd"&gt;group&lt;/span&gt; &lt;span class="kwrd"&gt;by&lt;/span&gt;
        DATEPART(yyyy, so.OrderDate), DATEPART(m, so.OrderDate)&lt;/pre&gt;

&lt;p&gt;Now we can take our view and compose it with other views or queries like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;view&lt;/span&gt; vSalesByMonth2004
&lt;span class="kwrd"&gt;as&lt;/span&gt;
    &lt;span class="kwrd"&gt;select&lt;/span&gt;
        SubTotal
        , [&lt;span class="kwrd"&gt;Month&lt;/span&gt;]
    &lt;span class="kwrd"&gt;from&lt;/span&gt;
        vSalesByYearAndMonth
    &lt;span class="kwrd"&gt;where&lt;/span&gt;
        [&lt;span class="kwrd"&gt;Year&lt;/span&gt;] = 2004&lt;/pre&gt;

&lt;p&gt;This is all very good, but now imagine that you’d really like to filter the results by some other aspect of a sales order: the region, the sales person, a product category, etc…You’d need a view for each scenario! Your best bet (assuming you’re using SQL Server) is probably to make a &lt;em&gt;function&lt;/em&gt;. That way you can create a bunch of parameters for everything you might conceivably want to filter by and then make the query itself a &lt;em&gt;lot&lt;/em&gt; more complicated with a whack of “…where (isnull(@x, x) = x) and (isnull(@y, y) = y) and…”. Whee!&lt;/p&gt;

&lt;h4&gt;A Solution Using LINQ&lt;/h4&gt;

&lt;p&gt;Now I’m going to do the same thing using LINQ and Entity Framework (EF). The source of my queries is an ADO.NET Entity Data Model that I generated directly from the AdventureWorks database (if you’re not sure how to do this, &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc716800.aspx"&gt;here is an example&lt;/a&gt;). If you generate a model in this way and never change it, you’re probably missing out on some of the goodness EF has to offer, but for this example I’m sticking with what the wizard gives me.&lt;/p&gt;

&lt;p&gt;The first thing I’m going to do is define a class to contain the result of the query (thanks to anonymous types, this step isn’t always necessary):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;class&lt;/span&gt; YearMonthTotal
        {
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Year { get; set; }
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Month { get; set; }
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; Total { get; set; }
        }&lt;/pre&gt;

&lt;p&gt;Now I’m going to write the LINQ query and encapsulate it in a function (all C# functions must have an explicit return type, which is why the previous step &lt;em&gt;is&lt;/em&gt; necessary):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        IEnumerable&amp;lt;YearMonthTotal&amp;gt; GetSalesByYearAndMonth()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt;
            (
                from so &lt;span class="kwrd"&gt;in&lt;/span&gt; context.SalesOrderHeader
                group so by &lt;span class="kwrd"&gt;new&lt;/span&gt; { so.OrderDate.Year, so.OrderDate.Month } into sog
                select &lt;span class="kwrd"&gt;new&lt;/span&gt; YearMonthTotal { Year = sog.Key.Year, Month = sog.Key.Month, Total = sog.Sum(so =&amp;gt; so.SubTotal) }
            );
        }&lt;/pre&gt;

&lt;p&gt;And for the sake of completeness, here’s what the second view looks like in LINQ:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        IEnumerable&amp;lt;YearMonthTotal&amp;gt; GetSalesByMonth2004()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; (from sbm &lt;span class="kwrd"&gt;in&lt;/span&gt; GetSalesByYearAndMonth() &lt;span class="kwrd"&gt;where&lt;/span&gt; sbm.Year == 2004 select sbm);
        }&lt;/pre&gt;

&lt;p&gt;Fantastic! But, uh, I haven’t done anything in LINQ that I couldn’t easily do with SQL…yet.&lt;/p&gt;

&lt;h4&gt;Making It Modular&lt;/h4&gt;

&lt;p&gt;Essentially, I want to be able to pass a “where” clause as a parameter of my function. The new parameter will have the same type as the &lt;em&gt;predicate&lt;/em&gt; parameter from &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb535040.aspx"&gt;Queryable.Where&lt;/a&gt;, but I’ll specify SalesOrderHeader as the generic parameter because that is what I’m filtering. Here is the revised function:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        IEnumerable&amp;lt;YearMonthTotal&amp;gt; GetSalesByYearAndMonth(&lt;strong&gt;Expression&amp;lt;Func&amp;lt;SalesOrderHeader, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; salesOrderFilter&lt;/strong&gt;)
        {
            &lt;strong&gt;var filteredSalesOrders = context.SalesOrderHeader.Where(salesOrderFilter);&lt;/strong&gt;

            &lt;span class="kwrd"&gt;return&lt;/span&gt;
            (
                from so &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;strong&gt;filteredSalesOrders&lt;/strong&gt;
                group so by &lt;span class="kwrd"&gt;new&lt;/span&gt; { so.OrderDate.Year, so.OrderDate.Month } into sog
                select &lt;span class="kwrd"&gt;new&lt;/span&gt; YearMonthTotal { Year = sog.Key.Year, Month = sog.Key.Month, Total = sog.Sum(so =&amp;gt; so.SubTotal) }
            );
        }&lt;/pre&gt;

&lt;p&gt;Wonderfully strange, is it not? How does one use such a beast? Here’s one example (sales for the Northeast):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;            var neSalesSummary =
                GetSalesByYearAndMonth(so =&amp;gt; so.SalesTerritory.Name == &lt;span class="str"&gt;&amp;quot;Northeast&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;And something more convoluted (sales for the great state of Maine):&lt;/p&gt;

&lt;pre class="csharpcode"&gt;            var maineSalesSummary =
                GetSalesByYearAndMonth(so =&amp;gt; so.SalesTerritory.StateProvince.Any(state =&amp;gt; state.StateProvinceCode ==&lt;span class="str"&gt; &amp;quot;ME&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

&lt;h4&gt;The Result&lt;/h4&gt;

&lt;p&gt;Retrieving the results of that last query causes the entire composed LINQ query to be translated into a single SQL query that looks like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; 
    1 &lt;span class="kwrd"&gt;AS&lt;/span&gt; [C1], 
    [GroupBy1].[K1] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [C2], 
    [GroupBy1].[K2] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [C3], 
    [GroupBy1].[A1] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [C4]
    &lt;span class="kwrd"&gt;FROM&lt;/span&gt; ( &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; 
        [Filter2].[K1] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [K1], 
        [Filter2].[K2] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [K2], 
        &lt;span class="kwrd"&gt;SUM&lt;/span&gt;([Filter2].[A1]) &lt;span class="kwrd"&gt;AS&lt;/span&gt; [A1]
        &lt;span class="kwrd"&gt;FROM&lt;/span&gt; ( &lt;span class="kwrd"&gt;SELECT&lt;/span&gt; 
            DATEPART (&lt;span class="kwrd"&gt;year&lt;/span&gt;, [Extent1].[OrderDate]) &lt;span class="kwrd"&gt;AS&lt;/span&gt; [K1], 
            DATEPART (&lt;span class="kwrd"&gt;month&lt;/span&gt;, [Extent1].[OrderDate]) &lt;span class="kwrd"&gt;AS&lt;/span&gt; [K2], 
            [Extent1].[SubTotal] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [A1]
            &lt;span class="kwrd"&gt;FROM&lt;/span&gt; [Sales].[SalesOrderHeader] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [Extent1]
            &lt;span class="kwrd"&gt;WHERE&lt;/span&gt;  &lt;span class="kwrd"&gt;EXISTS&lt;/span&gt; (&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; 
                &lt;span class="kwrd"&gt;cast&lt;/span&gt;(1 &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;bit&lt;/span&gt;) &lt;span class="kwrd"&gt;AS&lt;/span&gt; [C1]
                &lt;span class="kwrd"&gt;FROM&lt;/span&gt; [Person].[StateProvince] &lt;span class="kwrd"&gt;AS&lt;/span&gt; [Extent2]
                &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; ([Extent1].[TerritoryID] = [Extent2].[TerritoryID]) &lt;span class="kwrd"&gt;AND&lt;/span&gt; (N&lt;span class="str"&gt;'ME'&lt;/span&gt; = [Extent2].[StateProvinceCode])
            )
        )  &lt;span class="kwrd"&gt;AS&lt;/span&gt; [Filter2]
        &lt;span class="kwrd"&gt;GROUP&lt;/span&gt; &lt;span class="kwrd"&gt;BY&lt;/span&gt; [K1], [K2]
    )  &lt;span class="kwrd"&gt;AS&lt;/span&gt; [GroupBy1]&lt;/pre&gt;

&lt;p&gt;It may not be the most readable query, but I can't find any obvious flaws in its logic.&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.danielgpratt.com%2f2008%2f12%2fwhy-linq-is-better-than-sql-part-3.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.danielgpratt.com%2f2008%2f12%2fwhy-linq-is-better-than-sql-part-3.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-6869403088891193883?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/6869403088891193883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=6869403088891193883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6869403088891193883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/6869403088891193883'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/why-linq-is-better-than-sql-part-3.html' title='Why LINQ is better than SQL, Part 3: Query Composition'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-4555793488533532285</id><published>2008-12-16T20:09:00.001-05:00</published><updated>2008-12-16T20:09:21.818-05:00</updated><title type='text'>Why LINQ is better than SQL, Part 2: From comes first</title><content type='html'>&lt;p&gt;&lt;em&gt;&lt;font color="#808080"&gt;[Note: I have another of this “series” on stand-by, but it’s long and slightly complicated, so it made sense to me to post this one first.]&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I’ve recently upgraded my developer workstation to SQL Server 2008 (from 2005). For me the killer feature, hands-down, is IntelliSense. Of course, there’s still room for improvement:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_lGpaqv0-roY/SUhROyitB7I/AAAAAAAAABw/VpvIZJQMATY/s1600-h/image41.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_lGpaqv0-roY/SUhRPLgsuEI/AAAAAAAAAB0/Z6T7zAXlobs/image4_thumb.png?imgmax=800" width="510" height="120" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Great. How about telling me what I can never remember without firing up the documentation, namely which “expression” is the thing I’m searching &lt;em&gt;for &lt;/em&gt;and which is what I’m searching &lt;em&gt;in&lt;/em&gt;? Oh well, they’ll probably address this sooner or later. Then there is this: How can IntelliSense be provided for field names when you haven’t specified the source? It can’t, of course. If you want IntelliSense for field names you can type something like “select from &lt;em&gt;tableA &lt;/em&gt;as a [join &lt;em&gt;tableB&lt;/em&gt; as b]…” &lt;em&gt;then&lt;/em&gt; go back and complete the “select” clause. I know I should be grateful, but I find this mildly annoying.&lt;/p&gt;  &lt;p&gt;LINQ doesn’t have this problem because…“from” comes first.&lt;/p&gt;  &lt;p&gt;IntelliSense is not the only reason I prefer that “from” come first. The &lt;em&gt;biggest&lt;/em&gt; reason is the way that I &lt;em&gt;think&lt;/em&gt; about queries. Basically, I think of them as a pipeline, with data flowing from one end to the other, getting transformed and filtered along the way:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_lGpaqv0-roY/SUhRPn74iiI/AAAAAAAAAB4/wapf60CoVLM/s1600-h/selectstatementflow4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="select statement flow" border="0" alt="select statement flow" src="http://lh6.ggpht.com/_lGpaqv0-roY/SUhRQH8p7YI/AAAAAAAAAB8/mkoQvE2RtPI/selectstatementflow_thumb2.png?imgmax=800" width="477" height="204" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Coincidentally, this is pretty much the same order of elements in a LINQ query.&lt;/p&gt;  &lt;p&gt;Granted, putting the “select” clause first does put SQL &lt;em&gt;slightly &lt;/em&gt;closer to natural English sentence construction. Does that make SQL easier to understand? I think not.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-4555793488533532285?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/4555793488533532285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=4555793488533532285' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4555793488533532285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4555793488533532285'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/why-linq-is-better-than-sql-part-2-from.html' title='Why LINQ is better than SQL, Part 2: From comes first'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-8860687618806210831</id><published>2008-12-09T21:35:00.002-05:00</published><updated>2008-12-09T21:38:31.510-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Overriding LINQ</title><content type='html'>&lt;p&gt;As I’ve said previously, I love LINQ. I love the fact that so much interesting and useful functionality has been built up around a very simple interface (that being IEnumerable, of course). But, as the saying goes, not everything that &lt;em&gt;can &lt;/em&gt;be done &lt;em&gt;should &lt;/em&gt;be done.&lt;/p&gt;&lt;p&gt;Take for example Enumerable.Count (in case you hadn’t noticed, the LINQ-to-objects extension methods are hiding in the “System.Linq.Enumerable” class). Given an IEnumerable&amp;lt;T&amp;gt;, it returns the number of items in the sequence. How does it do that when IEnumerator&amp;lt;T&amp;gt; does not have a Count property or method? One way would be to enumerate over the entire sequence, incrementing a counter along the way. Of course, that’s potentially very inefficient and fortunately Enumerable.Count will only take that approach as a last resort. If the source container implements ICollection&amp;lt;T&amp;gt;, then Enumerable.Count will simply return ICollection&amp;lt;T&amp;gt;.Count.&lt;/p&gt;&lt;p&gt;The strategy LINQ uses makes a lot of sense, I’m sure you’ll agree, but I think there is room for improvement. For one thing, the relationships between LINQ and interfaces like ICollection&amp;lt;T&amp;gt; are not documented (probably because they are tenuous). If you were doing something “weird”, LINQ operations might not behave as you expect. Furthermore, the primary reason we have so many data containers to choose from is that different data containers are optimized for different operations. As it is currently implemented, the onus is on LINQ itself to know and choose the best implementation for each LINQ operation. Of course, if the data container in question did not come “in the box”, this is not merely difficult, but impossible.&lt;/p&gt;&lt;p&gt;I think there should be some way to &lt;em&gt;tell &lt;/em&gt;LINQ that your data container knows how to do operation &lt;em&gt;X&lt;/em&gt; in the most efficient manner possible, and that LINQ should defer its implementation of &lt;em&gt;X&lt;/em&gt; to the container. Perhaps the simplest way to accomplish that would be to organize LINQ operations into some number of logical groups and then define interfaces which, in-turn, define the operations in each group. If a container implements one or more of these interfaces, LINQ will defer its implementation of the corresponding operation(s) to the container. Such an interface might look like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; System.Linq
{
    &lt;span class="kwrd"&gt;interface&lt;/span&gt; ICountable&amp;lt;TSource&amp;gt; : IEnumerable&amp;lt;TSource&amp;gt;
    {
        &lt;span class="kwrd"&gt;int&lt;/span&gt; Count&amp;lt;TSource&amp;gt;(Func&amp;lt;TSource, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; predicate);
        &lt;span class="kwrd"&gt;int&lt;/span&gt; Count&amp;lt;TSource&amp;gt;();
    }
}&lt;/pre&gt;&lt;p&gt;The implementation for Enumerable.Count could then look like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Count&amp;lt;TSource&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; source)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (source == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;throw&lt;/span&gt; Error.ArgumentNull(&lt;span class="str"&gt;"source"&lt;/span&gt;);
&lt;/pre&gt;&lt;pre class="csharpcode"&gt;            var countable = source &lt;span class="kwrd"&gt;as&lt;/span&gt; ICountable&amp;lt;TSource&amp;gt;;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (countable != &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="kwrd"&gt;return&lt;/span&gt; countable.Count();

            &lt;span class="rem"&gt;// business as usual...&lt;/span&gt;
        }
&lt;/pre&gt;&lt;p&gt;A system like this would also allow a data container to “opt-out” of a particular operation by immediately throwing an exception. For example, suppose that you wrapped IEnumerable around some kind of stream. You wouldn’t want someone to try to “Count” that, would you?&lt;/p&gt;&lt;p&gt;Ideally, there would be a way to only partly implement an interface and otherwise fall back to the default LINQ implementation, but it would be hard to avoid a “stack overflow” scenario without making it much more complicated (or perhaps I’m missing something obvious).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-8860687618806210831?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/8860687618806210831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=8860687618806210831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/8860687618806210831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/8860687618806210831'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/overriding-linq.html' title='Overriding LINQ'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-922226483251466271</id><published>2008-12-06T18:48:00.001-05:00</published><updated>2008-12-06T18:48:49.133-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>How about some syntactic sugar for IEnumerable&lt;&gt;?</title><content type='html'>&lt;p&gt;Recently, my attitude has changed a bit toward IEnumerable&amp;lt;&amp;gt;. It has always served a very good purpose (foreach is so nice), but it has seemed to me to be an interesting, but mostly hidden implementation detail of the framework. And then there was LINQ.&lt;/p&gt;  &lt;p&gt;LINQ is a ton of functionality built around that simple little interface. Which makes me think about using it, exposing it directly in my own API. Why would I choose to expose IEnumerable&amp;lt;&amp;gt;, instead of IList&amp;lt;&amp;gt; or something else? First of all, what other interface is there for exposing a &lt;em&gt;read-only&lt;/em&gt; set of “things”? Second, I adhere to the philosophy APIs should expose only the necessary functionality and no more, because:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It makes it easier to understand how to use the API (and how &lt;strong&gt;not &lt;/strong&gt;to use it). &lt;/li&gt;    &lt;li&gt;It makes it easier to change or completely re-implement the original API. &lt;/li&gt;    &lt;li&gt;The less you can do, the less there is to go wrong. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Of course, IEnumerable&amp;lt;&amp;gt; may be useful, but it certainly isn’t pretty. Instead of IEnumerable&amp;lt;Foo&amp;gt;, I would rather see Foo* or Foo+ or…well, you get the idea.&lt;/p&gt;  &lt;p&gt;This is not a new idea (I’m sorry, but you probably won’t find those on this blog). There is, of course, Foo?, which means Nullable&amp;lt;Foo&amp;gt;. And then there is the experimental language &lt;a target="_blank" href="http://research.microsoft.com/Comega/"&gt;Cω&lt;/a&gt; (thank you, cut-and-paste), which proves how unoriginal this idea is: In Cω, Foo* is a “stream” of Foo. According to the Cω &lt;a target="_blank" href="http://research.microsoft.com/Comega/doc/comega_whatis.htm"&gt;Overview&lt;/a&gt;, “Streams in Cω are closely related to &lt;code&gt;IEnumerable&amp;lt;&amp;gt;&lt;/code&gt;…”. Well, who’s going to argue with the brains inside MS Research? Not me!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-922226483251466271?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/922226483251466271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=922226483251466271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/922226483251466271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/922226483251466271'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/how-about-some-syntactic-sugar-for.html' title='How about some syntactic sugar for IEnumerable&amp;lt;&amp;gt;?'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-4791769843055345744</id><published>2008-12-05T12:05:00.002-05:00</published><updated>2008-12-05T12:06:20.344-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Why LINQ is better than SQL (Part 1?)</title><content type='html'>&lt;p&gt;To be very honest, LINQ warms the cockles of my heart. The mere fact that I can write a compiler-checked query in C# that references my C# entity class and that query, through some magic incantations, gets executed as a SQL statement against my database...it makes me happy.&lt;/p&gt;&lt;p&gt;But maybe you're more pragmatic than I am. Maybe you think all this LINQ hoo-ha is pure sophistry. Take my word for it, I could go on and on about the wonders of LINQ, but then "I don't have time for this" do I?..Well, maybe one tiny example (since you asked so nicely):&lt;/p&gt;&lt;pre&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; r = (
        &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; e &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; context.Employee
        &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; e.Manager.Contact.LastName == &lt;span style="color:#800000;"&gt;"Word"&lt;/span&gt;
        &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; { e.Contact.FirstName, e.Contact.LastName });&lt;/pre&gt;&lt;p&gt;What's the big deal? This query traverses four logical tables. I didn't have to specify how those tables get joined together. Maybe this is kind of obvious, but it surprises me that standard SQL does not have a similar capability. Databases have these things called foreign keys that formalize the relationship between tables. That being the case, why do I have to spell out the relationship between every table in every query.&lt;/p&gt;&lt;p&gt;Don't get me wrong, I love SQL joins. Like the other day, when I needed to identify value gaps in a set of rows. Once upon a time, I probably would've resorted to some process involving cursors, but a simple self-join does the trick. The problem is that the chance to do something "clever" with a join doesn't come up very often. Most of the time (for me, at least), a join is identical to the relationship defined by a foreign key.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-4791769843055345744?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/4791769843055345744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=4791769843055345744' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4791769843055345744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4791769843055345744'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/why-linq-is-better-than-sql-part-1.html' title='Why LINQ is better than SQL (Part 1?)'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-4887448895009123238</id><published>2008-12-04T09:11:00.001-05:00</published><updated>2008-12-04T18:42:34.302-05:00</updated><title type='text'>Obligatory Introduction Post</title><content type='html'>Hello Blog World.

My name is Daniel. I live in Eastern Maine with my beautiful wife and four affable children. My passion and profession is software development. Presently, I am employed as a Software Architect with Tyler Technologies.

I heard about this "blog" thing (invented by some guy by the name of Dave Winer, I think) and I had to give it a go. Wish me luck, my imaginary audience!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-4887448895009123238?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/4887448895009123238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=4887448895009123238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4887448895009123238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/4887448895009123238'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/obligatory-introduction-post.html' title='Obligatory Introduction Post'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-3333711302122724017</id><published>2008-12-04T18:38:00.001-05:00</published><updated>2008-12-04T18:38:51.224-05:00</updated><title type='text'>Visual Studio Team System 2008 Database Edition GDR - RTM</title><content type='html'>&lt;p&gt;Last week, Visual Studio Team System 2008 Database Edition GDR was released to the developer public. I haven't had a lot of time to evaluate it, but my initial impression is positive.&lt;/p&gt;  &lt;p&gt;Of course, I had similar feelings about the VSTS 2005 edition of &amp;quot;Data Dude&amp;quot;, but my initial excitement quickly turned to disappointment when I realized it just wasn't going to work for us. I couldn't really blame the product...let's just say our db schema is rather sadistic. The SQL parser didn't stand a chance and died in a flurry of spurious error messages.&lt;/p&gt;  &lt;p&gt;The parser in the new version is obviously much improved. Once I got the projects/references set up, I was only left with a manageable number of legitimate errors. On top of that, they've managed to remove the dependency on the &amp;quot;Design DB&amp;quot;, which makes the product feel a lot less cumbersome. Add to that a lot of other compelling improvements (including basic code analysis and refactoring tools), and I'm a happy customer.&lt;/p&gt;  &lt;p&gt;I can't say that all is roses, yet. When I attempt to &amp;quot;deploy&amp;quot; my changes, targeting the original database, the generated script file is blank. The deployment process generates a ton of warnings, but no errors. Curiously, if I instead do a &amp;quot;schema compare&amp;quot; between the project and the aforementioned database, it works.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/gertd/archive/2008/11/25/visual-studio-team-system-2008-database-edition-gdr-rtm.aspx"&gt;Data Dude : Visual Studio Team System 2008 Database Edition GDR - RTM&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-3333711302122724017?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/3333711302122724017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=3333711302122724017' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/3333711302122724017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/3333711302122724017'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/visual-studio-team-system-2008-database.html' title='Visual Studio Team System 2008 Database Edition GDR - RTM'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-464390995524552962.post-5861553313225004876</id><published>2008-12-04T15:03:00.001-05:00</published><updated>2008-12-04T15:03:02.119-05:00</updated><title type='text'>January '09 BAND Gig</title><content type='html'>&lt;p&gt;I've agreed to be the presenter for the January '09 BAND (Bangor Area .NET Developers) gig. I'm not exactly sure what day it is (hopefully I'll show up), but I do know the topic: Microsoft's Entity Framework (EF). Here's the blurb I came up with to describe the talk (for the &lt;a href="http://www.bangordevelopers.com/"&gt;BAND site&lt;/a&gt;):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Using entity classes has many advantages over more generic data access methods. On the other hand, entity classes can be time-consuming and surprisingly difficult to implement correctly. In this talk, Daniel will show how Microsoft's new Entity Framework does the heavy lifting to make entity data access simple and powerful.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I'm not sure I'll ever get used to referring to myself in the third person.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/464390995524552962-5861553313225004876?l=www.danielgpratt.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.danielgpratt.com/feeds/5861553313225004876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=464390995524552962&amp;postID=5861553313225004876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/5861553313225004876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/464390995524552962/posts/default/5861553313225004876'/><link rel='alternate' type='text/html' href='http://www.danielgpratt.com/2008/12/january-band-gig.html' title='January &amp;#39;09 BAND Gig'/><author><name>Daniel Pratt</name><uri>http://www.blogger.com/profile/09623273077660656625</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='02050361312701776415'/></author><thr:total>0</thr:total></entry></feed>