tag:blogger.com,1999:blog-69283258420957183212024-02-19T04:04:35.240-05:00IFormattableThoughts, experiments, and opinions of a software developer... chronicling my journey in technology.testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comBlogger130125tag:blogger.com,1999:blog-6928325842095718321.post-60067649602173423152013-01-31T00:04:00.000-05:002013-01-31T00:04:13.395-05:00bash versus PowershellOccasionally, I find myself dumbfounded at how difficult something is in Powershell that is just brain-dead simple in bash. Then, I remember that the various Unix shell flavors and their POSIX toolset have had many more years to mature than even I have had thus far. The Unix shell tool philosophy is "do one thing and do it well". Doing things well in this context is certainly enabling the most common usage scenarios with minimum ceremony and surprise.<br />
<br />
So, let's say you wanted a one-liner that gave the number of lines in a bunch of C# files:<br />
<span style="font-family: Courier New, Courier, monospace;">find -name *.cs | xargs wc -l</span><br />
<br />
Now, let's see how to get the equivalent output from Powershell:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">gci -filter *.cs -Recurse | </span><br />
<span style="font-family: Courier New, Courier, monospace;">select @{Name="Lines";Expression={(gc $_.FullName | </span><span style="font-family: 'Courier New', Courier, monospace;">measure).Count }}, @{Name="Path";Expression={ resolve-path $_.FullName -Relative }} | </span><br />
<span style="font-family: 'Courier New', Courier, monospace;">sort Lines | </span><br />
<span style="font-family: 'Courier New', Courier, monospace;">ft -HideTableHeaders -Auto</span><br />
<br />
Believe it or not, that is all one line. Of course, wc also gave us a summary row in its output, and we can get that with Powershell, too.<br />
<span style="font-family: Courier New, Courier, monospace;">gci -Filter *.cs -Recurse | % {gc $_.FullName | measure } | measure Count -Sum | select -expand Sum</span><br />
<br />
Now we have a two-liner and tired fingers!<br />
<br />
To be fair I am not playing to Powershell's strengths, i.e. .NET accessibility, structured scripting, object pipelining, and a wonderful extensibility story. With Powershell you won't need the analog of Perl, sed, and awk when the built-in shell functions reveal their limitations.<br />
<br />
In fact our Powershell script is a lot more impressive in one respect than its competition; it allowed me to cobble together a "light" version of <span style="font-family: Courier New, Courier, monospace;">wc</span>. I was nearly able to duplicate its output. If the roles were reversed, one could almost certainly contrive some Powershell I/O that would make bash look like the verbose, stilted challenger.<br />
<br />
So, which shell wins? There's certainly a lot to be said for bash (and most Unix shells); it's power, succinctness, and ubiquity have been honed over more than 30 years. At the end of the day, I'm grateful for the Github for Windows release of a shell that incorporates Powershell and the POSIX tools, so I don't have to choose.<br />
<br />
Recommended: <a href="http://damienkatz.net/2013/01/follow_up_to_the_unreasonable.html" target="_blank">The Unreasonable Effectiveness of C</a><br />
<br />
testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-87954458237341316072012-08-19T12:39:00.001-04:002012-08-19T12:39:27.034-04:00What Works on the WebI can't find the quote, but I remember reading around the time of the dotcom bubble a secondhand quote from a Japanese business executive--paraphrasing here--that the only things that make money on the Internet are sex and gambling. He was wrong; advertising is very profitable.<br />
<br />
It's ironic that in the height of the dotcom era, if you had a business plan with a monetization strategy of selling ads, you were often quickly dismissed. Witness the latter day success of Google and Facebook. I bought a Google beanbag, before they invented Ad Words, because I so desperately needed their product. Monetization is emergent from network effects.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://romain.vuillemot.net/wp-content/uploads/2011/12/Chrome-Pouf.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://romain.vuillemot.net/wp-content/uploads/2011/12/Chrome-Pouf.jpg" width="240" /></a></div>
<br />
<br />
Back when collegiate Internet stalking (aka The Facebook) was first blowing up, I started thinking about the Internet resources I found indispensable in my brief college career. In the mid-90s, before Napster/Limewire/Kazaa/torrents, if you wanted free music downloads, you fired up an IRC client, joined #mp3 or #mp3central on Freenode or EFNet, and the friendly bots there would DCC you a list of the mp3 files their owner's had made available. With patience you could find just about anything you'd want to play at a party.<br />
<br />
While I was partying, my roommates were studying and doing homework. Some of the grad student TAs had setup class websites with Java applet chat rooms. Other studious individuals would share their answers--and more importantly--how they came to those answers. These chat rooms were busiest the night before homework was due.<br />
<br />
You see, the Internet has always been social. Anyone wanting to get anything done has always needed other people: tutor, muse, compatriot, nemesis, partner, friend. At the core of every human interaction is a give and take, a transaction of time or attention prosaically, but in a more important sense, a transaction of an intangible but indelible part of our selves--the currency that makes us human: ego-boo, whuffie, brownie points, karma, influence, power, etc.<br />
<br />
If you want to start a company that exists primarily on the web, you'll be engaged in a kind of arbitrage of this human currency. You must understand your particular arbitrage strategy and be able to articulate it. This allows you to focus on those features of your service(s) that provide the best leverage and/or growth.<br />
<br />
What works on the web? Making people useful to each other.testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-10265970108393264262012-07-29T14:56:00.000-04:002012-07-29T14:56:11.008-04:00Can Github Save Your Life?<br />
<div class="p1">
As of late I've had a renewed interest open-source medicine, specifically evidence-based medicine. My exposure while at <a href="http://www.zynxhealth.com/">Zynx Health</a> and a talk given on <a href="http://www.open-emr.org/">OpenEMR</a> is what engendered the interest, and it was recently rekindled by these articles: <a href="http://7fff.com/2012/07/14/the-most-important-social-network-github/">The Most Important Social Network: GitHub</a> and <a href="https://github.com/blog/1124-how-we-use-pull-requests-to-build-github">How we use Pull Requests to build GitHub</a>.</div>
<div class="p2">
<br /></div>
<div class="p1">
Briefly, the correlation there is that Github is a language-agnostic content management system, with strong versioning and collaboration capabilities. In evidence-based medicine, treatment and diagnostic decisions are based on rigorous statistical analysis of outcomes. In reality, though, physicians are, like the rest of us, <a href="http://www.amazon.com/Innumeracy-Mathematical-Illiteracy-Its-Consequences/">innumerate</a> and busy. (cf. <a href="http://www.ncbi.nlm.nih.gov/pubmed/22393129">Do physicians understand cancer screening statistics...</a>). Therefore it is incumbent in practicing evidence-based medicine to distill the research and analysis into <a href="http://en.wikipedia.org/wiki/Clinical_pathway">clinical pathways</a> that can be employed at the point of care. Github could be used to author those clinical pathways.</div>
<div class="p1">
<br /></div>
<div class="p1">
In fact, git as a distributed, <b>decentralized</b>, collaborative, open, <b>secure</b> content management system is ideally suited for this task, when leveraged by the powerful <b>collaboration</b> features offered by Github. On Github everyday the foremost experts in their field, collaborating from nearly every country on Earth, produce tools that they go on to employ in their work. The value of this activity then filters down to the rest of the practitioners through third-party systems.</div>
<div class="p1">
<br /></div>
<div class="p1">
I'm describing software, but I could be describing evidence-based medicine. </div>
<div class="p1">
<br /></div>
<blockquote class="tr_bq">
Evidence based medicine is the conscientious, explicit, and judicious use of current best evidence in making decisions about the care of individual patients. The practice of evidence based medicine means integrating individual clinical expertise with the best available external clinical evidence from systematic research. <a href="http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2349778/pdf/bmj00524-0009.pdf">Evidence-based Medicine[...]</a></blockquote>
<div class="p1">
<br /></div>
<div class="p1">
In a world where the clinical pathways were created by the foremost experts in their field and made readily available to medical professionals in the field: we make <a href="http://ianeslick.com/physician-replacement-therapy">all practitioners more effective</a>; we get lower costs and better outcomes; we can afford to save lives. </div>
<div class="p1">
<br /></div>
<div class="p1">
Open-source clinical pathways would provide grist for the mill of healthcare innovation. Entrepreneurs would create mobile applications that combine location, biometric, and symptom data to suggest diagnostics and treatments with high specificity. Like the Linux kernel, clinicians could use "builds" from a distributed trust model, where updates to clinical pathways were controlled through the kind of real-world trust and control models that are in place to <a href="http://en.wikipedia.org/wiki/Thalidomide#Birth_defects">keep us safe</a>.</div>
<div class="p1">
<br /></div>
<div class="p1">
What is needed is programming ecosystem for clinical pathways. I mean that literally. We need a "byte code" (portability standard), languages, compilers, linkers, theorem provers, IDEs, package managers, etc. We need all of this to create a <a href="http://www.catb.org/esr/writings/homesteading/cathedral-bazaar/">bazaar</a> of healthcare innovations, and we need it soon.</div>
<div class="p1">
<br /></div>
<div class="p1">
Your life may depend on it.</div>
<div class="p1">
<br /></div>
<div class="p1">
<br /></div>
<div class="p1">
<br /></div>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-70399838054029720512012-06-14T11:45:00.001-04:002012-06-14T12:56:19.332-04:00Learning French in a Hurry: Some iPhone Hacks to Try<p>My best friend and I—that is, my wife and I—are headed to Paris this Fall. Unfortunately, <em>no parlez français</em>. There's this awful rumor (okay, myriad anecdotes) going around that the French are a bit jingoistic, or, perhaps more fairly, intolerant of those who don't bother to learn any French at all before visiting the country, particularly of those Americans who simply expect everyone to speak English in pursuit of the (no-longer-almighty) American Dollar.</p>
<p>Think what you will of this attitude or the veracity of it's justification; it's their country. When in Paris...</p>
<p>So what is the busy American with about three months to learn French for a trip to Paris to do? First, and above all else, know that <a href="http://www.youtube.com/watch?v=qMz3gjl9x-M">only a genius with can learn a language this quickly</a>, so suck it up, be humble when you go, and do your best. Here are some hacks that we are trying out.</p>
<dl>
<dt>Change your iPhone language<dt>
<dd>You are surely extremely familiar with navigating your iPhone. Plus, the icons make it incredibly easy to find the app your looking for, despite it's caption. Changing the language your iPhone uses exposes you to French words and phrases as often as you check your phone. Since you already know what most of their counterparts are when the phone is using English, you'll surely pick up some new vocabulary and keep it. Immersion is the key to quick language acquisition.</dd>
<dt>Enable VoiceOver on your iPhone</dt>
<dd>Reading words is one thing, but it's hardly sufficient. You need to hear and speak them to improve retention and to make practical use of them. This is where the accessibility features of the iPhone come into play. Turn on VoiceOver to have all of the menu items, titles, button, etc. spoken by a clear French accent. Adjust the slider controlling how quickly the words are spoken to a rate your comfortable with interpreting—probably a slow as possible. Finally (and this is important), make sure you set the <em>Triple-click Home</em> feature to toggle VoiceOver. This is the most convenient way to silence the new Frenchman in your phone, but with VoiceOver on it is nearly impossible to do any texting.</dd>
<dt>Text message to your language buddy exclusively in French</dt>
<dd>My wife and I are using Google Translate in concert with iMessage for all of our text messaging. Here's the pattern:
<ul>
<li>Type your English in Google Translate</li>
<li>Listen to Google's French translation</li>
<li><strong>Important!</strong> <em>Manually type</em> the translation into iMessage. You could copy/paste if you are in a huge hurry, but this is where you will practice writing and recall of spelling.</li>
<li>Copy/paste your interlocutor's response into Google Translate and get the English translation. Yes, do this first; you need to know what the words mean before hearing or writing them.</li>
<li>Back in iMessage now, use Triple-click Home to enable VoiceOver. Select the response you just translated to English and listen to it a couple of times, repeating it time. Turn VoiceOver off before repeating these steps.</li>
</ul>
</dd>
<dt>News in Slow French</dt>
<dd>This <a href="http://itunes.apple.com/us/podcast/french-podcast/id427774337">podcast is available for free in iTunes</a>. As a beginner you won't understand much, but it is delivered in a way that is both entertaining and accessible with a didactic slant that sometimes makes it seem a little silly. Remember, immersion is key.</dd>
<dt>Create a French Radio Station for the Pandora app</dt>
<dd>We've had decent luck with Carla Bruni (thanks to this <a href="http://answers.yahoo.com/question/index?qid=20090106141415AAQp1k8">Yahoo! answer</a>). The real trick is to cull all of the non-French songs that come up using the thumbs-down button. Give it some time and you should get a pretty good stream of French language music.</dd>
<dt>
<dt>Put Google Translate on your Home Screen</dt>
<dd>This one almost goes without saying, but the <em>Add to Home Screen</em> feature of Safari is under-utilized in my opinion. Quick access to a standalone view of the Google Translate web app will save you a lot of time and frustration in employing these hacks.</dd>
<dt>Jibbigo</dt>
<dd><p>Don't expect miracles here, but when all else fails this app could save you. Jibbigo interprets speech and <em>translates</em> <strong>bi-directionally</strong>! This means you can speak in English and hear a French translation, and vice versa. The important distinction between this app and Google Translate is that it works offline.</p>
<p>There are two major drawbacks to this app that demand comment. First, it is really, really slow. Painfully. I'm using the iPhone 4, not the faster 4S, but I suspect it will still be awkward to use this in conversation, so don't rely on it. Second, the French speech-to-text function seems unreliable. As I don't speak French, I played Google Translate audio to the phone and got pretty bad results. Not bad for a universal translator, just imperfect enough to frustrate conversation. There is an option to type the words you want translated, so a patient interlocutor can succeed.</p>
<p>Besides an emergency translation, this app is useful in learning French when Google Translate is unavailable for any reason.</p>
</dd>
<dt>Pimsleur on your commute and in the gym</dt>
<dd>Get the Pimsleur French audio lessons into your iTunes and listen to them on your commute and at the gym. You really need to repeat these lessons, so I suggest doing a new lesson at the gym, or your commute home, whichever is first. Then listen to that same lesson on your morning commute. The sleep between these two periods will help things stick. If you are not sure about your commitment level, buy <a href="http://www.amazon.com/gp/product/0743550420/ref=as_li_ss_tl?ie=UTF8&tag=iforma-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0743550420">French, Conversational: Learn to Speak and Understand French with Pimsleur Language Programs (Pimsleur Instant Conversation)</a><img src="http://www.assoc-amazon.com/e/ir?t=iforma-20&l=as2&o=1&a=0743550420" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />. Otherwise, get <a href="http://www.amazon.com/gp/product/0743518349/ref=as_li_ss_tl?ie=UTF8&tag=iforma-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0743518349">French I, Comprehensive: Learn to Speak and Understand French with Pimsleur Language Programs</a><img src="http://www.assoc-amazon.com/e/ir?t=iforma-20&l=as2&o=1&a=0743518349" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, since there is a big overlap between the two products.
</dd>
</dl>
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=iforma-20&o=1&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0743550420" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=iforma-20&o=1&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0743518349" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>
<p>Those are the hacks we've come up with so far. Do you have a language learning hack for the iPhone?</p>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-29542652634394200842012-06-05T08:24:00.002-04:002012-06-05T09:03:09.669-04:00Web Performance: Measure the Right ThingBy attempting to improve your site's page performance, you can actually make it slower. There are numerous well developed techniques to improve the performance of your web sites and applications. Steve Souders and others have put together some best practices to improve your page performance, and companies like blaze.io have put together turn-key solutions to implement these practices. With these and other ingenious tools that help measure page performance, you'd think implementing a program to improve page performance would be straightforward, but you would be wrong.<br />
<div>
<br /></div>
<div>
Performance improvement is an optimization game, and optimization is the act of maximizing (or minimizing) some measurable quantity. The conventional wisdom for page performance holds that the time from first byte until window's load event is fired (i.e. time-to-onload, or TTO) by the browser is the best quantity to optimize, as it roughly approximates the wait until the page is interactive. While this seems like the worthwhile goal, it isn't; many of the techniques used to optimize TTO have deleterious effects on the user experience, including making perceived performance much slower.</div>
<div>
<br /></div>
<div>
Consider the practice of deferring the loading of various JavaScript files until TTO. This generally has a very positive effect on TTO, but can have potentially negative effects. At a former client, a major airline, developers and management became fixated on TTO (as measured internally and by a third party). The result was that the page would fully render in under a second on average, but some customers would be unable to use the flight search widget properly for twenty seconds or more.</div>
<div>
<br /></div>
<div>
In a somewhat common scenario, the HTML corpus of the page would download, along with the major images assets (hero shot and sprites), and the page would render completely above the fold. The deferred load and execution of the various JavaScript assets would then commence. Unfortunately, the assets that powered the flight search widget would sometimes take an inordinate amount of time to download, resulting in a much diminished, if not jolting, user experience.</div>
<div>
<br /></div>
<div>
The solution is simple; the prescriptive guidance from Souders and others is to put these assets, those that spark the interactivity of critical features of your pages, inline. Specifically, including the JavaScript for the flight search widget in a script tag at the bottom of the HTML payload would have made the widget interactive in a timely manner. By optimizing the wrong quantity, the team made things perceptively worse.</div>
<div>
<br /></div>
<div>
What should have been the optimized quantity? The answer to that question could only come from user-experience thinking. UX is a kind of optimization itself: personas are developed; their goals explored; and the interactions are designed to best help them meet those goals while balancing the personas' agendas against each other. This kind of user-centered exploration of the problem space gives us a tangible quantity to optimize in any given interaction.</div>
<div>
<br /></div>
<div>
In the particular case of an airline's homepage, many agendas begin with searching for a flight; it is clearly the most important interaction. Concordantly, it is the time-to-interactivity of the flight search widget on the homepage that should have been optimized. By prioritizing the interactions on a given screen, we create a ranked list of performance measures that will provide tangible benefits to users of our web sites.</div>
<div>
<br /></div>
<div>
These measures, like time-to-interactivity of the flight search widget, are couched in domain-specific terms. We have to instrument our JavaScript to make them measurable in ways not unlike the DOM onload event. By segmenting traffic and sending instrumentation data back to a beacon, we can monitor and optimize the real experiences of our customers, instead of a browser event.</div>
<div>
<br /></div>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-21293391985796339092012-04-17T16:09:00.002-04:002012-04-17T16:16:03.782-04:00Using Ruby to Download Files in ParallelI've been taking a few of the online classes offered by Stanford, and I wanted to write down for posterity (read: me) the way I grab the files I need from the course download page(s).<br /><code><br />gem install hpricot<br />gem install parallel<br /></code><br /><script src="https://gist.github.com/2408682.js"> </script>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-57802043116038016972012-02-15T10:37:00.002-05:002012-02-15T11:00:13.980-05:00Testing Multiple Versions of IE on any PlatformThe best summary of the available options I've found is the article, <a href="http://coding.smashingmagazine.com/2011/09/02/reliable-cross-browser-testing-part-1-internet-explorer/">"Reliable Cross-Browser Testing, Part 1: Internet Explorer"</a>. The upshot is that if you want to engage in the article titular activity, you'll be relying on VMs. Having used the other approaches outlined in the article, including Multiple IEs, I have to concur with this conclusion and aver that it is ultimately the only approach that provides the flexibility you'll need when you you need to debug some odd CSS or JavaScript behavior in IE6 with some odd configuration.<div><br /></div><div>So, the real trick is minimizing the pain of getting this setup. If you are running on Linux or Mac OSX, you'll be happy to find out that you're a <a href="https://github.com/xdissent/ievms">shell script</a> away (almost). This script uses Oracle's Virtual Box to operate the VPC images. It is ironic that this is the only way that Windows 7 Home/Home Premium users can use these images, since Virtual PC and the XP Mode feature are not available without the Pro or Ultimate SKUs.*</div><div><br /></div><div>Once you've got the IE App Compat images downloaded, you'll likely find they have a couple little problems: BSOD on boot and Windows activation; you'll find the solution to those problems in this <a href="http://blog.ertesvag.no/post/5794727557">blog article</a>. </div><div><br /></div><div>* As an aside, how long do you think Microsoft will continue this multiple SKUs? An OSX Lion upgrade is $30--for new VERSION! It doesn't matter, I suppose, given that most folks think Windows 8 will be <a href="http://www.zdnet.com/blog/open-source/five-reasons-why-windows-8-will-be-dead-on-arrival/10275">DOA</a>.</div>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-24691737316588275052012-01-29T12:04:00.004-05:002012-01-29T12:26:37.824-05:00Evernote Watched Folder on Mac Snow Leopard<p>Maybe you're a PC going Mac, or just a Mac looking to save a few clicks, but in either case you could reasonably expect this PC-only feature of Evernote to be available on Snow Leopard: watched folders. Basically, this ensures that most documents put into a particular folder find their way into a new note in Evernote. This is useful is you want to save PDFs, for example, that are not clipped in the way standard HTML pages are when using the Evernote Web Clipper plug-in for your favorite browser.</p><br /><br /><p>To add this feature to Evernote, we can use it's AppleScript interface through a Folder Action we will create in Automator.</p><br /><ol><br /> <li>Start Automator</li><br /> <li>Create a new Folder Action</li><br /> <li>Select the folder you want</li><br /> <li>Add a Run AppleScript task to the workflow</li><br /> <li>Add the following code to the task:<br /> <code><br />on run {input}<br /> tell application "Evernote"<br /> repeat with x in input<br /> try<br /> create note from file x notebook "Auto Import"<br /> on error error_message number error_number<br /> display alert "Send to Evernote Failed" message "Error: " & error_message & " " & "Error Number: " & error_number as warning<br /> end try<br /> end repeat<br /> end tell<br />end run<br /></code><br /> </li><br /> <li>Save it (File->Save a version)</li><br /> <li>Navigate to the folder in finder and ensure that there is a folder action assigned</li><br /> <li>Add a Notebook to Evernote called "Auto Import"; this step is optional, but you must remove the 'notebook "Auto Import"' from the code. If you do remove it, the note will be added to your default notebook.</li><br /> <li>Save files to the folder</li><br /></ol>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-60456206002266983462011-07-27T00:34:00.004-04:002011-07-27T01:02:33.009-04:00How Agile Makes You Dumb (or Smart)<p>While many of the thought leaders in the Agile community decry the inexorable march toward banal, brand-oriented adoption, entreating us to internalize the principles of Agile and not blindly follow prescriptive practices, proscribing such phrases as “being agile” or “doing agile”, there remains an elusiveness to what makes Agile work. We’ve heard the stories: high-functioning teams churning through a product backlog, steadily delivering week after week. Nothing impedes these paragons of Agile values, while the rest of us struggle.</p><br /><p>The picture looks quite different for most Agile teams: stories are estimated inaccurately; pair performance varies widely; velocity suffers at the mercy of technical debt; knowledge silos emerge; defect cycles lengthen; customers start getting frustrated. Very soon managers start trying to identify problems with the process, invariably looking for their keys under the lamplight instead of where they dropped them—looking for problems they can solve instead of solving the problems.</p><p>One cold Chicago winter night, Robert C. Martin, “Uncle Bob”, related a tale wherein a company engaged in the adoption of Scrum saw a very promising early spike in velocity followed by decline. They brought in Ken Schwaber, looking for the problems in their Agile practices and methodologies. With some tweaking they saw another bump in velocity but were too soon again swimming upstream. The Scrum Master himself next recommended they bring in Uncle Bob. They had done all the Agile stuff right—everything but the engineering.</p><br /><p>As Uncle Bob relates the tale, Extreme Programming (XP) neatly codified the marriage of what we now call Agile with fundamental, essential software engineering principles and techniques. Unfortunately, most managers have very little aptitude for or mastery of the engineering, and naturally focus on those things they perceive they can directly impact. Consequently, the Agile aspects got top billing, and the engineering relegated to understudy. The unequivocal result is underperforming teams and projects. Agile made them dumb.</p><br /><p>“Whoa! What about those teams who are delivering,” I hear you ask! Those fabled unicorns of the software industry where every iteration delivers substantial business value and change is accommodated like an accidental in a Kind of Blue reprise… surely they’ve got the system right. Or, maybe it isn’t the system at all. That’s the pretext of the Agile guru’s foreboding about “doing Agile”—there is no system, no prescription… There’s just really smart, wise, motivated people working together effectively.</p><br /><p>Organizations are driven to Agile practices for a number of reasons, but few managers would suggest that Agile makes their teams smarter. But that is truly the secret sauce of what makes so-called Agile teams successful. They have a high collective intelligence. As a group they can overcome a great many obstacles and continue performing at a high level. They create fewer problems for themselves and deal swiftly and precisely with the problems they don’t create. They work.</p><p>Recent research into high-performing teams—those with a high collective intelligence—shows two distinct and surprising facts. First, individual intelligence is only weakly correlated with team performance. Second, there is a strong positive correlation with the number of women on the team and team performance. Women make teams smarter than men. Full Stop.</p><br /><p>Why? Those of us with a Y-chromosome will be relieved to know that there is a similar correlation with social sensitivity and team performance. Women generally rate significantly better at social sensitivity than men. The researcher states, "what it suggests is that if you don't know the social sensitivity of a group, it is a better bet to include females than not." "The team also found that groups in which members took turns speaking were more collectively intelligent." (New Scientist)</p><br /><p>In most enterprises, groups develop software. The engineering aspects of software development are extremely difficult and require a great deal of intelligence. It stands to reason the groups with high emotional intelligence are better at developing software than not. A bunch of hotshots don’t make for a smart group. So how would we go about maximizing the collective intelligence of development team?</p><br /><p>“…took turns speaking…” Sound familiar? Stand-ups and pair programming, when effectively fostered, should result in an effective increase in the social sensitivity of the individuals on the team. The corollary is that teams that are good at stand-ups and pairing are better at delivering software. Agile makes them smarter.</p><br /><p>Managers should be cogitating on ways to increase the social sensitivity of their developers. To those that can’t break their addiction to quick fixes: fire all the asshole, prima dons and use the windfall to hire some competent women.</p>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-87634731818038645172011-02-21T14:47:00.003-05:002011-02-21T14:56:40.848-05:00Code qua ArtThe positronic sqrt program in rod logic is art. Damian Conway, Thoughtstream: "<a href="http://blip.tv/file/1145545/">Temporally Quaquaversal Virtual Nanomachine Programming In Multiple Topologically Connected Quantum-Relativistic Parallel Timespaces...Made Easy!</a>"<br /><br />The <a href="http://mamememo.blogspot.com/2010/09/qlobe.html">Qlobe</a> is art.testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-70919053643322664672010-09-06T15:33:00.007-04:002010-09-08T19:20:48.806-04:00Real Software Engineering & The Agile Value Graph<div>Glen Vanderburg (@glv) recently reprised his talk "Real Software Engineering" as a keynote at Ruby Hoedown 2010. In the words of Jim Weirich "every software developer should hear this"... Motivated to see what all the buzz was about, I watched the recording of the same talk from earlier this year (<a href="http://j.mp/9dqw9Q">http://j.mp/9dqw9Q</a>). The thesis is simple--Agile IS the state of the art in Software Engineering, not some sort of anti-engineering, or accidental engineering.</div><div><br /></div><div>This, of course, is not news to most practioners, but his approach to defending this thesis is pretty novel, I think. He begins by quoting a paper from the proceedings of a NATO computing conference in 1969:</div><div>"A software system can best be designed if the testing is interlaced with the designing instead of being used after the design."</div><div><br /></div><div>Pretty compelling huh?</div><div><br /></div><div>He then frames the inception and growth of the Waterfall methodology as stemming from two errors: 1) the misinterpretation of a 1970 paper by Dr. Winston Royce by Pointy-Haired Bosses (a la <a href="http://www.paulgraham.com/icad.html">http://www.paulgraham.com/icad.html</a>), and 2) the Barry Boehm "cost of errors" graph had a hidden bias in that only Waterfall projects were measured.</div><div><br /></div><div>I hope you are interested enough to check out the talk. I couldn't do it justice here. And you will find he draws several other valuable conclusions. Personally, I was compelled to read another of Vanderburg's papers referenced at the end of this talk, "Extreme Programming Annealed" (<a href="http://vanderburg.org/Writing/xpannealed.pdf">http://vanderburg.org/Writing/xpannealed.pdf</a>), published in ACM SIGPLAN proceedings 2005.</div><div><br /></div><div>In this paper he attempts an exposition of the coupling between the 12 (+1) XP practices to understand how to cope with a situation where one of the practices is disallowed. I won't recapitulate that work here, but he did present an interesting arrangement of the practices in relation to time. To me there was an immediate correlation between the cost of errors graph and this arrangement.</div><div><br /></div><div>As providence would have it, I had recently been thinking about visual depictions of the "value" of Agile/XP. The pointy-haired bosses need something simple(-ish) to understand why these Agile practices are important. Ideally, they'd like to see how they affect the bottom-line; everything in business is a trade-off, after all...</div><div><br /></div><div>After a few iterations, I came up with something that I hope Edward Tufte wouldn't snarl at and Kent Beck might nod at approvingly. I present you, the "Value of Agile Methods"</div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY_IxQzNfZJNrKUjRMR9wDqAK2nvw6i3VOTF8FyymW9ByZxXxG_RvID1Byf87hKt0JX9aUwO_r7W4Uy4H5QqaVL4BeUBvvustONu8KtAAAucqxBMzeTaZZOrTSdLBm4_0C0qgunzLu2n0/s1600/AgileValueGraph.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 272px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY_IxQzNfZJNrKUjRMR9wDqAK2nvw6i3VOTF8FyymW9ByZxXxG_RvID1Byf87hKt0JX9aUwO_r7W4Uy4H5QqaVL4BeUBvvustONu8KtAAAucqxBMzeTaZZOrTSdLBm4_0C0qgunzLu2n0/s400/AgileValueGraph.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5514686494084435906" /></a><br /><br /><div>Some notes:<br /><ul><br /><li>P(Error) is the probability of introducing an error. I make the facile assumption that there is a linear relationship between the frequency with which an activity is performed and the frequency of errors introduced by that activity.</li><br /><li>P(Error<sub>Agile</sub>) is the result of flattening of P(Error) by four particular Agile methods (see downward arrows); in Vanderburg's paper these are called noise-filters</li><br /><li>the "x-axis" is a logarithmic arrangement of time; in the case of the probability of error curves, this is how frequently an activity is performed; in the case of the cost of errors curve, it is the length of an interval between when an error is introduced and when it is discovered</li><br /><li>the groupings of the time axis represent the "epochs" of different practices: engineering (code, test, vet req's etc.); process (define requirements, team meetings, project management, etc.); and strategy (direction set from executives, market research, etc.). There is obviously some overlap and flexibility in what activities correspond to which "epochs"</li><br /></ul><br /></div><br /><h3>Inferences</h3><br /><div>I hope the graph would compel the following inferences:<br /><ul><br /><li>Agile practices reduce the frequency of errors in engineering activities while reducing the time between when an error is introduced and when it is identified in both engineering and process epochs.</li><br /><li>The cumulative effect of these practices is to reduce the probability of errors and limit the overall cost of errors.</li><br /><li>Engineering errors are invariably frequent and cheap to fix when applying Agile practices, in stark contrast to errors in strategic decisions that are both infrequent and very, very expensive.</li><br /></ul><br /></div><br /><h3>Call to Action</h3><br /><div>If you think this graph is interesting, flawed, has potentional, etc. I encourage you to iterate it and share it.<br /><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</div>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-12315750205164597112010-09-04T12:00:00.005-04:002010-09-04T16:33:05.386-04:00Hipster Programming: Coding in F# on Mac OS X<p>The vitriol towards Microsoft has a long and graceless tradition with a lexicon sporting such inventive neologisms as the venerable "M$FT" and the puerile "Total Failure System" in reference to Team Foundation Server (TFS). Oh, how these countless little slights must wound the souls of those folks toiling away under the yoke of stodgy corporate masters! Their inner light having been dimmed and filtered by a soulless, crushing capitalism so much so that they unconsciously embrace their sameness, adopting a uniform of pique polo shirts and khaki pants.</p><br /><p>The iconoclasts, the individualists, the thinkers--these bear the nome d'guerre "Rubyist", "Rails aficionado", "Python hacker", "open source developer". You will know them not by their similarity but their diversity, their vestiture definitively anti-establishment and their mocking of any tool that you don't have to download from github and compile from source.</p><br /><p>As in all things, there is a middle road whose pedestrians are accused of compromise with the Devil by one side and "just trying to be different" on the other. Yet in this camp we find many sagacious, experienced craftspeople who have spent time in both camps. With the reader's indulgence, I shall call them hipster programmers.</p><br /><p>For what its worth, I consider myself a hipster programmer, as evinced by how I spent my morning. Having been developing in .NET for nearly a decade and of recent years drawn strongly to functional programming, I am of course learning F#. But, I'm also experimenting with Erlang, Ruby, and more recently Clojure. As far as platforms go, you've got a lot of choice these days: Windows, Linux, Mac OS X. With Windows you certainly need Cygwin and a git port. Linux is probably the easiest to get going on but lacks some of the day-to-day niceties (e.g. iTunes). Mac OS X can't be (legally) virtualized, so it makes an obvious choice as the base system.</p><br /><p>My work machine is a MacBook Pro running VMWare Fusion. My recent explorations of Clojure have kept my exclusive in the Java tools domain--Maven, Ant, Netbeans, etc., but the Chicago Clojure user group recently invited Dr. David Miller to come talk about clojure-clr, a C# implementation of Clojure for the CLR, very hipster! What could be cooler than that?</p><br /><p>Well, porting clojure-clr to F# of course!</p><br /><p>Sure, I could fire up Fusion and VS 2010 and start rocking, but I like to begin with the end in mind, namely moving seamlessly between writing code in Clojure targetting the CLR and the JVM. I'd like to use similar tool chains. And, I'd like to present to a group of the cool kids in their native tongue.</p><br /><p>The first step is getting an environment setup. Robert Pickering has a <a href="http://strangelights.com/fsharp/MonoLinux.aspx">great article to get Mono setup on Mac OS X</a>. Don't skip the 'sudo install-mono.sh' step. At the time of this writing their is a strange error in his instructions regarding the mono.snk file. The install-mono.sh file makes this pretty clear, so just ignore that part. Basically, you have to give the F# assemblies a proper strong name to add it to the GAC.</p><br /><p>Now, I love vim--it was my first code editor--but the Ruby kids have been using TextMate, so let's use that since someone kindly shared <a href="http://code.google.com/p/fsharp-tmbundle/">an F# bundle</a>. That bundle uses <a href="http://iterm.sourceforge.net/">iTerm</a> to evaluate function in F# interactive, so we'll need that too. Finally, we need to alias "fsi" to run F# interactive using Mono, so the TextMate bundle will run it properly. Edit ~/.profile adding this command.</p><br /><pre><br />alias fsi='mono ~/path/to/fsi.exe'<br /></pre><br /><p>So we've got the beginnings of a build environment going; what's next?<br /><ul><br /><li>Get a branch going on github, referencing the clojure-clr project</li><br /><li>Get a build system stack setup (Maven? Rake?)</li><br /><li>Find an unit testing suite for F#/Mono/Mac OS X</li><br /><li>Start hacking</li><br /></ul><br /></p>testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-45492588131454282872010-08-09T17:16:00.001-04:002010-08-10T10:04:51.415-04:00REST: The Uniform Interface<blockquote> <p>The central feature that distinguishes the REST architectural style from other network based styles is its emphasis on a uniform interface between components. (Fielding’s Dissertation, Sec. 5.1.5)</p> </blockquote> <p>Street RESTers will immediately submit that the uniform interface is simply having a URL that reads: “/controller/method/id”.  While this maps nicely to their server-side MVC application, it does not represent the necessary constraints to satisfy the uniform interface of REST.</p> <p>In the dissertation Fielding defines four interface constraints for REST:</p> <ol> <li>Identification of resources </li> <li>Manipulation of resources through representations </li> <li>Self-descriptive messages </li> <li>Hypermedia as the engine of application state </li> </ol> <p>The benefits realized by the uniform interface are best understood in terms of the effects upon the architecture when applying these constraints.</p> <h2>Identification of Resources</h2> <p>To understand this constraint we must first have a solid definition of a resource.  A resource is some named entity that is provided by our application.  On the web we generally use URLs to name these entities.  The normal notion of a URL is “a link to a web page”.  A URL is a special kind of Uniform Resource Identifier.  REST constrains the URIs we use in a few ways:</p> <ul> <li>The semantics of the mapping of a URI to a resource must not change.  So, while the contents of example.com/Top10 can change over time, the thing that it names—e.g. the top 10 examples of the day—cannot. </li> <li>A resource’s identity is independent of its value. So, two resources could point to the same value at some point in time, but they are not the same resource. </li> <li>The provider of a resource is solely responsible for maintaining the semantic validity of the URI.  This just means that we should choose good URLs that are easy to maintain. </li> <li>A URI should not contain any reference to the media type used to represent the resource; example.com/Top10/json is verboten. </li> </ul> <p>This seems like a simple constraint, and it is, but its significant benefits include:</p> <ul> <li>There is just one way to get at a particular resource. </li> <li>The value of a resource at a point in time (representation) can be served up in any appropriate media type at the time it is requested, based on the characteristics of the request (Accept header). </li> <li>Since the semantics of resource identifiers are static, and the media type of the representation is determined at the time of the request, clients dependent on a resource do not have to change any identifiers in order for the content type to change. </li> </ul> <h2>Manipulation of Resources through Representations</h2> <p>The abstract notion of a resource named by a URI is reified by a representation in a media type selected based upon the nature of the request for that resource.  A representation contains the data and metadata describing the data, such as the media type of the data.  All of the perceived work done by a server in REST architecture is initiated by a client either: a) requesting a resource whereupon the server returns a representation of that resource; b) sending a representation of a resource whereupon the server nominally mutates/creates the resource.</p> <p>There are additional details to the semantics of representation-based interactions, but the salient point is that URLs are not akin to call sites in a program.  These interactions are more akin to message passing.</p> <p>An important and often overlooked consequence of this constraint is that there is no distributed consistency, and so the notion of a “transactional REST” is anathema:</p> <blockquote> <p>REST just says that there is no consistency -- only representations that indicate state at some point in the past and an implicit grant of use for some time into the future. –<a href="http://tech.groups.yahoo.com/group/rest-discuss/message/3593">Fielding on rest-discuss</a></p> </blockquote> <p>Besides decoupling the resource from a particular representation, the benefit to this approach are seen in the application of the next two constraints.</p> <h2>Self-Descriptive Messages</h2> <p>All of the details required to route, interpret, and process a message must be in the message itself.  This enables the communication between components to be stateless and allows messages to be cached appropriately.</p> <blockquote> <p>REST concentrates all of the control state into the representations received in response to interactions. The goal is to improve server scalability by eliminating any need for the server to maintain an awareness of the client state beyond the current request. (dissertation)</p> </blockquote> <h2>Hypermedia as the Engine of Application State</h2> <blockquote> <p>The model application is therefore an engine that moves from one state to the next by examining and choosing from among the alternative state transitions in the current set of representations. (dissertation)</p> </blockquote> <p>This is probably the least applied of the REST constraints, especially with the proliferation of AJAX clients. The core idea is that the representation given to the client will have embedded hyperlinks that completely disambiguate what actions are available to interact with the server.</p> <p>Dr. Fielding wrote an <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">extended exposition of the hypermedia constraint</a> wherein he makes explicit some rules that apply to a RESTful API.  He also says this,</p> <blockquote> <p>A truly RESTful API looks like hypertext. Every addressable unit of information carries an address, either explicitly (e.g., link and id attributes) or implicitly (e.g., derived from the media type definition and representation structure). Query results are represented by a list of links with summary information, not by arrays of object representations (query is not a substitute for identification of resources).</p> </blockquote> <p>Lest you think you can apply REST to your architecture sans this “hypermedia constraint”, Dr. Fielding further clarifies.</p> <blockquote> <p>ROA is supposed to be a kind of design method for RESTful services, apparently, but most folks who use the term are talking about REST without the hypertext constraint. In other words, not RESTful at all. REST without the hypertext constraint is like pipe-and-filter without the pipes: completely useless because it no longer induces any interesting properties. (<a href="http://roy.gbiv.com/untangled/2008/on-software-architecture">blog</a>)</p> </blockquote> <h3>Towards a RESTful Client</h3> <p>Taken together, the constraints that engender the uniform interface of REST-style architecture, in turn force certain characteristics in clients of a RESTful API.  Among these client characteristics are:</p> <ul> <li>Ability to process one or more media types available for a resource’s representation. </li> <li>Ability to maintain and manage state by selecting among hyperlinks. </li> <li>Awareness of potential inconsistency of representations. </li> <li>Only enters the interaction from a known entry point. </li> </ul> <p>If we are building RESTful web applications, we have to supply such a client that can run in a browser.  For example, the user agent can navigate to the URL that identifies the client. This client is assembled in the browser via normal mechanisms for displaying a web page.  The various JavaScript libraries loaded then augment the capabilities of the browser to exhibit the characteristics mentioned above while interacting with the RESTful API on the server.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-28601990536002774082010-07-25T04:34:00.001-04:002010-07-25T04:35:22.399-04:00Dynamic Dispatch (Multimethods) in C#?<p>I’ve recently become enamored with the multimethods system of Clojure, as well as its approach to polymorphism and “type” hierarchies in general.  Having never heard the term, I consulted <a href="http://en.wikipedia.org/wiki/Multimethods">Wikipedia about multimethods</a>, hoping to have its origins elucidated, though it appears it is simply a synonym of multiple dispatch.</p> <p><a href="http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming">Polymorphism</a>, “the ability of one type to appear as and be used like another type”, is limited to inheritance with simple overloading semantics (and generics) in C#.  The ability to be “used as” another type is implemented by allowing subclasses to implement any virtual methods defined on their respective superclasses.  Then, at compile time, the method to be called is determined based on the actual types of the objects upon which the function/method is invoked; we call this compile-time binding or early-binding.</p> <p>Let’s look at it from a more mechanical perspective.  In most OO languages, when we write <em>obj.Foo()</em> we are implicitly writing <em>(Foo obj)</em>.  In other words, <em>obj</em> is the first argument in the invocation of <em>Foo</em>;<em> </em>an argument called <em>this</em> in many languages.  (See JavaScript’s call/apply.) So, in our inheritance example, the compiler looks at the actual type of this first argument <em>obj</em> (the target of the invocation) when determining the <em>Foo</em> to call. This is called single dispatch.</p> <p>What about the other arguments to the function?  Can we vary which function is called based on the other arguments to a method besides the target (i.e. the first implicit argument)?  Well, of course, we can have method overloads that take a different number and/or type of arguments.  However, unlike the first argument, there’s no mechanism in C# to evaluate the the derived types of these other arguments to make a dispatch decision;<strong> there is no multiple dispatch in C#</strong>.</p> <p>This blog article, <a href="http://blogs.msdn.com/b/devdev/archive/2005/08/29/457798.aspx">“The Visitor Pattern and Multiple Dispatch”</a>, usefully explains the problem in terms of the Visitor pattern.  As a means of implementing <a href="http://en.wikipedia.org/wiki/Double_dispatch">double dispatch</a> the Visitor pattern has some shortcomings.  First, the targets must be aware of and receive the visitor, violating the single responsibility principle.  Second, the visitor itself must evaluate the type of the target and invoke the correct method. Though some suggest <a href="http://stackoverflow.com/questions/42587/double-dispatch-in-c/42656#42656">using reflection to invoke the correct method</a>, that implementation, reflecting on the runtime type of the object and using dynamic invocation through the type to get to the right method can be expensive.  </p> <p>We can simplify that approach <a href="http://blogs.msdn.com/b/laurionb/archive/2009/08/13/multimethods-in-c-4-0-with-dynamic.aspx">using the dynamic keyword to effect dynamic dispatch</a>.  Using the <em><a href="http://msdn.microsoft.com/en-us/library/dd264736.aspx">dynamic keyword</a></em> to “box” the arguments to the target method (<em>Foo</em> above), we can let the runtime system do the reflection for us. In the code below, I build on the Visitor example in “The Visitor Pattern and Multiple Dispatch” article, see line 28.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7c614de1-6b00-4851-9ce2-457687c2bbde" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">class</span> <span style="color:#2b91af">Program</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">abstract</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Expression</span> { }</li> <li style="background: #f3f3f3"> </li> <li>    <span style="color:#0000ff">class</span> <span style="color:#2b91af">ConstantExpression</span> : <span style="color:#2b91af">Expression</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> constant;</li> <li style="background: #f3f3f3">    }</li> <li> </li> <li style="background: #f3f3f3">    <span style="color:#0000ff">class</span> <span style="color:#2b91af">SumExpression</span> : <span style="color:#2b91af">Expression</span></li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#2b91af">Expression</span> left, right;</li> <li>    }</li> <li style="background: #f3f3f3"> </li> <li>    <span style="color:#0000ff">class</span> <span style="color:#2b91af">EvaluateVisitor</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Visit(<span style="color:#2b91af">Expression</span> e)</li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">Exception</span>(<span style="color:#a31515">"Unsupported type of expression"</span>); <span style="color:#008000">// or whatever</span></li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Visit(<span style="color:#2b91af">ConstantExpression</span> e)</li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">return</span> e.constant;</li> <li>        }</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Visit(<span style="color:#2b91af">SumExpression</span> e)</li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">return</span> Visit(e.left <span style="color:#0000ff">as</span> <span style="color:#0000ff">dynamic</span>) + Visit(e.right <span style="color:#0000ff">as</span> <span style="color:#0000ff">dynamic</span>);</li> <li>        }</li> <li style="background: #f3f3f3">    }</li> <li>    </li> <li style="background: #f3f3f3">    <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Main(<span style="color:#0000ff">string</span>[] args)</li> <li>    {</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">var</span> one = <span style="color:#0000ff">new</span> <span style="color:#2b91af">ConstantExpression</span> { constant = 1 };</li> <li>        <span style="color:#0000ff">var</span> two = <span style="color:#0000ff">new</span> <span style="color:#2b91af">ConstantExpression</span> { constant = 2 };</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">var</span> sum = <span style="color:#0000ff">new</span> <span style="color:#2b91af">SumExpression</span> { left = one, right = two };</li> <li>        <span style="color:#0000ff">var</span> vistor = <span style="color:#0000ff">new</span> <span style="color:#2b91af">EvaluateVisitor</span>();</li> <li style="background: #f3f3f3">        <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">"Visit result {0}"</span>, vistor.Visit(sum));</li> <li>        <span style="color:#2b91af">Console</span>.ReadKey();</li> <li style="background: #f3f3f3">    }</li> </ol> </div> </div> </div> <p> </p> <p>This technique has some utility but should be used wisely.  Obviously there will be <a href="http://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.html">some cost for “dynamic” dispatch</a>.  It’s important to note that this isn’t a generalized system for multiple dispatch, just a great spot welding technique to <a href="http://blogs.msdn.com/b/laurionb/archive/2009/05/29/implementing-the-visitor-pattern-with-the-dynamic-feature-of-c-4-0.aspx">make the Visitor pattern more palatable</a>.</p> <p>In contrast, Clojures multimethods allow you to define a function on the arguments that is evaluated and cached, while the “overloads” define the results of that evaluation that they correspond to.  In this way dispatch on multimethods in Clojure can consider not only the “types” and values of all the arguments, but really any sort of inspection or evaluation you choose.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-12805060457883866612010-07-20T22:24:00.001-04:002010-07-20T22:24:58.132-04:00Using the Web to Create the Web<p>Wikis do this, as do blogs.</p> <p>Fast JavaScript in browsers is enabling a new generation of programmers to develop applications completely in their browser.  While the most obvious commercial example is Force.com, there are many other ideas out there.  In no particular order:</p> <ul> <li><a href="http://www.tiddlywiki.com/">TiddlyWiki</a></li> <li><a href="http://jsbin.com/">JsBin</a></li> <li><a href="http://jsfiddle.net/">jsFiddle</a></li> <li><a href="http://www.lively-kernel.org/index.html">Lively Kernel</a></li> <li><a href="http://mozillalabs.com/bespin/">Bespin</a></li> <li><a href="http://www.flapjax-lang.org/">FlapJax</a></li> </ul> <p>The common connection between these frameworks is the notion of bootstrapping the web; that is, using the web to create the web.</p> <p>If you’ll forgive the inchoate thoughts, let me attempt to connect some mental dots.</p> <p>Dr. Alan Kay has of late been discussing the SmallTalk architecture of real objects (computers) all the way down and how this might improve the nature of software on the Internet.</p> <p>In September 2009 in an <a href="http://www.simple-talk.com/opinion/geek-of-the-week/alan-kay-geek-of-the-week/">interview</a>, Dr. Kay said,</p> <blockquote> <p>The ARPA/PARC research community tried to do as many things ‘no center’ as possible and this included Internet […] and the Smalltalk system which was ‘objects all the way down’ and used no OS at all. This could be done much better these days, but very few people are interested in it (we are). We’ve got some nice things to show not quite half way through our project. Lots more can be said on this subject.</p> </blockquote> <p>This month in an <a href="http://www.computerworld.com.au/article/352182/z_programming_languages_smalltalk-80/?pp=2">interview with ComputerWorld Australia</a>, Dr. Kay expounded,</p> <blockquote> <p>To me, one of the nice things about the semantics of real objects is that they are “real computers all the way down (RCATWD)” – this always retains the full ability to represent anything. The old way quickly gets to two things that aren’t computers – data and procedures – and all of a sudden the ability to defer optimizations and particular decisions in favour of behaviours has been lost.</p> <p>In other words, always having real objects always retains the ability to simulate anything you want, and to send it around the planet. If you send data 1000 miles you have to send a manual and/or a programmer to make use of it. If you send the needed programs that can deal with the data, then you are sending an object (even if the design is poor).</p> <p>And RCATWD also provides perfect protection in both directions. We can see this in the hardware model of the Internet (possibly the only real object-oriented system in working order).</p> <p>You get language extensibility almost for free by simply agreeing on conventions for the message forms.</p> <p>My thought in the 70s was that the Internet we were all working on alongside personal computing was a really good scalable design, and that we should make a virtual internet of virtual machines that could be cached by the hardware machines. It’s really too bad that this didn’t happen.</p> </blockquote> <p><a href="http://www.infoq.com/news/2010/07/objects-smalltalk-erlang">Is OOP the wrong path</a>? What is this RCATWD concept really about?  Doesn’t the stateless communication constraint of REST force us to think of web applications in the browser as true peers of server applications?  <em>Should we store our stateful browser-based JavaScript applications in a cloud object-database</em>, in keeping with the Code-On-Demand constraint of REST?  Can we make a them “real objects” per Dr. Kay?  Are RESTful server applications just functional programs?  If so, <em>shouldn’t we be writing them in functional languages</em>?</p> <p>I definitely believe we can gain many benefits from adopting a more message-passing oriented programming style.  I would go so far as to say that OO classes should only export functions, never methods.  (They can use methods privately of course, to keep things DRY.)</p> <p>I’ve written extensively in a never published paper about related topics: single-page applications, not writing new applications to build and deliver applications for every web site, intent-driven design, event sourcing, and others.  Hopefully I’ll find the time to return to that effort and incorporate some of this thinking.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-35808911286033890552010-07-20T21:14:00.001-04:002010-07-20T21:14:33.328-04:00RavenDB: In the Code, Part 1—MEF<p>If you’ve not heard of <a href="http://ravendb.net/">RavenDB</a>, it’s essentially a .NET-from-the-ground-up document database taking its design cues from CouchDB (and MongoDB to a lesser degree). Rather than go into the details about its design and motivations, I’ll let <a href="http://herdingcode.com/?p=255">Ayende speak for himself</a>.</p> <p>Instead, I would like to document some of the great things I’ve found in the <a href="http://github.com/ravendb/ravendb/">codebase of RavenDB</a>, as I <a href="http://www.hanselman.com/blog/HanselminutesPodcast72BeABetterDeveloperInSixMonths.aspx">read to be a better developer</a>.  This series of articles discusses RavenDBs use of the following .NET 4 features.</p> <ul> <li>Managed Extensibility Framework (MEF) </li> <li>New Concurrency Primitives in .NET 4.0 </li> <li>The new <em>dynamic</em> keyword in C# 4 </li> </ul> <p>While discussing RavenDB’s use of these features, I hope to provide a gentle introduction to these technologies.  In this, the first post of the series, we discuss MEF.  For a very brief introduction to MEF and its core concepts, see the <a href="http://mef.codeplex.com/wikipage?title=Overview">Overview in the wiki</a>.</p> <h3>Managed Extensibility Framework</h3> <p>MEF was originally in the Patterns & Practices team and has since moved into the BCL as the System.ComponentModel.Composition namespace.  <a href="http://channel9.msdn.com/shows/SilverlightTV/Silverlight-TV-7-When-and-Where-to-use-MEF/">Glenn Block has nominated it</a> as a plug-in framework, an application partitioning framework, and has given <a href="http://codebetter.com/blogs/glenn.block/archive/2009/08/16/should-i-use-mef-for-my-general-ioc-needs.aspx">many reasons</a> why you may not want to attempt to use it as your <a href="http://martinfowler.com/articles/injection.html">inversion-of-control container</a> (especially if you listen to <a href="http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion">Uncle Bob’s advice</a>). RavenDB uses MEF to handle extensibility for it’s RequestResponder classes.</p> <p>RavenDB’s communication architecture is essentially an HTTP server that has a number of registered handlers of requests, not unlike the front-controller model of ASP.NET MVC.  Akin to MVC’s Routes, each RequestResponder provides a UrlPattern and SupportedVerbs to identify those requests it will handle. A given RequestResponder will vary it’s work depending on the HTTP verbs, headers, and body of the request.  It is in this sense that RavenDB can be considered RESTful (even if it isn’t, see <a href="http://tech.groups.yahoo.com/group/rest-discuss/message/15027">street REST</a>).</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2e9bc6a9-7b75-4d98-a390-0d63f0274a73" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">HttpServer</span> : <span style="color:#2b91af">IDisposable</span></li> <li style="background: #f3f3f3">    {</li> <li>        [<span style="color:#2b91af">ImportMany</span>]</li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span><<span style="color:#2b91af">RequestResponder</span>> RequestResponders { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</li> </ol> </div> </div> </div> <p>This HttpServer class dispatches requests to one of the items in the RequestResponders. This is populated by MEF because of the ImportManyAttribute.    MEF looks in its catalogs and finds the RequestResponder class is exported, as is all of it’s subclasses; see below.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b0e82968-1462-4fc0-b0a1-82720b8b5a84" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li>[<span style="color:#2b91af">InheritedExport</span>]</li> <li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#0000ff">abstract</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">RequestResponder</span></li> </ol> </div> </div> </div> <p>The InheritedExportAttribute ensures that MEF considers all subclasses of the attributed class are themselves as exports.  So, if your class inherits from RequestResponder and MEF can see your class, it will automatically be considered for each incoming request.</p> <p>How does MEF “see your class”? Out-of-the-box MEF provides for the definition of what is discoverable in a number of useful ways. RavenDB makes use of these by providing it’s own MEF CompositionContainer.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f0f92a4f-ee53-4b7b-9f26-382444d409d3" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> HttpServer(<span style="color:#2b91af">RavenConfiguration</span> configuration, <span style="color:#2b91af">DocumentDatabase</span> database)</li> <li style="background: #f3f3f3">{</li> <li>    Configuration = configuration;</li> <li style="background: #f3f3f3"> </li> <li>    configuration.Container.SatisfyImportsOnce(<span style="color:#0000ff">this</span>);</li> </ol> </div> </div> </div> <p>Above, in the constructor of the HttpServer class, we see the characteristic call to <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.compositioncontainer.satisfyimportsonce.aspx">SatisfyImportsOnce</a> on the CompositionContainer. This instructs the container to satisfy all the imports for the HttpServer, namely the RequestResponders.  The configuration.Container property is below:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3560a294-7de5-4919-b2b5-88cc8122eb27" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">public</span> <span style="color:#2b91af">CompositionContainer</span> Container</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> container ?? (container = <span style="color:#0000ff">new</span> <span style="color:#2b91af">CompositionContainer</span>(Catalog)); }</li> </ol> </div> </div> </div> <p>And the Catalog property is initialized in the configuration class’ constructor like this:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ef603f52-b319-4845-a9f3-fc55a5b20219" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li>Catalog = <span style="color:#0000ff">new</span> <span style="color:#2b91af">AggregateCatalog</span>(</li> <li style="background: #f3f3f3">    <span style="color:#0000ff">new</span> <span style="color:#2b91af">AssemblyCatalog</span>(<span style="color:#0000ff">typeof</span> (<span style="color:#2b91af">DocumentDatabase</span>).Assembly)</li> <li>    );</li> </ol> </div> </div> </div> <p>So the container is created with a single AggregateCatalog that can contain multiple catalogs.  That AggregateCatalog is initialized with an AssemblyCatalog which pulls in all the MEF parts (classes with Import and Export attributes) in the assembly containing the DocumentDatabase class (more on that later).</p> <p>That takes care of the built-in RequestResponders, because those are in the same assembly as the DocumentDatabase class.  If that smells like it violates orthogonality, you are not alone. But, I digress; what about extensibility? How does Raven get MEF to see RequestResponder plugins? </p> <p>The configuration class also has a PluginsDirectory property; in the setter, is the following code.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:36badf63-775c-4272-bb06-260773211ca2" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">if</span>(<span style="color:#2b91af">Directory</span>.Exists(pluginsDirectory))</li> <li style="background: #f3f3f3">{</li> <li>    Catalog.Catalogs.Add(<span style="color:#0000ff">new</span> <span style="color:#2b91af">DirectoryCatalog</span>(pluginsDirectory));</li> <li style="background: #f3f3f3">}</li> </ol> </div> </div> </div> <p>So, in Raven’s configuration you can specify a directory where MEF will look for parts.  That’s the raison d'être of MEF’s DirectoryCatalog, since a plugins folder is such a common deployment/extensibility pattern.  You can learn more about the various <a href="http://mef.codeplex.com/wikipage?title=Using%20catalogs">MEF catalogs in the CodePlex wiki</a>.</p> <p>Now, the <u>real</u> extensibility story for RavenDB is its <strong>triggers</strong>.</p> <h3>RavenDB Triggers</h3> <p>The previously mentioned DocumentDatabase class is responsible for the high-level orchestration of the actual database work.  It maintains four groups of triggers.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:63deb6c5-4c47-4d2e-a083-1613a22d23b9" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li>[<span style="color:#2b91af">ImportMany</span>]</li> <li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span><<span style="color:#2b91af">AbstractPutTrigger</span>> PutTriggers { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</li> <li> </li> <li style="background: #f3f3f3">[<span style="color:#2b91af">ImportMany</span>]</li> <li><span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span><<span style="color:#2b91af">AbstractDeleteTrigger</span>> DeleteTriggers { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</li> <li style="background: #f3f3f3"> </li> <li>[<span style="color:#2b91af">ImportMany</span>]</li> <li style="background: #f3f3f3"><span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span><<span style="color:#2b91af">AbstractIndexUpdateTrigger</span>> IndexUpdateTriggers { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</li> <li> </li> <li style="background: #f3f3f3">[<span style="color:#2b91af">ImportMany</span>]</li> <li><span style="color:#0000ff">public</span> <span style="color:#2b91af">IEnumerable</span><<span style="color:#2b91af">AbstractReadTrigger</span>> ReadTriggers { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</li> </ol> </div> </div> </div> <p>Following the same pattern as RequestResponders, the DocumentDatabase calls <em>configuration.Container.SatisfyImportsOnce(this)</em>. So, the imports are satisfied in the same way, i.e. from DocumentDatabase’s assembly and from a configured plug-ins directory.</p> <p>In RavenDB triggers are the way to perform some custom action when documents are “put” (i.e. <a href="http://en.wikipedia.org/wiki/Upsert">upsert</a>) or read or deleted.  RavenDB triggers also provide a way to block any of these actions from happening.</p> <p>Raven also allows for custom actions to be performed when the database spins up using the IStartupTask interface.</p> <h3>Startup Tasks</h3> <p>When the DocumentDatabase class is constructed, it executes the following method after initializing itself.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8e581c60-e856-4c94-9041-3c1e386e9eaf" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> ExecuteStartupTasks()</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> task <span style="color:#0000ff">in</span> Configuration.Container.GetExportedValues<<span style="color:#2b91af">IStartupTask</span>>())</li> <li style="background: #f3f3f3">    {</li> <li>        task.Execute(<span style="color:#0000ff">this</span>);</li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div> <p>This method highlights the use of the CompositionContainer’s GetExportedValues<T> function, which returns all of the IStartupTasks in the catalogs created in the configuration object.</p> <h3>Conclusion</h3> <p>We’ve seen three important extensibility points in RavenDB supported by MEF: RequestResponders, triggers, and startup tasks.  Next time, we’ll look at two more—view generators and dynamic compilation extensions—while learning more about RavenDB indices.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-77219646919665933272010-06-21T15:40:00.001-04:002010-06-21T15:40:15.645-04:00iPad: The InterPersonal Computer<p>There’s no shortage of information on the “how” of the iPad.  Apple’s reification of Alan Kay’s Dynabook makes no sacrifices in terms of processing, communications, display—even the audio is surprisingly good.  But what does the A4 system-on-a-chip, IPS display, Wifi/Bluetooth/3G add up to in terms of experience?</p> <p>Having spent a week with the iPad, I feel compelled to write down my answers to that question. The iPad is nothing short of a joy in my home.  It’s the device we didn’t know we needed: the fourth screen.  It’s the morning paper, the evening magazine, and the after dinner board game.  It’s the vacation photo album, the argument settler, and the cookbook.  The iPad is the first interpersonal computer (iPC); the PC has artfully been disguised as an intelligent, portable screen that facilitates rather than stymies interpersonal interaction.</p> <p>Why did we need this device? Surely I could use Wikipanion on my phone to settle the debate on the national language of Côte d’Ivoire during the game. But, I couldn’t show you the map of the region from across the room.  I definitely could have turned on my PC and connected my TV via DLNA to show our vacation photos. But I’d rather just hand you the album to scan at your leisure.  We could get all the tiles out, flip them over, mix them up, and arrange them, but board games are much more fun (and more apt to be played) when you don’t have to set them up or put them away. I could have done an internet search for recipes that included lemon balm and printed one out, but it’s nice to just go straight from searching to cooking. If we had kids the raison d'être of this latter-day Dynabook would be handsomely fulfilled by an interactive periodic table, a sketchbook, musical toys, and a huge library of books.  For now we’ll just have to settle for loving these apps as grown-ups.</p> <p>This is a device for kids of all ages, to be sure.  Each app acts as a mask, transforming the iPad to a device well-suited to the task at hand. Who wouldn’t find something to enjoy?</p> <p>I’d be remiss if I didn’t offer some lament or prognostication on future enhancements.  This device would be truly magical if I didn’t have to plug it in and synch with iTunes.  If my photos, videos, and music were just wirelessly transported from the cloud on demand and cached locally, I wouldn’t have to wait forever to synch or chew up a bunch of space with things I rarely want.  </p> <p>I would love it if the apps knew me. Maybe a fingerprint scanner could be added to help applications identify me; when I launch a game or Twitter client, if I swiped my finger it could load my saved game or timeline.  An iPC should be like a family friend, a unique relationship with each of us, but impartial and accessible to all.</p> <p>AT&T+Apple could score quite the coup if the 3G was free up to a certain level of usage.  How many snowbirds would buy an iPad to stay in touch with the family back home?  How many more  business travelers would be able to keep up with their inbox without having to be nickel-and-dimed all the time?  More importantly, they would have a device that would be complete out-of-the-box; thank you for purchasing this magical screen that is connected to everyone, everywhere, anywhere you are—right now.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-85911550889876581642010-05-17T11:36:00.001-04:002010-05-17T11:41:44.766-04:00The Law of Demeter and Command-Query Separation<p>My first encounter of the <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a> (LoD) was in the Meilir Page-Jones book, <a href="http://www.amazon.com/gp/product/020169946X?ie=UTF8&tag=iforma-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=020169946X">Fundamentals of Object-Oriented Design in UML</a>. It is also referenced in <a href="http://www.amazon.com/gp/product/0132350882?ie=UTF8&tag=iforma-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0132350882">Clean Code</a> by Robert C. Martin.  Basically, the law states that methods on an object should only invoke methods on objects in their <strong>immediate context</strong>: locally created objects, containing instance members, and arguments to the method itself.  This limits what Page-Jones calls the <strong>direct encumbrance</strong> of a class;  the total set of types a class directly depends upon to do its work.  Martin points out that if an object effectively encapsulates it’s internal state, we should not be able “navigate through it.”  Not to put too fine of a point on it, but the kind of code we are talking about here is:</p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4c83f155-3c42-4a17-84d8-13e271c38d13" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 200px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Main(<span style="color:#0000ff">string</span>[] args)</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">var</span> a = <span style="color:#0000ff">new</span> <span style="color:#2b91af">A</span>();</li> <li style="background: #f3f3f3">    a.Foo().Bar();</li> <li>}</li> <li style="background: #f3f3f3"> </li> <li><span style="color:#0000ff">class</span> <span style="color:#2b91af">A</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">public</span> <span style="color:#2b91af">B</span> Foo()</li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#008000">// do some work and yield B</span></li> <li style="background: #f3f3f3">    }</li> <li>}</li> <li style="background: #f3f3f3"> </li> <li><span style="color:#0000ff">class</span> <span style="color:#2b91af">B</span></li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> Bar()</li> <li style="background: #f3f3f3">    {</li> <li> </li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div> <p>Martin calls line 4 above a “train wreck” due to its resemblance to a series of train cars.  Our Main program has a direct encumbrance of types A & B. We “navigate through” A and invoke a method of B.  Whatever Foo() does, it is not effectively encapsulating it; we cannot change it to an implementation that uses C transparently.</p> <p>LoD is a heuristic that leverages the encumbrance of a type to determine code quality. We observe that effective encapsulation directly constrains encumbrance, so we can say that the Law of Demeter is a partial corollary to an already well known OOP principle: encapsulation.  Another such principle is Command-Query Separation (CQS) as identified by Bertrand Meijer in his work on the Eiffel programming language.</p> <p>CQS simply states that methods should either be commands or query; they should either mutate state or return state without side-effects.  Queries must be <strong>referentially transparent</strong>; that is you can replace all query call sites with the value returned by the query without changing the meaning of the program. Commands must perform some action but not yield a value.  Martin illustrates this principle quite succinctly in Clean Code.</p> <p>Referring to our snippet above again, we can see that if CQS were to have been observed, Foo() would return void and our main program would not have been returned an instance of B.  CQS thus reinforces LoD, both of which manifest as specializations of OO encapsulation.  Following these principles force us to change the semantics of our interfaces, creating contracts that are much more declarative.</p> <p>CQS has many implications.  Fowler <a href="http://martinfowler.com/bliki/CommandQuerySeparation.html">observes</a> that CQS allows consumers of classes to utilize query methods with a sense of “confidence, introducing them anywhere, changing their order.”  In other words, CQS allows for arbitrary composition of queries; this is a very important concept in functional programming.  Queries in CQS are also necessarily idempotent, by definition; this is extremely important in caching.</p> <p>In Martin’s discussion of LoD, he notes that if B above were simply a data structure—if all of its operations were Queries—we would not have a violation of LoD, in principle.  This is because LoD is really only concerned with the proper abstraction of Commands. From the <a href="http://c2.com/cgi/wiki?DontConfuseYourDog">C2 wiki</a>, </p> <blockquote> <p>In the discussion on the <a href="http://c2.com/wiki?LawOfDemeter">LawOfDemeter</a>, <a href="http://c2.com/wiki?MichaelFeathers">MichaelFeathers</a> offers the analogy, "If you want your dog to run, do you talk [to] your dog or to each leg? Further, should you be able to manipulate the dog's leg without it knowing about it? What if your dog wants to move its leg and it doesn't know how you left it? You can really confuse your dog."</p> </blockquote> <p>To extend the analogy, when you are walking your dog, you don’t command it’s legs, you command the dog.  But, if you want to have a smooth walk, you’ll stop and wait if you one of the dog’s legs is raised. It is in this sense that we can restate the Law of Demeter in terms of Command-Query Separation.</p> <ul> <li>Whereas a <strong>Query</strong> of an object must:</li> <ol> <li>never alter the observable state of the object, i.e. the results of any queries; </li> <li>and return only objects entirely composed of queries, <strong>no commands</strong>.</li> </ol> <li>A <strong>Command</strong> of an object must: </li> <ol> <li>constrain its actions to be dependent upon the observable state, i.e. Queries, of <strong>only</strong> those objects in its immediate context (as defined above); </li> <li>and hide the internal state changes that result of its actions from observers. </li> </ol> </ul> <p>This restating is helpful in that it implies that we refactor to CQS before applying LoD. In the first phase we clearly separate commands from queries. In the second phase we alter the semantics of our commands and queries to comply with LoD.  While the first phase is rather mechanical, it give us a good starting point to reconsider the semantics of our objects as we bring them into compliance with LoD.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-6220196894242525352010-04-22T16:04:00.001-04:002010-04-22T16:05:00.066-04:00Usability Apothegms<p>A common saying in computing is that “Security is inversely proportional to usability”… or something like that.  As we critical examine the security of our systems, we realize we need to put measures in place that make the system harder to access and thus harder to use.  A good interaction design can help mitigate the usability issues, but at the end of the day a system that doesn’t require me to memorize a password or login is easier to use than a system that does.</p> <p>We can say definitively that security and usability exist in tension.</p> <p>As software architects we seek simplicity in our designs in the name of maintainability, if not intelligibility.  We also seek modularity in the name of reusability. I submit that simplicity and modularity exist in tension.</p> <p>Accepting <em>a priori</em> that simplicity is the absence of complexity, we can obtain the simplicity of a program by measuring its complexity.  A field of computer science called algorithmic information theory defines the complexity of something to be the length of the simplest program for calculating it.  We might infer from this that a monolithic program (no components, no objects, no abstractions, etc.) is a simpler program than our common object-oriented code.  In general we can say that modularity implies no small increase in the use of abstractions to enable that modularity.</p> <p><strong>In object-oriented* systems, an increase in modularity results in a proportional increase in complexity.</strong></p> <p>I limit this to object-oriented systems purposefully.  In my experience functional programming languages modularity is <em>de rigueur</em>. </p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-64540970934180699772010-04-12T19:53:00.001-04:002010-04-12T19:53:28.959-04:00Converting Oranges to Apple’s: Meta-competition in the Platform Wars<p>Updates to the developer agreement in the new iPhone SDK restrict developers to using C, C++, or Objective-C to create their native iPhone applications.  That is, they must have been “originally written” in one of those languages.</p> <p>This move has made its rounds among the pundits and bloggers.  Rather than rehashing any of those points, I’ll give my own opinions on why Apple made this move.</p> <p>Make no mistake, this is about stewardship of the iPhone experience.  Steve Jobs has responded to the criticism (emphasis my own),</p> <blockquote> <p>[…] intermediate layers between the platform and the developer ultimately produces sub-standard apps and hinders the progress of <strong>the platform</strong>.</p> </blockquote> <p>Before you go say they’re really just trying to kill Flash, let’s address that up front.  Flash does not run in Safari on the iPhone for the same reason that you are prohibited in the developer agreement from hosting a virtual machine in your iPhone application.  As the steward of the platform, Apple has to attempt to ensure that users have consistently good experience.  Trying to squeeze a bloated swf player into a memory and processor constrained device is just not workable currently.  As any iPhone user can attest, websites that are not optimized for mobile browsers are horribly slow to load.  Flash content would just make that worse.  And, guess what, my mom doesn’t know that your website or Flash animation is a pig, she just thinks her phone is slow.</p> <p>Let’s look at it from another perspective.  The latest incarnation of Microsoft’s flagship development suite, Visual Studio 2010, has been re-written on their WPF platform.  Well, everything except the splash screen.  You see, it takes too long to load WPF and .NET up to affect the desired result of a splash screen—giving you something to look at while the main application loads.  The iPhone developer guide makes it abundantly clear that you should load something as quickly as possible to give the user the sense that your app is responsive.  Try explaining to your mom that, yes, her phone has registered her tap on the application icon, but that it has to spin up a virtual machine or load some large libraries that abstract away Cocoa.</p> <p>Next, try to explain to her why the extra cycles required by the VM and/or interoperability libraries drain her battery.  She’ll just be annoyed that she’s constantly plugging the darn thing in.</p> <p>Apologies to all the technical moms out there.</p> <p>so, Flash [1] is not the target here, at least in the sense that Apple cares if Flash is around or perceives it as a threat.  And, assuredly, we cannot say that stewardship of the performance of the phones is the only reason.  That’s part of Steve’s “sub-standard apps” argument, and it is not entirely convincing given that it becomes an optimization problem, and developers are notoriously good at those when they set their mind to it.  As a steward though, you really cannot afford to wait from them to figure it out.  Nevertheless, I think the original ban on virtual machines and this subsequent tightening to a whitelist of languages comes down to a stewardship of a different kind: keeping out the riff-raff.</p> <p>Keeping up with AppStore submissions is already pretty hard and very expensive.  Developers are often frustrated by the time it takes to get their updates into the store, especially developers used to patching websites with no downtime. Don’t imagine for a second that your $99 covers the cost of the program.  This is Apple’s investment in the ecosystem.  Imagine the deluge of useless, crappy submissions they will get if every Flash developer and every VB developer can just tick a box to target the iPhone.</p> <p>But, it’s not just about raising the bar for entry to keep out sub-standard developers and their apps.  They have to look after all those developers who have committed to their platform.  They aren’t going to invest significant resources to enabling C#, VB, Python, Ruby, or Flash developers to compete against their own.  </p> <p>Apple is not interested in seeing your app run on a Droid, Windows Mobile 7, and iPhone.  They are actively controverting homogenization of the mobile application marketplace.  They have an insurmountable lead[2] in the mobile applications marketplace, and the iPad, another device on the iPhone OS platform, marks the next step in their overall competitive strategy for leveraging that lead.  At the center of all of this is the AppStore, perhaps the single most valuable asset in computing today.  Whereas no one controls the Internet, Apple owns the AppStore outright with all the rights and responsibilities that entails; think of Salesforce.com and their AppExchange.</p> <p>Microsoft has long understood that developers are what make their ecosystem work.  Steve Ballmer’s famous rallying cry, “Developers! Developers! Developers!”, is poignant illustration of this reality.  Apple understands that to usurp Microsoft’s position in the PC and enterprise markets, to continue their domination of consumer segments, they need a large population of developers that understand their platform.  What they don’t need are more ways for developers to “write once, run everywhere.”  In the platform wars, he who has the developers wins.</p> <p> </p> <p>[1] Anyway, it isn’t just about Flash.  Look no further than Microsoft’s Windows Mobile 7 announcements to see that.  Silverlight, a Flash competitor to say that least, will be the native platform of those devices.  Where Flash is Silverlight will surely follow.</p> <p>[2] I believe that Google will continue to have limited success as a web-native device.  There is a significant segment of the marketplace that just want a phone, email, web-browsing device.  RIM has an Apple-style loyalty thing going for it.  Microsoft?  Well, they still have such a big footprint; they could fail and still make a huge impact.  I think the move to Silverlight helps shield their effort from their internal Windows-Office power structure enough that it actually has a chance of competing, but they are way too far behind to win.  There’s not a huge population of Silverlight developers in the world, after all.</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-38541161374041186352009-12-29T19:23:00.001-05:002009-12-29T19:37:30.060-05:00Inchoate Thoughts on New Programming Abstractions for the Cloud<p>I watched an InfoQ video of <a href="http://www.infoq.com/presentations/liskov-power-of-abstraction">Barbara Liskov at OOPSLA</a> this evening.  At the end of her talk in a look at the challenges looking forward she said, “I’ve been waiting for thirty years for a new abstraction mechanism,” and, “There’s a funny disconnect in how we write distributed programs.  You write your individual modules, but then when you want to connect them together you’re out of the programming language, and sort of into this other world.  Maybe we need languages that are a little more complete now so that we can write the whole thing in the language.”  Her talk was an interesting journey through the history of Computer Science through the lens of her work, but this notion connected with something I’ve been thinking about lately.</p> <p>Earlier this month I was catching up on the happenings on Channel9 and stumbled on <a href="http://channel9.msdn.com/posts/Charles/JAOO-2007-Erik-Meijer-and-Dave-Thomas-Objects-Functions-Virtual-Machines-IDEs-and-Other-Fun-St/">this conversation between Erik Meijer and Dave Thomas</a>.  I would have preferred a different interview-style, but Dave Thomas’ opinions are always interesting.  “I find it hard to believe that people would build a business application in Java or C#. […] The real opportunity is recognizing that there is really no need for people to do all of the stuff they have to do today.  And, I really believe that is fundamentally a language problem, whether that’s through an extended SQL, or its a new functional language, whether its a vector functional language; I can see lots of possibilities there. […] I see a future where there are objects in the modeling layer, but not in the execution infrastructure.”</p> <p>I see a connection between Liskov’s desire “new abstraction mechanism” and Thomas’ “language problem”.  If you look at the history of “execution infrastructure”, there has been an unremitting trend toward greater and greater abstraction of the hardware that makes it all happen.  From twiddling bits, to manipulating registers, to compiled languages, to compiled to virtual machine bytecode and attendant technologies like garbage collection, interpreters, to very declarative constructs, we continually move away from the hardware to focus on the actual problems that we began writing the program to solve in the first place(1).  Both Liskov and Thomas are bothered by the expressivity of languages; that is, programming languages are still burdened with the legacy of the material world.</p> <p>I think this may very well be the point of “Oslo” and the “M” meta-language.  One might view that effort as a concession that even DSLs are too far burdened by their host language’s legacy to effectively move past the <strong>machine programming era</strong> into the <strong>solution modeling</strong> era.  So, rather than create a language with which to write solution code, create a language/runtime to write such languages.  This is really just the logical next step, isn’t it?</p> <p>I didn’t quite understand this viewpoint at the time, but I had this discussion to some extent with <a href="http://www.shycohen.com/blog/">Shy Cohen</a> at TechEd09.  I just didn’t grasp the gestalt of “Oslo”.  This certainly wasn’t a failing of his explanatory powers nor—hopefully—my ability to understand.  Rather I think it’s because they keep demoing it as one more data access technology.  The main demo being to develop an M grammar of some simple type and have a database created.  Again, the legacy of computing strikes again.  To make the demo relevant, they have to show you how it works with all your existing infrastructure.</p> <p>So, maybe the solution to developing new abstractions is to once and for all abstract away the rest of the infrastructure.  Both Liskov and Thomas were making this point.  Why should we care how and where the data is stored?  Why should most developers care about concurrency?  Why should we have to understand the behemoth that is WCF in order to get to modules/systems/components talking to each other?</p> <p>Let’s start over with an abstraction of the entirety of computing infrastructure(2): servers, networking, disks, backups, databases, etc..  We’ll call it, oh, I don’t know… a cloud.  Now, what properties must a cloud exhibit in order to ensure this abstraction doesn’t leak?  I suggest we can examine why existing abstractions in computing have been successful, understand the problems they solve at a fundamental level, and then ensure that our cloud can do the same.  Some candidates for this examination are: relational databases, virtual machines/garbage collectors, REST, Ruby on Rails, and LINQ.  I’m sure there are countless other effective abstractions that could serve as guideposts.</p> <p>Should we not be able to express things naturally in a <strong>solution modeling language</strong>?  Why can’t I write, “When Company X sends us a shipment notification for the next Widget shipment, make sure that all Whatzit production is expedited. And, let me know immediately if Whatzit production capacity is insufficient to meet our production goals for the month.”  Sure, this is a bit imperative, but it’s imperatively modeling a solution, not instructions on how to push bits around to satisfy the solution model; in that sense it is very, very declarative.  I believe the cloud abstraction enables this kind of <strong>solution modeling language</strong>.</p> <p>How about a cloud as the ambient monad for all programs?  What about a Google Wave bot as a sort of REPL loop for this solution modeling language?  What about extensive use of the Maybe monad or <a href="http://community.schemewiki.org/?amb">amb</a> style evaluation in a constraint driven lexicon so that imperative rules like those in the sample above are evaluated in a <a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx">reactive</a> rather than deterministic fashion?</p> <ol> <li>Quantum computing productively remains undecided as to “how” it actually works.  That is, “how” is somewhat dependent on your interpretation of quantum mechanics.  Maybe an infinite number of calculation occur simultaneously in infinite universes with the results summed over via quantum mechanical effects.</li> <li>I should say here that I think the Salesforce.com model is pretty far down this path, as is Windows Azure to a lesser extent.  Crucially, neither of these platforms mitigate the overhead of persistence and communications constructs.</li> </ol> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-15889740300037884322009-12-21T08:52:00.001-05:002009-12-21T08:52:59.033-05:00System.Tuple: More .NET 4.0 Functional Goodness<p>In functional languages, tuples are pretty much a requirement.  Of the functional languages I’ve used, including Erlang and T-SQL, tuples are bread’n’butter.  Every release of .NET has included more and more support for functional programming paradigms, and we’re getting tuple support in the BCL in .NET 4.0, though first-class language support is still not there.  Here’s an example of using System.Tuple with the new Zip LINQ operator.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8d9a9a9f-9d40-42d0-a958-00e3675fd297" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="color:#0000ff">var</span> xs = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span><<span style="color:#0000ff">int</span>> { <span style="color:#a52a2a">1</span>, <span style="color:#a52a2a">3</span>, <span style="color:#a52a2a">5</span> };</li> <li style="background: #f3f3f3"><span style="color:#0000ff">var</span> ys = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span><<span style="color:#0000ff">string</span>> { <span style="color:#a31515">"hello"</span>, <span style="color:#a31515">"world"</span>, <span style="color:#a31515">"channel"</span> };</li> <li><span style="color:#0000ff">var</span> zs = xs.Zip(ys, <span style="color:#2b91af">Tuple</span>.Create);</li> <li style="background: #f3f3f3"> </li> <li><span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> z <span style="color:#0000ff">in</span> zs)</li> <li style="background: #f3f3f3">    <span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">"{1}:{0}"</span>,z.Item1, z.Item2);</li> </ol> </div> </div> </div> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-28006168911344789722009-12-17T23:31:00.001-05:002009-12-21T04:01:18.900-05:00Quicksort Random Integers with PLINQ<div>The first “homework assignment” of <a href="http://channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1/">Dr. Erik Meijer’s functional programming course on Channel 9</a> was to write quicksort using C# (or VB) functional comprehensions.  I did it in a very naïve way, then I wondered if I could get a “free” speed up simply by leveraging some of the Parallel Extensions to .NET 4.0.  </div> <div> </div> <div>My results were mixed.  As the number of integers in the unsorted array increases, the parallel implementation begins to pull away, but with smaller numbers the sequential implementation is faster.  I think I’ll try to do something very similar in Erlang this weekend.  It should be an interesting comparison exercise since Erlang terms are immutable.  A naïve implementation should look pretty similar I think.  Neither of them would be true quicksort implementations, since the algorithm was specified by Hoare to work in a mutable fashion with the original array being changed in situ.</div> <div> </div> <div>My dual core machine yielded times of about 80s and 100s when sorting an array of a thousand for the parallel (QsortP) and sequential (Qsort) methods respectively.  So that’s definitely not impressive, but I did it in a very abstract way.  The same function could sort strings or floats or anything else that implements IComparable.  <p></p> <p></p> <p></p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e927f59b-4f71-4bcd-842d-de3cdfc0166e" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px; white-space: nowrap"> <li><span style="color:#0000ff">using</span> System;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">using</span> System.Collections.Generic;</li> <li><span style="color:#0000ff">using</span> System.Linq;</li> <li style="background: #f3f3f3"><span style="color:#0000ff">using</span> System.Threading.Tasks;</li> <li><span style="color:#0000ff">using</span> System.Diagnostics;</li> <li style="background: #f3f3f3"> </li> <li><span style="color:#0000ff">namespace</span> ConsoleApplication3</li> <li style="background: #f3f3f3">{</li> <li>    <span style="color:#0000ff">class</span> <span style="color:#2b91af">Program</span></li> <li style="background: #f3f3f3">    {</li> <li>        <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Main(<span style="color:#0000ff">string</span>[] args)</li> <li style="background: #f3f3f3">        {</li> <li>            <span style="color:#0000ff">int</span>[] ints = <span style="color:#0000ff">new</span> <span style="color:#0000ff">int</span>[<span style="color:#a52a2a">100</span>];</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">var</span> rand = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Random</span>();</li> <li>            <span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> i = <span style="color:#a52a2a">0</span>; i < ints.Length; i++)</li> <li style="background: #f3f3f3">                ints[i] = rand.Next(<span style="color:#a52a2a">0</span>, <span style="color:#2b91af">Int32</span>.MaxValue);</li> <li>            <span style="color:#0000ff">int</span>[] sortedP;</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">int</span>[] sorted;</li> <li>            Time(() => sortedP = QsortP(ints).ToArray());</li> <li style="background: #f3f3f3">            Time(() => sorted = Qsort(ints).ToArray());</li> <li>            <span style="color:#2b91af">Debugger</span>.Break();</li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">IEnumerable</span><T> QsortP<T>(<span style="color:#2b91af">IEnumerable</span><T> arr) <span style="color:#0000ff">where</span> T : <span style="color:#2b91af">IComparable</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">if</span> (arr.Count() == <span style="color:#a52a2a">0</span>)</li> <li>                <span style="color:#0000ff">return</span> arr;</li> <li style="background: #f3f3f3">            T pivot = arr.First();</li> <li>            <span style="color:#0000ff">var</span> sortLess = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Task</span><<span style="color:#2b91af">IEnumerable</span><T>>(() => QsortP(arr.Where(v => v.CompareTo(pivot) < <span style="color:#a52a2a">0</span>)));</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">var</span> sortMore = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Task</span><<span style="color:#2b91af">IEnumerable</span><T>>(() => QsortP(arr.Where(v => v.CompareTo(pivot) > <span style="color:#a52a2a">0</span>)));</li> <li>            sortLess.Start(); sortMore.Start();</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">var</span> equal = arr.AsParallel().Where(v => v.CompareTo(pivot) == <span style="color:#a52a2a">0</span>);</li> <li>            <span style="color:#0000ff">return</span> sortLess.Result.Concat(equal).Concat(sortMore.Result);</li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#2b91af">IEnumerable</span><T> Qsort<T>(<span style="color:#2b91af">IEnumerable</span><T> arr) <span style="color:#0000ff">where</span> T : <span style="color:#2b91af">IComparable</span></li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">if</span> (arr.Count() == <span style="color:#a52a2a">0</span>)</li> <li>                <span style="color:#0000ff">return</span> arr;</li> <li style="background: #f3f3f3">            T pivot = arr.First();</li> <li>            <span style="color:#0000ff">return</span> Qsort(arr.Where(v => v.CompareTo(pivot) < <span style="color:#a52a2a">0</span>))</li> <li style="background: #f3f3f3">                .Concat(arr.Where(v => v.CompareTo(pivot) == <span style="color:#a52a2a">0</span>))</li> <li>                .Concat(Qsort(arr.Where(v => v.CompareTo(pivot) > <span style="color:#a52a2a">0</span>)));</li> <li style="background: #f3f3f3">        }</li> <li> </li> <li style="background: #f3f3f3">        <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> Time(<span style="color:#2b91af">Action</span> a)</li> <li>        {</li> <li style="background: #f3f3f3">            <span style="color:#0000ff">var</span> t = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Stopwatch</span>();</li> <li>            t.Start();</li> <li style="background: #f3f3f3">            a();</li> <li>            t.Stop();</li> <li style="background: #f3f3f3">            <span style="color:#2b91af">Debug</span>.Write(t.Elapsed.TotalSeconds);</li> <li>        }</li> <li style="background: #f3f3f3">    }</li> <li>}</li> </ol> </div> </div> </div> </div> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-83022021526760851752009-12-15T14:57:00.001-05:002009-12-15T15:12:47.958-05:00Premature Optimization and LINQ to SQL<p>Don’t count your chickens before they hatch.  Let’s call that adage the “count-no” principle.  I promise that will be funny later.</p> <p>The common interpretation of this adage is that you should not rely on future results when making decisions in the present.  It is generally an admonishment to not be too cocky about the future.  What might the corollary be?  Perhaps to concern ourselves with the details of the present moment rather than thinking about the future.  We’ll call this corollary “nocount”.  One specific example of this corollary is the programmer’s maxim about premature optimization.  In fact, it was <a href="http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf">Donald Knuth</a> who said, “"We should forget about small efficiencies, say about 97% of the time: premature <a href="http://en.wikipedia.org/wiki/Optimization_(computer_science)">optimization</a> is the root of all evil,” in a response to Dijkstra’s “Go to statement considered harmful”.</p> <p>So, I’m debugging a particularly pernicious problem today.  In production (and only production) we were getting a <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.changeconflictexception.aspx">ChangeConflictException</a> when updating a row in the database.  Unfortunately, the logs indicated that there were no <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.memberchangeconflict.aspx">MemberChangeConflict</a> objects.  In other words we weren’t violating optimistic concurrency.  So, I profiled the SQL statements and it appeared to be just what I expected, a simple update supporting optimistic concurrency.</p> <p>Did you know you can eek out an exceedingly miniscule amount of performance by using the “SET NOCOUNT ON” option with SQL Server?  Did you know that you can actually set this option at the <strong><em>server level</em></strong>? Do you know what happens when your LINQ to SQL DataContext uses the row count returned from your optimistically concurrent update statement to determine if one and only one row was updated?</p> <p>Yes dear reader, premature optimization can cause the most insidious and difficult to discover problems.  Please, don’t ever violate the “nocount princple”!</p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.comtag:blogger.com,1999:blog-6928325842095718321.post-16039089379420637132009-11-10T13:44:00.001-05:002009-11-10T13:47:03.378-05:00Create an XML Schema Enumeration of Supported .NET CultureInfo with Powershell<p>Here’s a Powershell script to generate the enumeration elements of an XML Schema simpleType restriction.  The first command loads the .NET Assembly you’ll need, sysglobl.dll.</p> <code>PS> [System.Reflection.Assembly]::Load("sysglobl, Version=2.0.0.0, Culture=neutral, PublicKeyToken= b03f5f7f11d50a3a, processorArchitecture=MSIL")</code> <br /> <code>PS> [System.Globalization.CultureInfo]::GetCultures([System.Globalization.CultureTypes]::FrameworkCultures) <br />| ? {$_.Name.Trim().Length -eq 5} | % { "<xs:enumeration value=`"$_`"/>"} | Out-File cultures.txt</code> <p>See my earlier post on locale identifiers for more background. </p> testhttp://www.blogger.com/profile/00936599699870104928noreply@blogger.com