<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D04EQHo-eip7ImA9WhVTEEo.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203</id><updated>2012-02-24T09:31:41.452Z</updated><category term="Coding" /><category term="Literature amp; Language" /><category term="Project Euler" /><category term="Vim" /><category term="Patterns" /><category term="Book Club" /><category term="Data Structures" /><category term="Software Engineering" /><category term="Mathematics" /><category term="Ruby" /><category term="Refactoring" /><category term=".Net" /><title>Basildon Coder</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.basildoncoder.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>40</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/basildoncoder/sLzB" /><feedburner:info uri="basildoncoder/slzb" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUcDQXo-eyp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-2239564839655688196</id><published>2009-03-31T20:03:00.000+01:00</published><updated>2011-10-03T10:11:10.453+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.453+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Data Structures" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><title>Marshalling a Variable-Length Array From Unmanaged Code In C#</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TyZ3N297dL56JZpxtyZDFoIQbXI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TyZ3N297dL56JZpxtyZDFoIQbXI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TyZ3N297dL56JZpxtyZDFoIQbXI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TyZ3N297dL56JZpxtyZDFoIQbXI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I recently spent time working on some C# code to interact with a simple &lt;a href="http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt"&gt;DNS-SD&lt;/a&gt; system. This requires using &lt;a href="http://en.wikipedia.org/wiki/List_of_DNS_record_types"&gt;DNS TXT records&lt;/a&gt;, which are not supported in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.dns.aspx"&gt;System.Net.Dns&lt;/a&gt; class. After a few google searches failed to turn up a pure .Net client library that met my needs, I settled on an approach based around p/invoking the Win32 &lt;a href="http://msdn.microsoft.com/en-us/library/ms682016(VS.85).aspx"&gt;DnsQuery&lt;/a&gt; function.&lt;br/&gt;&lt;br/&gt;And quickly ran into problems.&lt;br/&gt;&lt;br/&gt;For DNS TXT records, DnsQuery returns a &lt;a href="http://msdn.microsoft.com/en-us/library/ms682109(VS.85).aspx"&gt;DNS_TXT_DATA&lt;/a&gt; structure in the Data field of the &lt;a href="http://msdn.microsoft.com/en-us/library/ms682082(VS.85).aspx"&gt;DNS_RECORD&lt;/a&gt; structure. DNS_TXT_DATA is declared like this:&lt;br/&gt;&lt;pre lang="C"&gt;typedef struct {&lt;br/&gt;    DWORD dwStringCount;&lt;br/&gt;    PWSTR pStringArray[1];&lt;br/&gt;} DNS_TXT_DATA,&lt;br/&gt;    *PDNS_TXT_DATA;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;Using the very handy &lt;a href="http://clrinterop.codeplex.com/"&gt;P/Invoke Interop Assistant&lt;/a&gt;, we see that this struct can be represented like this in managed code:&lt;br/&gt;&lt;pre lang="csharp"&gt;[StructLayout(LayoutKind.Sequential)]&lt;br/&gt;public struct DNS_TXT_DATA {&lt;br/&gt;&lt;br/&gt;    /// DWORD-&gt;unsigned int&lt;br/&gt;    public uint dwStringCount;&lt;br/&gt;&lt;br/&gt;    /// PWSTR[1]&lt;br/&gt;    [MarshalAs(UnmanagedType.ByValArray,&lt;br/&gt;            SizeConst=1,&lt;br/&gt;            ArraySubType=UnmanagedType.SysUInt)]&lt;br/&gt;    public IntPtr[] pStringArray;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;There is a problem with pStringArray, unfortunately. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx"&gt;System.Runtime.InteropServices.Marshal&lt;/a&gt; class cannot marshal a variable length array, as it needs to know in advance how big the array is in order to allocate memory. That's why the managed structure needs SizeConst specified in the MarshalAs attribute.&lt;br/&gt;&lt;br/&gt;However, if the DNS TXT record data contains multiple quoted strings separated by whitespace, DnsQuery will return a structure with a variable number of elements in pStringArray. Since SizeConst is set at compile-time, when we marshal this into the managed struct defined above, we only get the first element in our single-element array. Rats.&lt;br/&gt;&lt;br/&gt;More googling turned up very little info on dealing with this, though I found indications that others had run into the same problem without finding a satisfactory conclusion. DnsQuery is not the only Win32 function that returns variable-length arrays, and p/invoking any of the others has the same issue.&lt;br/&gt;&lt;br/&gt;Simply declaring SizeConst to be bigger than we need - "hey, I know I'll never get more than 10 or so strings back, so why not declare SizeConst to be 128?" - is inelegant (hardcoded upper limits, ugh) and doesn't work properly anyway. Since the struct layout is sequential the marshaller will copy over (e.g.) 128*sizeof(IntPtr) sequential bytes (a total of 512 bytes, in this case). That much memory was never allocated on the unmanaged side, so we end up with a load of junk in the tail of pStringArray, and more often than not the marshaller chokes on this junk and throws an AccessViolationException. Fun.&lt;br/&gt;&lt;br/&gt;There IS a way to get round the problem, though. I'm not sure it's the best way, but it works and seems stable, so I thought I'd throw it out there in case anyone else can use it (or maybe explain to me why it's an unsafe stupid thing to do...)&lt;br/&gt;&lt;br/&gt;Basically, since we're dealing with sequential memory, we can use Marshal.PtrToStructure to marshal the DNS_TXT_DATA structure as defined above, then use pointer arithmetic to gain access to any further data that needs marshalling.&lt;br/&gt;&lt;br/&gt;Pointer arithmetic? Oh yes, even in the safe and secure world of managed code it's sometimes still necessary to get our hands dirty, and situations like this illustrate that it will always be valuable to have some hard-earned Assembly/C/C++ war wounds.&lt;br/&gt;&lt;br/&gt;So, assuming we have valid p/invoke declarations and data structures (I've included a complete source program below), DnsQuery is called like so:&lt;br/&gt;&lt;pre lang="csharp"&gt;var pServers = IntPtr.Zero;&lt;br/&gt;var ppQueryResultsSet = IntPtr.Zero;&lt;br/&gt;var ret = DnsQuery(domain,&lt;br/&gt;        DnsRecordType.TEXT,&lt;br/&gt;        DnsQueryType.STANDARD,&lt;br/&gt;        pServers,&lt;br/&gt;        ref ppQueryResultsSet,&lt;br/&gt;        IntPtr.Zero);&lt;br/&gt;if (ret != 0)&lt;br/&gt;    throw new ApplicationException("DnsQuery failed: " + ret);&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;If we examine the memory location of ppQueryResultsSet (Ctrl-Alt-M,1 or Debug-&amp;gt;Windows-&amp;gt;Memory-&amp;gt;Memory1 in Visual Studio) we'll see something like the following (actual address locations may vary - just copy the int value of ppQueryResultsSet to the Address bar of the memory window):&lt;br/&gt;&lt;pre&gt;0x049E0878  00 00 00 00  ....&lt;br/&gt;0x049E087C  b8 09 9e 04  ¸.ž.&lt;br/&gt;0x049E0880  10 00 20 00  .. .&lt;br/&gt;0x049E0884  19 30 00 00  .0..&lt;br/&gt;0x049E0888  00 00 00 00  ....&lt;br/&gt;0x049E088C  00 00 00 00  ....&lt;br/&gt;0x049E0890  06 00 00 00  ....&lt;br/&gt;0x049E0894  b8 08 9e 04  ¸.ž.&lt;br/&gt;0x049E0898  d8 08 9e 04  Ø.ž.&lt;br/&gt;0x049E089C  f8 08 9e 04  ø.ž.&lt;br/&gt;0x049E08A0  28 09 9e 04  (.ž.&lt;br/&gt;0x049E08A4  68 09 9e 04  h.ž.&lt;br/&gt;0x049E08A8  88 09 9e 04  ˆ.ž.&lt;/pre&gt;&lt;br/&gt;I've set the column size to 4 here, as most of the values we are dealing with are 4 bytes in size. This effectively shows one value per line.&lt;br/&gt;&lt;br/&gt;The first 6 rows (24 bytes) correspond to the DNS_RECORD structure up until (but not including) the DNS_TXT_DATA structure in DNS_RECORD's Data union. We can marshal this first structure without problem:&lt;br/&gt;&lt;pre lang="csharp"&gt;var dnsRecord = (DnsRecord) Marshal.PtrToStructure(&lt;br/&gt;        ppQueryResultsSet, typeof (DnsRecord));&lt;/pre&gt;&lt;br/&gt;The DNS_TXT_DATA structure starts at address 0x049E0890 in my example. Having already marshalled the DNS_RECORD structure, now I want a pointer to the DNS_TXT_DATA structure. I can do this by creating a new pointer at the address of ppQueryResultsSet plus 24 bytes, and marshalling again:&lt;br/&gt;&lt;pre lang="csharp"&gt;var ptr = new IntPtr(&lt;br/&gt;        ppQueryResultsSet.ToInt32() + Marshal.SizeOf(dnsRecord));&lt;br/&gt;var txtData = (DNS_TXT_DATA) Marshal.PtrToStructure(&lt;br/&gt;        ptr, typeof (DNS_TXT_DATA));&lt;/pre&gt;&lt;br/&gt;Because of the definition of DNS_TXT_DATA, this only marshals 8 bytes - 4 bytes for dwStringCount, and 4 bytes for the single element in pStringArray (an IntPtr). Since we know the memory is sequential, however, this gives us everything we need - we now know how many strings have been received (6 in this case, as indicated at 0x049E0890), and the location of the pointer to the first string (0x049E0894).&lt;br/&gt;&lt;br/&gt;With this info, we can marshal all the pointers into an array with a length of dwStringCount:&lt;br/&gt;&lt;pre lang="csharp"&gt;ptr = new IntPtr(ptr.ToInt32() + sizeof (uint)); // move to first&lt;br/&gt;var ptrs = new IntPtr[txtData.dwStringCount]; // dest array&lt;br/&gt;Marshal.Copy(ptr, ptrs, 0, ptrs.Length);&lt;/pre&gt;&lt;br/&gt;And finally we iterate through those pointers, marshalling the string pointed at by each:&lt;br/&gt;&lt;pre lang="csharp"&gt;var strings = new List&lt;string&gt;();&lt;br/&gt;for (var i = 0; i &lt; ptrs.Length; ++i)&lt;br/&gt;{&lt;br/&gt;    strings.Add(Marshal.PtrToStringAnsi(ptrs[i]));&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;While the example I've presented here is specific to DnsQuery, the general approach should be applicable to any situation where you need to marshal a data structure containing a variable-length array.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://basildoncoder.com/marshal-variable-length-array.cs"&gt;Source code&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-2239564839655688196?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/mWo3gDqvJjw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/2239564839655688196/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2009/03/marshalling-variable-length-array-from.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2239564839655688196?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2239564839655688196?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/mWo3gDqvJjw/marshalling-variable-length-array-from.html" title="Marshalling a Variable-Length Array From Unmanaged Code In C#" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>6</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2009/03/marshalling-variable-length-array-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXoyeip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-6539552734679374963</id><published>2009-02-09T19:30:00.000Z</published><updated>2011-10-03T10:11:10.492+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.492+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 8</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MfzUw-RfIRLgAT7quutYi6ut9BM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MfzUw-RfIRLgAT7quutYi6ut9BM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MfzUw-RfIRLgAT7quutYi6ut9BM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MfzUw-RfIRLgAT7quutYi6ut9BM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=8"&gt;&lt;em&gt;&lt;strong&gt;Problem 8&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;br/&gt;&lt;blockquote&gt;"Find the greatest product of five consecutive digits in the 1000-digit number.&lt;br/&gt;&lt;br/&gt;73167176531330624919225119674426574742355349194934&lt;br/&gt;96983520312774506326239578318016984801869478851843&lt;br/&gt;85861560789112949495459501737958331952853208805511&lt;br/&gt;12540698747158523863050715693290963295227443043557&lt;br/&gt;66896648950445244523161731856403098711121722383113&lt;br/&gt;62229893423380308135336276614282806444486645238749&lt;br/&gt;30358907296290491560440772390713810515859307960866&lt;br/&gt;70172427121883998797908792274921901699720888093776&lt;br/&gt;65727333001053367881220235421809751254540594752243&lt;br/&gt;52584907711670556013604839586446706324415722155397&lt;br/&gt;53697817977846174064955149290862569321978468622482&lt;br/&gt;83972241375657056057490261407972968652414535100474&lt;br/&gt;82166370484403199890008895243450658541227588666881&lt;br/&gt;16427171479924442928230863465674813919123162824586&lt;br/&gt;17866458359124566529476545682848912883142607690042&lt;br/&gt;24219022671055626321111109370544217506941658960408&lt;br/&gt;07198403850962455444362981230987879927244284909188&lt;br/&gt;84580156166097919133875499200524063689912560717606&lt;br/&gt;05886116467109405077541002256983155200055935729725&lt;br/&gt;71636269561882670428252483600823257530420752963450"&lt;/blockquote&gt;&lt;br/&gt;The first step here is to find a representation for that fairly humungous number. Obviously it's not going to fit into a paltry 32-bit int...but then we don't need it to. The problem description requires us to think in terms of smaller (5-digit) numbers, not one giant 1000-digit number.&lt;br/&gt;&lt;br/&gt;So, it is sufficient for us to consider the number as an enumerable stream of single digits, which we can conveniently represent as IEnumerable&lt;int&gt;. I could use a macro to convert the number into a collection initialiser, but it's much easier to treat the string as an IEnumerable&lt;char&gt;&amp;lt;char&amp;gt; and let LINQ do the heavy lifting.&lt;/char&gt;&lt;/int&gt;&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var nums = Enumerable.AsEnumerable(&lt;br/&gt;        "73167176531330624919225119674426574742355349194934" +&lt;br/&gt;        "96983520312774506326239578318016984801869478851843" +&lt;br/&gt;&lt;br/&gt;        // ..... etc etc ......&lt;br/&gt;&lt;br/&gt;        "05886116467109405077541002256983155200055935729725" +&lt;br/&gt;        "71636269561882670428252483600823257530420752963450"&lt;br/&gt;        ).Select(x =&gt; Convert.ToInt32(x.ToString()));&lt;/pre&gt;&lt;br/&gt;This gives us an IEnumerable&lt;int&gt;&amp;lt;int&amp;gt; containing every digit in the 1000-digit number. Now, the 'obvious' way to solve the problem is to iterate through the collection, and at each index multiply the value against the next four indexes. A simple loop should deal with it:&lt;/int&gt;&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;private static int SimpleSolver(int[] ints)&lt;br/&gt;{&lt;br/&gt;    int max = 0;&lt;br/&gt;    for (int i = 0; i &lt; ints.Length - 4; i++)&lt;br/&gt;    {&lt;br/&gt;        int tmp = ints[i] * ints[i + 1] * ints[i + 2]&lt;br/&gt;            * ints[i + 3] * ints[i + 4];&lt;br/&gt;        max = Math.Max(max, tmp);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    return max;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;As ever, though, that's pretty ugly - the loop condition and product calculation is tied to the sequence size of 5, and messing with an index variable is tedious.&lt;br/&gt;&lt;br/&gt;An alternative approach is to take advantage of LINQ's Skip and Take methods to split the problem domain into overlapping 'slices'. Similar to the for loop above, the core of the approach is to iterate through the digits, and at each digit grab a number of subsequent digits and calculate the product.&lt;br/&gt;&lt;br/&gt;Lets look at the 5-digit slices available from the first 10 digits:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;  7   3   1   6   7   1   7   6   5   3&lt;br/&gt;|       73167       |&lt;br/&gt;    |       31671       |&lt;br/&gt;        |       16717       |&lt;br/&gt;            |       67176       |&lt;br/&gt;                |       71765       |&lt;br/&gt;                    |       17653       |&lt;/pre&gt;&lt;br/&gt;We can use Skip to progressively move the starting index forward, and Take to grab the 5 digits we need. So, starting with i=0, each successive slice can be sliced from the whole with:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var slice = ints.Skip(i++).Take(5);&lt;/pre&gt;&lt;br/&gt;To calculate the product of the digits in the slice, we can use the Aggregate operation:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;slice.Aggregate(1, (curr, next) =&gt; curr*next);&lt;/pre&gt;&lt;br/&gt;We've met Aggregate before - it's basically a fold, which collapses a sequence to a single item by repeatedly applying an operation to an accumulating result.&lt;br/&gt;&lt;br/&gt;This can all be wrapped up as an iterator block, like so:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;private static IEnumerable&lt;int&gt; EnumerateSlices(&lt;br/&gt;        IEnumerable&lt;int&gt; ints, int sliceSize)&lt;br/&gt;{&lt;br/&gt;    int i = 0;&lt;br/&gt;    while (true)&lt;br/&gt;    {&lt;br/&gt;        var slice = ints.Skip(i++).Take(sliceSize);&lt;br/&gt;&lt;br/&gt;        if (slice.Count() &lt; sliceSize)&lt;br/&gt;            yield break; // end&lt;br/&gt;&lt;br/&gt;        yield return slice.Aggregate(1,&lt;br/&gt;                (curr, next) =&gt; curr*next);&lt;br/&gt;    }&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Note the termination condition - when we have enumerated every slice, our next slice will contain only 4 elements (3, 4, 5, and 0 from the end of the sequence) - that's our cue to exit the loop.&lt;br/&gt;&lt;br/&gt;Also note that this approach makes the algorithm trivial to parameterize - it will work just as well with slice sizes other than 5.&lt;br/&gt;&lt;br/&gt;This iterator will produce an IEnumerable&lt;int&gt; containing the products of all slices, so the final step is to select the largest:&lt;/int&gt;&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var result = EnumerateSlices(nums, 5).Max();&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-6539552734679374963?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/shKFKvahpKQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/6539552734679374963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2009/02/project-euler-problem-8.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/6539552734679374963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/6539552734679374963?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/shKFKvahpKQ/project-euler-problem-8.html" title="Project Euler Problem 8" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2009/02/project-euler-problem-8.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo9eCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-2314128211367731131</id><published>2009-02-08T21:01:00.000Z</published><updated>2011-10-03T10:11:10.460+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.460+01:00</app:edited><title>Killing and Reviving an Aspire One</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/95Vjuee5ktPot4UneGqKjJTly6I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/95Vjuee5ktPot4UneGqKjJTly6I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/95Vjuee5ktPot4UneGqKjJTly6I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/95Vjuee5ktPot4UneGqKjJTly6I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I just spent 2 hours reviving my Aspire One netbook after inadvertently killing it whilst fiddling about configuring &lt;a href="http://www.getdropbox.com"&gt;dropbox&lt;/a&gt;. I found the whole process unnecessarily fiddly and information on the interwebs to be a bit scarcer than I would have liked, so I'm documenting it here in case I need it in the future. Hopefully it'll be useful to someone else too.&lt;br/&gt;&lt;br/&gt;So, the cause of death was a typo when trying to set up the dropboxd daemon to start automatically on boot. I'm not running nautilus so couldn't use one of the prepackaged releases, and it's completely my fault that I made a mess of installing the vanilla x86 build.&lt;br/&gt;&lt;br/&gt;After making the fatal change and rebooting, the system would only boot up to a blank black screen with a default X mouse cursor. This is because the system was trying to run my broken command, failing, and therefore never getting to the main desktop.&lt;br/&gt;&lt;br/&gt;In the world of normal linux, there's all sorts of ways of dealing with this, but despite plenty of googling I couldn't find a way to use run-level 2 or 3 on an Aspire One, and the Ctrl+Alt+F1-F6 key combos for switching away from X to a terminal don't work either. There seems to be no way of preventing the system following the same doomed process over and again if you break X.&lt;br/&gt;&lt;br/&gt;Frustrated, I thought about using the restore disk, but that's a nuclear option - it re-paves the whole machine, so bye-bye data. That seemed a bit drastic when all I needed to do was edit a single text file to fix the system.&lt;br/&gt;&lt;br/&gt;Ironically, this was happening as a result of me trying to install a file sync system as a simple backup. Grr.&lt;br/&gt;&lt;br/&gt;Still, like countless thousands before me, I was saved by a live linux distro - in this case, a USB bootable one (since the Aspire One has no optical drive). Following the &lt;a href="http://www.pendrivelinux.com/feather-linux-on-usb/"&gt;instructions&lt;/a&gt;&lt;sup&gt;[1]&lt;/sup&gt; at &lt;a href="http://www.pendrivelinux.com/"&gt;pendrivelinux&lt;/a&gt; I created a bootable Feather Linux USB drive, and booted the netbook from it by hitting F12 on the post screen and selecting to boot from the USB stick.&lt;br/&gt;&lt;br/&gt;At the boot prompt, I used 'knoppix 3' to boot the system up to a command line, mounted /dev/hdc1 as an ext2 filesystem, and fixed my typo. Reboot, and tada! Everything was working again (well, after hitting Fn-F7 to reenable the touchpad, which I had accidentally disabled whilst mashing the keyboard in frustration at the sight of a blank screen about an hour earlier, heh).&lt;br/&gt;&lt;br/&gt;&lt;sup&gt;[1]&lt;/sup&gt; Note that I had to use a newer version of syslinux than the one referenced on pendrivelinux. &lt;a href="http://www.kernel.org/pub/linux/utils/boot/syslinux/Old/syslinux-3.36.zip"&gt;This one &lt;/a&gt;worked for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-2314128211367731131?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/s44RfZTEsZk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/2314128211367731131/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2009/02/killing-and-reviving-aspire-one.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2314128211367731131?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2314128211367731131?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/s44RfZTEsZk/killing-and-reviving-aspire-one.html" title="Killing and Reviving an Aspire One" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2009/02/killing-and-reviving-aspire-one.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXozfCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-4717955348529020260</id><published>2009-02-06T15:03:00.000Z</published><updated>2011-10-03T10:11:10.484+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.484+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><title>Macros: You Oughta Know</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BFiuhCPrUCtLz0tWHZmIEZ6o5zY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BFiuhCPrUCtLz0tWHZmIEZ6o5zY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BFiuhCPrUCtLz0tWHZmIEZ6o5zY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BFiuhCPrUCtLz0tWHZmIEZ6o5zY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;One of the most useful tools available in any decent text editor is the macro recorder, but it's criminally underused. It seems most people either don't know the functionality exists, or simply ignore it. This is a shame, since it's a great timesaver.&lt;br/&gt;&lt;br/&gt;I don't know why macros are so underused. It might be a mindset thing - it can take a little while to develop the ability to spot repetitive editing tasks quickly (i.e. not when you're 75% of the way through thinking &lt;em&gt;dang, I have to do this again?&lt;/em&gt;), so maybe many people never quite make the leap.&lt;br/&gt;&lt;br/&gt;It's worth it though, because once you get your eye in you see chances to use macros everywhere.&lt;br/&gt;&lt;br/&gt;I had a useful example just yesterday, in which I needed to make a change to a colossal switch statement (220 branches! Run the cyclomatic-complexity doohickey on THAT!) and had no unit tests to fall back on.&lt;br/&gt;&lt;br/&gt;If I had to modify (and hopefully refactor) such a huge construct I wanted to be able to compare before-and-after test results, but I didn't much fancy hand-cranking a few hundred unit tests.&lt;br/&gt;&lt;br/&gt;By recording a temporary macro, however, it took just a couple of minutes to cover every branch. I've decided to post a detailed walkthrough of the process here in the hopes that a fairly simple example will be illustrative for those that don't already lean heavily on macros.&lt;br/&gt;&lt;br/&gt;Note that &lt;em&gt;this is not an advanced tutorial&lt;/em&gt;. Please refrain from leaving snarky comments about how macros are so much more powerful than this - I'm just doing some introductory material here :-)&lt;br/&gt;&lt;br/&gt;Here is a representative snippet of the C# source. It's part of a legacy permissioning system that, under certain circumstances, needs to check for the existence of a permission represented by an enum against a permission table containing a string-based hierarchy (application/role/permission). The code I was modifying did the appropriate conversion:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;    case PermissionKey.SecurityParameterManagementAdd:&lt;br/&gt;    {&lt;br/&gt;        return new string[] {"Security", "ParameterManagement", "Add"};&lt;br/&gt;    }&lt;br/&gt;    case PermissionKey.SecurityRoleManagementAdd:&lt;br/&gt;    {&lt;br/&gt;        return new string[] {"Security", "RoleManagement", "Add"};&lt;br/&gt;    }&lt;br/&gt;    case PermissionKey.SecurityRoleManagementModify:&lt;br/&gt;    {&lt;br/&gt;        return new string[] {"Security", "RoleManagement", "Modify"};&lt;br/&gt;    }&lt;br/&gt;    case PermissionKey.SecurityUserManagementDelete:&lt;br/&gt;    {&lt;br/&gt;        return new string[] {"Security", "UserManagement", "Delete"};&lt;br/&gt;    }&lt;br/&gt;    case PermissionKey.SecurityPermissionManagementAdd:&lt;br/&gt;    {&lt;br/&gt;        return new string[] {"Security", "PermissionManagement", "Add"};&lt;br/&gt;    }&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;I needed to add a couple of branches to this, but I also wanted to tidy up the code by removing the superfluous braces, as a precursor to converting it into something a bit more robust and maintainable. I wanted unit test coverage to give me confidence that I hadn't mucked up some logic and inadvertantly granted admin access to the helpdesk trainee role or something.&lt;br/&gt;&lt;br/&gt;So, I copied the entire switch body into Notepad++ (well, vim really, but I'll pretend it's Notepad++ for the sake of making this post a bit more accessible) and set to work&lt;sup&gt;[1]&lt;/sup&gt;.&lt;br/&gt;&lt;br/&gt;Before recording my macro, I needed to do a bit of preprocessing to trim the code down to just the data I wanted to work with. The following steps show the 'find' regexes I used (in each case, the value of the replace field was empty, so these are effectively deletes), and the effect on the first switch branch from the list above:&lt;br/&gt;&lt;br/&gt;1) Remove opening and closing braces from every switch branch:&lt;br/&gt;&lt;pre&gt;^\s+[\{\}]$&lt;/pre&gt;&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;    case PermissionKey.SecurityParameterManagementAdd:&lt;br/&gt;&lt;br/&gt;        return new string[] {"Security", "ParameterManagement", "Add"};&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;2) Remove blanks - TextFX/Edit/Delete Blank Lines&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;    case PermissionKey.SecurityParameterManagementAdd:&lt;br/&gt;        return new string[] {"Security", "ParameterManagement", "Add"};&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;3) Remove case statements and leading whitespace:&lt;br/&gt;&lt;pre&gt;^\s+case\s+&lt;/pre&gt;&lt;br/&gt;&lt;pre lang="csharp"&gt;PermissionKey.SecurityParameterManagementAdd:&lt;br/&gt;PermissionKey.SecurityParameterManagementAdd:&lt;br/&gt;        return new string[] {"Security", "ParameterManagement", "Add"};&lt;/pre&gt;&lt;br/&gt;4) Remove colon from end of case statement:&lt;br/&gt;&lt;pre&gt;:$&lt;/pre&gt;&lt;br/&gt;5) Remove return statement and leading whitespace:&lt;br/&gt;&lt;pre&gt;^\s+return new string\[\]\s*&lt;/pre&gt;&lt;br/&gt;I ended up with a sequence of couplets looking similar to this one:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;PermissionKey.SecurityParameterManagementAdd&lt;br/&gt;{"Security", "ParameterManagement", "Add"};&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;Now the fun starts - lets walk through the process.&lt;br/&gt;&lt;br/&gt;We want to convert the first couplet into a simple unit test fixture, and record the process. This will be our macro - the instructions for converting one couplet into one unit test. We can then play the macro multiple times to convert all the others effortlessly.&lt;br/&gt;&lt;br/&gt;Start by moving the cursor to the start of the line, before the 'P' of PermissionKey. This is the start point of the macro, so for the macro to be repeatable we must make sure that we finish recording the macro in perfect position to run it again, i.e. before the 'P' of PermissionKey for the next couplet (column 0 line 3). Hit Ctrl-Shift-R to start recording.&lt;br/&gt;&lt;br/&gt;It is important not to use the mouse when editing - stick to the keyboard. It's also important not to record keystrokes that are too specific to one bit of code. For instance, don't use the arrow keys to move left and right character-by-character, because it won't work on longer or shorter lines.&lt;br/&gt;&lt;br/&gt;Instead, use the Home and End keys to jump to the start or end of the line, and hold Ctrl whilst arrowing left or right to move a word at a time instead of a character at a time (this is one of the areas where vim's movement commands really differentiate it from wannabes like Notepad++...but I digress). See the 'Detailed Instructions' section below for more information.&lt;br/&gt;&lt;br/&gt;Assume the original switch body is in a method called 'LookupEnumPermission'. The couplet should be edited to look like this (without the linewrap...):&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;[Test]&lt;br/&gt;public void TestSecurityParameterManagementAdd()&lt;br/&gt;{&lt;br/&gt;    string[] result = LookupEnumPermission(&lt;br/&gt;            PermissionKey.SecurityParameterManagementAdd);&lt;br/&gt;    Assert.AreEqual("Security", result[0]);&lt;br/&gt;    Assert.AreEqual("ParameterManagement", result[1]);&lt;br/&gt;    Assert.AreEqual("Add", result[2]);&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Make sure you finish by moving the cursor into position for the next couplet, and hit Ctrl-Shift-R again to stop recording.&lt;br/&gt;&lt;br/&gt;Now, hit Ctrl-Shift-P to play back the macro. If you've done everything right, the next couplet should magically format itself into a unit test. Hit Ctrl-Shift-P again, and the next couplet will change too. Under the Macro menu, select 'Run a macro multiple times...' and you can enter a fixed number of iterations, or just apply the macro over and over again until the end of the file is reached.&lt;br/&gt;&lt;br/&gt;Finally, you can copy the unit tests into a new or existing test fixture, and you're done! In much less time (hopefully) and with fewer errors than if the tests had been written one-by-one.&lt;br/&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;Detailed Instructions:&lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;These are ley-by-key instructions in Notepad++, in case something in the description above is unclear. Visual Studio should be similar. Vim will be faster once you've learned how, but I'll assume if you use vim you're already au fait with this sort of editing :-)&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;Type [Test], and hit enter to start a new line.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Type 'public void Test' and hit Enter.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Type '{' and hit Enter, then Tab.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Hold Ctrl and tap the right arrow twice to jump over a couple of words and place the cursor at the start of the word SecurityParameterManagementAdd, then hold Ctrl-Shift and right arrow again to select the word. Ctrl-C to copy, then arrow up two lines and paste it after the word 'Test' to create the full function name TestSecurityParameterManagementAdd. Type () for the empty parameter list.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Arrow down two lines and hit Home to jump to the start of the line. Type 'string[] result = LookupEnumPermission(', then hit End to jump to the end of the line and type ');'.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Arrow down one line, hit Home, then Tab. Type 'Assert.Equals(' then hit Delete to remove the '{'. Hold Ctrl and move right three times (to move the cursor just past the comma) and type 'result[0]);' and hit Enter.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Repeat variations of step 7 a couple of times to convert the next two lines. Remember to use the correct indexes (result[1] and result[2]). Hit Enter after the last line and type '}' to close the function body.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt; Arrow down one line and hit Home to place the cursor at the correct start position for the next couplet, and end the macro by hitting Ctrl-Shift-R again.&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;&lt;sup&gt;[1]&lt;/sup&gt;I could have just done this in a new file in Visual Studio, but for some reason I find VS intolerably slow at running macros once recorded. So slow, in fact, that you can watch the cursor laboriously complete each step - I wind up thinking it would have been quicker to do it manually. That might just be something odd about my VS installation though, as no-one else seems to think it's slow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-4717955348529020260?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/3U76FvjBtfk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/4717955348529020260/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2009/02/macros-you-oughta-know.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/4717955348529020260?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/4717955348529020260?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/3U76FvjBtfk/macros-you-oughta-know.html" title="Macros: You Oughta Know" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2009/02/macros-you-oughta-know.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXs7fSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-832233967385185421</id><published>2009-01-16T16:00:00.000Z</published><updated>2011-10-03T10:11:10.505+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.505+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><title>OOD - The Second Coming?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LGxupfqNB5BA68DqM4n22GBD2t8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LGxupfqNB5BA68DqM4n22GBD2t8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LGxupfqNB5BA68DqM4n22GBD2t8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LGxupfqNB5BA68DqM4n22GBD2t8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Over the last couple of months I've been burning up my free time on a pet project (hence the scarcity of posting here). This particular project is a web application, and since I've always been a desktop or middle-tier dude in my day job, it's a bit of a step out of my normal environment to grapple with browser compatibility and suchlike.&lt;br/&gt;&lt;br/&gt;Still, I wanted it to be a decent learning experience, so after a brief dalliance with Rails I scrapped the idea of using any &lt;a href="http://basildoncoder.com/blog/2007/12/09/coding-by-convention/"&gt;framework sorcery&lt;/a&gt; and decided to write everything in plain ol' &lt;a href="http://php.net/"&gt;PHP&lt;/a&gt;, and lean heavily on &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt; and &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; to sort out the browser stuff.&lt;br/&gt;&lt;br/&gt;This probably isn't an approach I'd use in future projects, but I bet I'll appreciate those frameworks a lot more once I've encountered and understood the problems they attempt to solve.&lt;br/&gt;&lt;br/&gt;So, having strayed from the comfort of &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; and its clones, I had to think about lots of things like security, validation, data access, and how to organise my code. Just because I'd abandoned the training wheels I had no intention of falling over all the time - I still wanted a nice, maintainable app with sensible  abstractions, properly decoupled, and resilient to failure. Time to start reading articles and the odd open source project, obviously.&lt;br/&gt;&lt;br/&gt;It's at this point I noticed something interesting. Since I regularly read plenty of development websites it could scarcely have escaped my notice that the trendy framework players (e.g. Rails, Django, Cake, ASP.NET MVC) strongly advocate the &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;MVC&lt;/a&gt; pattern and &lt;a href="http://en.wikipedia.org/wiki/Class-based_programming"&gt;class-based object-oriented design&lt;/a&gt;. What I hadn't really realised until now is how endemic that viewpoint had become.&lt;br/&gt;&lt;br/&gt;In fact, beyond a few admirably out-there frameworks like &lt;a href="http://www.seaside.st/"&gt;Seaside&lt;/a&gt;, it's almost universal. OOD = good, EVERYTHING ELSE = bad. MVC = good, EVERYTHING ELSE = bad. No shades of grey, no room for dissenting opinion.&lt;br/&gt;&lt;br/&gt;Go anywhere where best-practices are discussed and mention you're writing some procedural code, and watch the fireworks. It doesn't matter if your application has fewer lines of code than a newly-created Rails app has source files - if you haven't structured it with models, views, and controllers you may as well have written it in Visual Basic for all the bile you're going to have thrown at you.&lt;br/&gt;&lt;br/&gt;If you say you're writing functional code, you might get away with it, since functional programming is still widely misunderstood and you'll likely be classified as some weird LISPer or Schemer doing something arcane and thus ignored.&lt;br/&gt;&lt;br/&gt;Ironically, of course, if you grab a random Rails/Django/Cake app from &lt;a href="http://github.com/"&gt;github&lt;/a&gt; or &lt;a href="http://code.google.com/hosting/"&gt;Google Code&lt;/a&gt;, there's a pretty fair chance that what you'll find isn't particularly object-oriented anyway. Hint - usage of the 'class' keyword does not an object-oriented design make. And sweet zombie Jesus, I've never seen such abuse of the singleton pattern. That's a sure sign someone doesn't 'get' OO - the &lt;a href="http://c2.com/cgi/wiki?SingletonsAreEvil"&gt;singleton pattern is evil&lt;/a&gt; and basically a way to &lt;a href="http://steve.yegge.googlepages.com/singleton-considered-stupid"&gt;shoehorn globals into an application&lt;/a&gt; without admitting it to your friends.&lt;br/&gt;&lt;br/&gt;So, we have massive fanatical advocacy of a technique that will allegedly solve all your problems, coupled with large-scale real-world misunderstandings and misapplication. Does this remind anyone of anything? Say, for example, the last time OOD swept the world, panacea to all programming woes, about 20 or so years ago?&lt;br/&gt;&lt;br/&gt;Don't get me wrong, I'm not arguing that class-based OO itself is just a fad - it deserves its place as a paradigm alongside procedural, functional, parallel, and numerous others. It's the heralding of OO as the one true way that seems faddish.&lt;br/&gt;&lt;br/&gt;So, in the very best "bah, humbug" traditions I've written my app in unashamedly procedural PHP code. I don't mix my presentation and content. My data layer is decoupled and unit tested. Every bit of SQL is a parameterised query, to guard against injection. I don't have a single echo() statement containing any html tags. All my errors are exception based, and I don't have a single die() call anywhere. My average function size is about 10 lines, and my longest is about 20. I've no doubt that there's a legion of 15-year-old self-appointed geniuses ready to accuse me of inflicting yet more spaghetti code junk on the world just because "find . -iname '*php' | xargs grep class" comes up empty, but hey I'm OK with that.&lt;br/&gt;&lt;br/&gt;I'm writing my next app in &lt;a href="http://en.wikipedia.org/wiki/Brainfuck"&gt;brainf*ck&lt;/a&gt; using ed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-832233967385185421?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/eT8e6uxcXfU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/832233967385185421/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2009/01/ood-second-coming.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/832233967385185421?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/832233967385185421?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/eT8e6uxcXfU/ood-second-coming.html" title="OOD - The Second Coming?" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2009/01/ood-second-coming.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXozfip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-5032318045692489402</id><published>2008-10-26T21:58:00.000Z</published><updated>2011-10-03T10:11:10.486+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.486+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 7</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5x-jDQOXYqS-Y8lQh5Riii5Qj1I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5x-jDQOXYqS-Y8lQh5Riii5Qj1I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5x-jDQOXYqS-Y8lQh5Riii5Qj1I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5x-jDQOXYqS-Y8lQh5Riii5Qj1I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;em&gt;&lt;strong&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=7"&gt;Problem 7&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;blockquote&gt;By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6&lt;sup&gt;th&lt;/sup&gt; prime is 13.&lt;br/&gt;&lt;br/&gt;What is the 10001&lt;sup&gt;st&lt;/sup&gt; prime number?&lt;/blockquote&gt;&lt;br/&gt;Ah, what a nice, straightforward, unambiguous spec! If only business software specifications were so precise.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://basildoncoder.com/blog/2008/04/07/project-euler-problem-3/"&gt;Way back in problem 3&lt;/a&gt;, I took a bit of a wander off-topic and built a prime generator in .Net using the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt;. Armed with this, problem 7 should be easy, right? The sieve implementation generates an IEnumerable&lt;long&gt;, which is non-indexable (i.e. I can't just say Primes()[10001]), but I can take the first 10,001 and then ask for the last element, which will be the answer to the problem.&lt;br/&gt;&lt;/long&gt;&lt;br/&gt;&lt;br/&gt;There's a problem with this, however. The sieve requires an upper bound during initialisation. This means it's great for solving problems like "generate all the primes less than 10,001", but not so great at answering questions like "what is the 10,001st prime number?", since it requires foreknowledge of the upper bound.&lt;br/&gt;&lt;br/&gt;To illustrate the problem, I'll take a wild guess at the upper bound. I'm going to guess that the 10,001st prime number is less than 99,999. What happens?&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var sieve = new SieveOfEratosthenes(99999);&lt;br/&gt;var result = sieve.Primes().Take(10001).Last();&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;This generates an answer of 99,991. If I enter this into the Project Euler website, however, it tells me the answer is wrong. Gah! What went wrong? A simple test reveals the problem:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var sieve = new SieveOfEratosthenes(99999);&lt;br/&gt;var primes = sieve.Primes().Take(10001);&lt;br/&gt;var count = primes.Count();&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;There's only 9,592 primes generated! As the &lt;a href="http://msdn.microsoft.com/en-us/library/bb503062.aspx"&gt;docs for Take()&lt;/a&gt; state (emphasis mine):&lt;br/&gt;&lt;blockquote&gt;Take&amp;lt;TSource&amp;gt;&lt;tsource&gt; enumerates source and yields elements until count elements have been yielded &lt;em&gt;or source contains no more elements&lt;/em&gt;.&lt;/tsource&gt;&lt;/blockquote&gt;&lt;br/&gt;Damn. So, looks like my 99,999 guess was too small - with that as an upper bound, the sieve only finds 9,592 primes, and I need the 10,001st. OK, I'll bump it up by an order of magnitude:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var sieve = new SieveOfEratosthenes(999999);&lt;br/&gt;var result = sieve.Primes().Take(10001).Last();&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;This gives me the correct answer. Not exactly a wonderful solution though; the idea of having to guess the upper bound is pretty horrendous, and if this was real code it wouldn't be particularly maintainable - what if the requirements changed and we had to find the &lt;em&gt;n&lt;/em&gt;th prime, which happened to be &amp;gt;99,999? We'd have to guess again. Ugh.&lt;br/&gt;&lt;br/&gt;Worse, the sieve algorithm precomputes all the primes up to the specified upper bound, meaning that in the above approach I've asked the sieve to generate primes up to 999,999 (all 78,498 of them!) despite only needing 10,001. Not very efficient.&lt;br/&gt;&lt;br/&gt;Fortunately, the upper bound can be calculated separately. &lt;a href="http://primes.utm.edu/howmany.shtml" aiotarget="false" aiotitle="Where n &amp;gt;8601, as in this case, we can use the following equation"&gt;Where &lt;em aiotitle="n"&gt;n&lt;/em&gt;&amp;gt;8601, as in this case, we can use the following equation&lt;/a&gt;:&lt;br/&gt;&lt;pre&gt;p(&lt;em&gt;n&lt;/em&gt;) &lt;u&gt;&amp;lt;&lt;/u&gt; &lt;em&gt;n&lt;/em&gt; (log&lt;sub&gt;e&lt;/sub&gt; &lt;em&gt;n&lt;/em&gt; + log&lt;sub&gt;e&lt;/sub&gt; log&lt;sub&gt;e&lt;/sub&gt; &lt;em&gt;n&lt;/em&gt; - 0.9427)&lt;/pre&gt;&lt;br/&gt;where p(&lt;em&gt;n&lt;/em&gt;) is the &lt;em&gt;n&lt;/em&gt;th prime number.&lt;br/&gt;&lt;br/&gt;Alternatively, for flexibility in handling &lt;em&gt;n&lt;/em&gt;&amp;lt;8601, we can use the less accurate&lt;br/&gt;&lt;pre&gt;p(&lt;em&gt;n&lt;/em&gt;) &amp;lt; &lt;em&gt;n&lt;/em&gt; log&lt;sub&gt;e&lt;/sub&gt; log&lt;sub&gt;e&lt;/sub&gt; &lt;em&gt;n&lt;/em&gt;&lt;/pre&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number"&gt;which works for &lt;em&gt;n&lt;/em&gt;&amp;gt;5&lt;/a&gt;. We can easily precompute the answers for &lt;em&gt;n&lt;/em&gt;&amp;lt;=5, or simply calculate on demand.&lt;br/&gt;&lt;br/&gt;The formula can be implemented on the sieve class, with a factory method to help when we want to use it:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;public static SieveOfEratosthenes&lt;br/&gt;    CreateSieveWithAtLeastNPrimes(int n)&lt;br/&gt;{&lt;br/&gt;    return new SieveOfEratosthenes((long)&lt;br/&gt;            Math.Ceiling(UpperBoundEstimate(n)));&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;private static double UpperBoundEstimate(int n)&lt;br/&gt;{&lt;br/&gt;    return n * Ln(n) + n * (Ln(Ln(n)));&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;private static double Ln(double n)&lt;br/&gt;{&lt;br/&gt;    return Math.Log(n, Math.E);&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;This leaves us with an overall solution like so:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;var sieve = SieveOfEratosthenes.CreateSieveWithAtLeastNPrimes(10001);&lt;br/&gt;var result = sieve.Primes().Take(10001).Last();&lt;/pre&gt;&lt;br/&gt;This generates a total 10,018 primes, cutting the wasted effort from almost 70,000 superfluous primes to just 17, and takes around 20ms to execute on my machine. Plenty fast enough, I think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-5032318045692489402?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/RogHisNK5IA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/5032318045692489402/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/10/project-euler-problem-7.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/5032318045692489402?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/5032318045692489402?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/RogHisNK5IA/project-euler-problem-7.html" title="Project Euler Problem 7" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/10/project-euler-problem-7.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo_eyp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-1343210370072038307</id><published>2008-10-24T15:32:00.000+01:00</published><updated>2011-10-03T10:11:10.443+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.443+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><title>Look Before You Look Before You Leap</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TbG7wKNcHL3m7QPeeXjdwMm6UB0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TbG7wKNcHL3m7QPeeXjdwMm6UB0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TbG7wKNcHL3m7QPeeXjdwMm6UB0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TbG7wKNcHL3m7QPeeXjdwMm6UB0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Generally, I try to avoid turning this blog into some sort of &lt;a href="http://www.google.co.uk/search?q=define%3Asnark"&gt;snark&lt;/a&gt;-fest about other programmers or blogs. I've disagreed with Jeff Atwood &lt;a href="http://basildoncoder.com/blog/2008/02/22/code-can-be-beautiful/"&gt;once&lt;/a&gt; or &lt;a href="http://basildoncoder.com/blog/2008/01/29/freedom-zero-the-all-or-nothing-fallacy/"&gt;twice&lt;/a&gt; though, and so by posting this I'm probably straying a little close to the edge...but what the hell.&lt;br/&gt;&lt;br/&gt;A couple of days ago Coding Horror carried a &lt;a href="http://www.codinghorror.com/blog/archives/001177.html"&gt;fluff piece&lt;/a&gt; about how all developers should be marketers too. Predictably, the article soon got posted to &lt;a href="http://www.reddit.com/r/programming/"&gt;proggit&lt;/a&gt; where it was &lt;a href="http://www.reddit.com/r/programming/comments/78vq3/jeff_atwood_finally_jumps_the_shark/"&gt;ripped on by reddit's resident Jeff-haters&lt;/a&gt;, and even more predictably the comments were a mix of interesting insight and barely-concealed hate.&lt;br/&gt;&lt;br/&gt;Apparently some of them got up Jeff's nose a bit, and today he &lt;a href="http://www.codinghorror.com/blog/archives/001178.html"&gt;responded&lt;/a&gt;. The core of his rebuttal seems to be that you shouldn't trust what you read on blogs, and should verify everything yourself. True enough, I guess, if perhaps a bit impractical given the sheer amount of information out there.&lt;br/&gt;&lt;br/&gt;Then, however, Jeff goes on to give an example by referencing a &lt;a href="http://blog.madskristensen.dk/post/Compression-and-performance-GZip-vs-Deflate.aspx"&gt;compression benchmark&lt;/a&gt; he'd read on a blog and providing counter-analysis to show that the benchmark was wrong in claiming Deflate is faster than gzip. In doing so, much knowledge was gained.&lt;br/&gt;&lt;br/&gt;Or so we are told.&lt;br/&gt;&lt;br/&gt;The comment thread quickly becomes a goldmine of humour. Bugs in Jeff's benchmarking code (not resetting the stopwatch) meant that the durations were cumulative, not independent, with inevitable distortion of the results. Another commenter pointed out that &lt;a href="http://en.wikipedia.org/wiki/Gzip"&gt;gzip&lt;/a&gt; cannot possibly be faster than Deflate, since the gzip algorithm IS the Deflate algorithm plus some additional computation.&lt;br/&gt;&lt;blockquote&gt;“gzip” is often also used to refer to the gzip file format, which is:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;a 10-byte header, containing a magic number, a version number and a timestamp&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;optional extra headers, such as the original file name,&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;a body, containing a DEFLATE-compressed payload&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;an 8-byte footer, containing a CRC-32 checksum and the length of the original uncompressed data&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;p align="right"&gt;&lt;a href="http://en.wikipedia.org/wiki/Gzip"&gt;http://en.wikipedia.org/wiki/Gzip&lt;/a&gt;&lt;/p&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;br/&gt;With the benchmarking code fixed, we see that Deflate is indeed slightly faster than gzip.&lt;br/&gt;&lt;br/&gt;All of which leads to repeated quotations from Jeff about the community being smarter than him, and some drastic toning down of language in post-publication edits to the article. I read a cached version of the RSS feed, which is markedly different to the article currently live on codinghorror.com - "on my box, GZip is twice as fast as Deflate" becomes "on my box, GZip is just as fast as Deflate", "Deflate is way slower. It's not even close" becomes "Deflate is nowhere near 40% faster", etc.&lt;br/&gt;&lt;br/&gt;&lt;img src="http://basildoncoder.com/images/codinghorror01.png" align="middle" /&gt;&lt;br/&gt;&lt;br/&gt;Anyone who's tackled a major performance problem will likely agree that profiling is a tremendously valuable technique that should always be applied before attempting to optimise (i.e. look before you leap). I think this little episode has highlighted a couple of important things to bear in mind, however:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;Profiling isn't a magic wand - if you use buggy profiling code, you are leading yourself up the garden path.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Profiling is less useful when you can reason (in the mathematical sense) about the code. That involves &lt;em&gt;understanding the algorithms you are dealing with&lt;/em&gt;. Gzip is Deflate plus a bit more processing - so unless that extra processing has a negative duration gzip must necessarily take longer. You don't need a profiler to work that out. Look &lt;em&gt;before &lt;/em&gt;you look before you leap.&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;Anyway, enough hatcheting from me, normal service will be resumed shortly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-1343210370072038307?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/JDc36RtaMvg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/1343210370072038307/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/10/look-before-you-look-before-you-leap.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1343210370072038307?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1343210370072038307?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/JDc36RtaMvg/look-before-you-look-before-you-leap.html" title="Look Before You Look Before You Leap" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/10/look-before-you-look-before-you-leap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXozeSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-4056328189497344166</id><published>2008-08-14T01:00:00.000+01:00</published><updated>2011-10-03T10:11:10.481+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.481+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 6</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sLi_oVcp2nGr6CGe6FGZL3U4GAs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sLi_oVcp2nGr6CGe6FGZL3U4GAs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sLi_oVcp2nGr6CGe6FGZL3U4GAs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sLi_oVcp2nGr6CGe6FGZL3U4GAs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="problem_content"&gt;Onwards to...&lt;/p&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=6"&gt;Problem 6&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;blockquote&gt;The sum of the squares of the first ten natural numbers is,&lt;br/&gt;&lt;p style="text-align: center"&gt;1&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;2&lt;/sup&gt; + ... + 10&lt;sup&gt;2&lt;/sup&gt; = 385&lt;/p&gt;&lt;br/&gt;The square of the sum of the first ten natural numbers is,&lt;br/&gt;&lt;p style="text-align: center"&gt;(1 + 2 + ... + 10)&lt;sup&gt;2&lt;/sup&gt; = 55&lt;sup&gt;2&lt;/sup&gt; = 3025&lt;/p&gt;&lt;br/&gt;Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 &lt;img src="http://projecteuler.net/images/symbol_minus.gif" style="vertical-align: middle" border="0" width="9" height="3" /&gt; 385 = 2640.&lt;br/&gt;&lt;br/&gt;Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.&lt;/blockquote&gt;&lt;br/&gt;Bit of a disappointment, problem 6; it's too easy. &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;sort=difficulty"&gt;It's rated as the third-easiest&lt;/a&gt;, i.e. easier than problems &lt;a href="http://basildoncoder.com/blog/2008/04/07/project-euler-problem-3/"&gt;3&lt;/a&gt;, &lt;a href="http://basildoncoder.com/blog/2008/04/21/project-euler-problem-4/"&gt;4&lt;/a&gt;, and &lt;a href="http://basildoncoder.com/blog/2008/06/10/project-euler-problem-5/"&gt;5&lt;/a&gt; which I've already covered. In fact, for my money it's easier than problem &lt;a href="http://basildoncoder.com/blog/2008/03/22/project-euler-problems-1-and-2/"&gt;2&lt;/a&gt; as well. Ah well, the difficulty ramps up soon enough, trust me.  Here's the very simple python solution:&lt;br/&gt;&lt;pre lang="python"&gt;&lt;br/&gt;sum_sq = sum([ x*x for x in xrange(1, 101)])&lt;br/&gt;sq_sum = sum(xrange(1, 101)) ** 2&lt;br/&gt;&lt;br/&gt;print sq_sum - sum_sq&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;As you can see, it's pretty intuitive. You sum the squares, square the sum, and calculate the difference. The answer is basically in the description, you just have to scale up a little.&lt;br/&gt;&lt;br/&gt;There's not much else to say about this one. Even if I abandon the functional approach and write a straightforward imperative solution it's still very straightforward. In (deliberately non-idiomatic, so don't whine at me) ruby:&lt;br/&gt;&lt;pre lang="ruby"&gt;&lt;br/&gt;sum_of_squares = 0&lt;br/&gt;sum = 0&lt;br/&gt;&lt;br/&gt;1.upto 100 do |x|&lt;br/&gt;    sum_of_squares += x * x&lt;br/&gt;    sum += x&lt;br/&gt;end&lt;br/&gt;&lt;br/&gt;p (sum * sum) - sum_of_squares&lt;br/&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-4056328189497344166?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/KgBQ6c0A1D8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/4056328189497344166/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/08/project-euler-problem-6.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/4056328189497344166?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/4056328189497344166?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/KgBQ6c0A1D8/project-euler-problem-6.html" title="Project Euler Problem 6" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/08/project-euler-problem-6.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo9eyp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-2673024050667139089</id><published>2008-08-13T13:48:00.000+01:00</published><updated>2011-10-03T10:11:10.463+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.463+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><title>Magic Numbers and Other Numerical Nightmares</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xR8IXGfyVx0TnY2UOkqiwZGTEKo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xR8IXGfyVx0TnY2UOkqiwZGTEKo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xR8IXGfyVx0TnY2UOkqiwZGTEKo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xR8IXGfyVx0TnY2UOkqiwZGTEKo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;There are many coding practices that are near-universally regarded as 'bad', yet somehow keep cropping up over and over again. Conditional-branch abuse (including, yes, gotos). Deep nesting. Cryptic variable names. Global variables. Tight coupling. Entangled business/presentation logic. I could go on.&lt;br/&gt;&lt;br/&gt;Why do we keep doing it? Convenience? Laziness? Tiredness? Is unreadable spaghetti code some sort of steady-state/equilibrium for code? Is it a natural consequence of the vague and squidgy limitations of our evolved monkey-brains? Or is well-designed code abhorred like a vacuum and naturally atrophies into the sort of shambles you dread seeing on your first day at a new job, unless well-intentioned and dedicated people actively work to clean and polish it, like the &lt;a href="http://en.wikipedia.org/wiki/Forth_Railway_Bridge#Maintenance"&gt;Forth Bridge&lt;/a&gt;?&lt;br/&gt;&lt;br/&gt;I don't have the time or wit to give this subject the treatment it deserves, but I do want to rant a bit about another symptom of this disease, which has given me a couple of sleepless nights recently. I refer, as the title might suggest, to &lt;a href="http://en.wikipedia.org/wiki/Magic_number_(programming)"&gt;magic numbers&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Magic numbers are constants, &lt;a href="http://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constant"&gt;unnamed&lt;/a&gt; in the most pathological cases, that represent an assumption or a limit in a piece of code. They often cause problems because soon they are forgotten about or their meaning is lost - and then something happens to invalidate the assumption, the code breaks, and all hell breaks loose.&lt;br/&gt;&lt;br/&gt;Magic numbers, to stretch the definition a bit, can also be implicit. If you are using a 32-bit integer, your magic number is 2,147,483,647 - that's the biggest number you can store in that type. Often, movement up to and beyond these ranges can trigger long-dormant bugs that are no fun at all to diagnose.&lt;br/&gt;&lt;br/&gt;Three times in recent history I've been bitten by bugs of this class, triggered by auto-incrementing sequences in database. These are they:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;A table in a database had a 32-bit integer primary key. At the time this seemed like a perfectly reasonable default, but insanely fast growth in usage of the system meant that the ~2.1billion upper limit of that data type was quickly reached. The DB column was switched to a 64-bit integer, but some of the client applications reading that table were not identified as at-risk. When the sequence generator left the 32-bit range, those applications overflowed. This happened at 4:30pm on a Friday afternoon. Saturdays were peak-times for system usage. You can imagine the frantic hacking that ensued.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;A sequence generator for a particular entity was started at 20,000,000, so as not to clash with the ID sequence of a related entity (that had started at 0 a good few years earlier). The similarity between the entities and the need to not have the IDs overlap had valid business justification, but the magic number was selected arbitrarily and promptly forgotten. Inevitably, the latter sequence surpassed that number, causing bizarre and difficult-to-trace entity relationship corruption that manifested as strangely-disappearing data on the front-end.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;A stored procedure parameter was incorrectly declared as an OracleType.Float, when it should have been an OracleType.Int32. This resulted in the value being cast from an integer to a floating-point and back again. For the first 16,777,216 integers, this happens to work OK. For the value 16,777,217, however, the loss in precision means that the number changes during casting. This simple bit of (heavily contrived) code shows the problem:&lt;br/&gt;&lt;pre lang="csharp"&gt;&lt;br/&gt;static void Main(string[] args)&lt;br/&gt;{&lt;br/&gt;    for (int i = 0; i &lt; 17000000; ++i)&lt;br/&gt;    {&lt;br/&gt;        if (i != (int)(float)i)&lt;br/&gt;        {&lt;br/&gt;            Console.WriteLine("{0} != {1}", i, (int)(float)i);&lt;br/&gt;            break;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;There are many numbers above 16,777,217 that have this characteristic; 16,777,217 just happens to be the first, for reasons you can probably divine if you think the IEEE floating-point spec is a riveting read. A couple of weeks after the launch of a fairly major internal application, this time-bomb exploded due to a sequence reaching the magic number. The bug was nothing to do with the new application, but of course fingers were pointed at it since a long-running and stable system had mysteriously choked very shortly after deployment of the new application.&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;Now, unquestionably, all these problems are avoidable, and a strong argument could be made that none of them should ever have been allowed to happen. Yet, for many reasons, they do. For example, first-mover advantage can mean the opportunity cost of taking the time to do things right first time is greater than the cost of fixing problems later.&lt;br/&gt;&lt;br/&gt;Also, people make assumptions. The issue underlying the &lt;a href="http://en.wikipedia.org/wiki/Millennium_bug"&gt;Millennium Bug&lt;/a&gt; hysteria was caused by well-meaning developers who knew that two-digit dates wouldn't work after 1999 (effectively another magic number), but assumed the software would have been replaced or upgraded by then. No doubt that seemed a totally reasonable assumption in the 1970s, and it had genuine technical benefits (storage space was so tight that every byte saved was a battle won).&lt;br/&gt;&lt;br/&gt;Anyway, I don't have a magic bullet solution for this, I'm just venting spleen. Unit tests can help, but won't magically eliminate this class of bug (no matter what some of the more extreme TDD fanatics might tell you), so I suppose the lesson to take from this is the importance of being able to recognise and diagnose potential magic number issues. Pay close attention to data types, type conversions, and current values of sequences in your database. Keeping a sacrifical goat on hand might pay dividends too, in case any blood-thirsty deities with a head for binary arithmetic are watching.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-2673024050667139089?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/ZQV_KIbKj68" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/2673024050667139089/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/08/magic-numbers-and-other-numerical.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2673024050667139089?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2673024050667139089?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/ZQV_KIbKj68/magic-numbers-and-other-numerical.html" title="Magic Numbers and Other Numerical Nightmares" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/08/magic-numbers-and-other-numerical.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXs6fSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-8780546485671483316</id><published>2008-08-10T23:34:00.000+01:00</published><updated>2011-10-03T10:11:10.515+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.515+01:00</app:edited><title>Ubuntu, Xmonad, and an Ode to Apt</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6HxpyNCaueg3k3E7dxmWCf9_uYk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6HxpyNCaueg3k3E7dxmWCf9_uYk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6HxpyNCaueg3k3E7dxmWCf9_uYk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6HxpyNCaueg3k3E7dxmWCf9_uYk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;This weekend I finally got around to updating my main Linux box from Ubuntu 7.10 to 8.04 (yes, I know, 4 months late - but moving fast!). The highly excellent &lt;a href="http://xmonad.org/"&gt;xmonad&lt;/a&gt; has made it into the main Ubuntu repositories, so I discarded my own build and grabbed the packaged version - which promptly didn't work as expected on my dual-head setup. Gah.&lt;br/&gt;&lt;br/&gt;&lt;a href="https://bugs.launchpad.net/debian/+source/haskell-x11/+bug/203594"&gt;A bit of googling suggested&lt;/a&gt; that the problem lay with the upstream debian package, which contained a build of libghc6-x11-dev that was compiled without xinerama support. This left me with a choice of either waiting for the package to get sorted out, or to do the build myself again. I decided to do my own build rather than live without xmonad, but rather than mucking about with tarballs I could at least now get the source from the package repository.&lt;br/&gt;&lt;br/&gt;The appropriate steps, for anyone interested or having the same problem, are:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;Make sure libxinerama-dev is installed&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Recompile libghc6-x11-dev and install it&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Recompile libghc6-xmonad-dev and libghc-xmonad-contrib-dev against the new X11 lib&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;The apt-get incantations are:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;sudo apt-get install libxinerama-dev&lt;br/&gt;&lt;span class="Statement"&gt;cd&lt;/span&gt; /tmp&lt;br/&gt;sudo apt-get source &lt;span class="Special"&gt;--compile&lt;/span&gt; libghc6-x11-dev&lt;br/&gt;sudo dpkg &lt;span class="Special"&gt;-i&lt;/span&gt; libghc6-x11-dev_1.&lt;span class="Constant"&gt;4&lt;/span&gt;.&lt;span class="Constant"&gt;1&lt;/span&gt;-1_i386.deb&lt;br/&gt;sudo apt-get build-dep libghc6-xmonad-dev&lt;br/&gt;sudo apt-get source &lt;span class="Special"&gt;--compile&lt;/span&gt; libghc6-xmonad-dev&lt;br/&gt;sudo dpkg &lt;span class="Special"&gt;-i&lt;/span&gt; libghc6-xmonad-dev&lt;br/&gt;sudo apt-get build-dep libghc6-xmonad-contrib-dev&lt;br/&gt;sudo apt-get source &lt;span class="Special"&gt;--compile&lt;/span&gt; libghc6-xmonad-contrib-dev&lt;br/&gt;sudo dpkg &lt;span class="Special"&gt;-i&lt;/span&gt; libghc6-xmonad-contrib-dev_0.&lt;span class="Constant"&gt;6&lt;/span&gt;-4_i386.deb&lt;/pre&gt;&lt;br/&gt;A quick alt-q restart, and all is well.&lt;br/&gt;&lt;br/&gt;I only mention all this because it's so easy in this day and age to take something like apt for granted, and every so often it's worth taking a moment to appreciate just how spectacularly good it really is. Where I work, deployments are an endless source of headaches and grief, yet the complexity of those deployments absolutely pales against the task of updating literally millions of systems, all slightly different to each other, thousands of times a day. It's just a joy to be able to say to apt "hey, go get me everything I need to build package x, then build package x, then install it for me. And get it right first time!".&lt;br/&gt;&lt;br/&gt;In most cases, it does just that. It's an astonishing piece of software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-8780546485671483316?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/fSgz7hrppVo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/8780546485671483316/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/08/ubuntu-xmonad-and-ode-to-apt.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8780546485671483316?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8780546485671483316?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/fSgz7hrppVo/ubuntu-xmonad-and-ode-to-apt.html" title="Ubuntu, Xmonad, and an Ode to Apt" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/08/ubuntu-xmonad-and-ode-to-apt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo8fSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-3719267444897194651</id><published>2008-08-08T17:41:00.000+01:00</published><updated>2011-10-03T10:11:10.475+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.475+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><title>Dynamic Async Batching with PFX</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Mvc8c9WAiApHD8MPacMvB2QvXb0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Mvc8c9WAiApHD8MPacMvB2QvXb0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Mvc8c9WAiApHD8MPacMvB2QvXb0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Mvc8c9WAiApHD8MPacMvB2QvXb0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;The &lt;a href="http://blogs.msdn.com/pfxteam/default.aspx"&gt;PFX Team blog&lt;/a&gt; has been posting some excellent articles recently on the subject of &lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/08/05/8835612.aspx"&gt;task batching&lt;/a&gt; using the June 2008 CTP release of the Task Parallel Library. It's really cool to see some of these techniques abstracted properly in .Net, and I hope it eventually becomes part of the core libraries.&lt;br/&gt;&lt;br/&gt;I've been playing around a bit recently with the June CTP in the context of batching up web service calls, as that's something I do quite a lot. One particular problem that comes up occasionally is a two-stage series of requests to download a complete set of paged data. I might do this if I wanted to download an entire discussion thread, for instance, or a large account statement from my online bank.&lt;br/&gt;&lt;br/&gt;Typically in this situation the web service will limit the number of records I can retrieve in one request, and allow me to specify start and count parameters to the request. The response will also include a total record count, so I know how much data there is.&lt;br/&gt;&lt;br/&gt;The normal use case for this is to request the first page of data, and use the total record count to display a list of page links that my user can click on to navigate the data or jump to any page. In my case, however, I want ALL the data as quickly as possible.&lt;br/&gt;&lt;br/&gt;So, imagine a situation where I am using a service that lets me download a maximum of 200 records per request. My first step is to request the maximum 200 records starting from index 0, i.e. the first page of data. In the response will be a total record count - if that number is equal to the number of records I got back (i.e. &amp;lt;= 200) I've got everything in one hit and can stop. But what if the total record count is, say, 1000? I need to make four more requests (since I've already got records 1-200, I have 800 more to get in batches of 200 each).&lt;br/&gt;&lt;br/&gt;Naturally I want to do this asynchronously, using as few resources as I can. This means all webservice calls should be using the APM pattern (thus using IO completion ports, and not consuming worker threads from the thread pool or creating my own threads) and, preferably, not blocking anywhere except when I actually need some data before continuing.&lt;br/&gt;&lt;br/&gt;The two-stage process can be successfully captured asynchronously by combining a future and a continuation. I encapsulate the initial request in a Future object (which is a subclass of Task), and handle the check-record-count-and-get-more-records-if-required logic in the continuation. The code for this basically looks as follows:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;public&lt;/span&gt; Future&amp;lt;List&amp;lt;Item&amp;gt;&amp;gt; GetAllItemsAsync()&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;var&lt;/span&gt; f = Create&amp;lt;GetItemsResponse&amp;gt;(&lt;br/&gt;            ac =&amp;gt; Service.BeginGetItems(&lt;span class="Constant"&gt;0&lt;/span&gt;, ac, &lt;span class="Constant"&gt;null&lt;/span&gt;),&lt;br/&gt;            Service.EndGetItems);&lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;var&lt;/span&gt; start = &lt;span class="Constant"&gt;200&lt;/span&gt;;&lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;var&lt;/span&gt; resultFuture = f.ContinueWith(&lt;br/&gt;        r =&amp;gt;&lt;br/&gt;            {&lt;br/&gt;                &lt;span class="Comment"&gt;// Batch retrieval here...&lt;/span&gt;&lt;br/&gt;            });&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; resultFuture;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;In order to support the APM pattern neatly, I'm using the following method &lt;a href="http://blogs.msdn.com/pfxteam/archive/2008/03/16/8272833.aspx"&gt;from the PFX blog&lt;/a&gt;:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; Future&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(&lt;br/&gt;        Action&amp;lt;AsyncCallback&amp;gt; beginFunc,&lt;br/&gt;        Func&amp;lt;IAsyncResult, T&amp;gt; endFunc)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;var&lt;/span&gt; f = Future&amp;lt;T&amp;gt;.Create();&lt;br/&gt;    beginFunc(iar =&amp;gt;&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="Statement"&gt;try&lt;/span&gt;&lt;br/&gt;            {&lt;br/&gt;                f.Value = endFunc(iar);&lt;br/&gt;            }&lt;br/&gt;            &lt;span class="Statement"&gt;catch&lt;/span&gt; (Exception e)&lt;br/&gt;            {&lt;br/&gt;                f.Exception = e;&lt;br/&gt;            }&lt;br/&gt;        });&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; f;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;This could be coded as an extension method, though I haven't bothered yet as I'm hopeful this immensely useful snippet will be integrated into the library itself.&lt;br/&gt;&lt;br/&gt;Now I need to make a number of calls to get the rest of the data, so I loop until I've made the required number of async service calls:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;var&lt;/span&gt; resultFuture = f.ContinueWith(r =&amp;gt;&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Type"&gt;var&lt;/span&gt; items = &lt;span class="Statement"&gt;new&lt;/span&gt; ConcurrentQueue&amp;lt;Item&amp;gt;();&lt;br/&gt;        &lt;span class="Type"&gt;var&lt;/span&gt; handles = &lt;span class="Statement"&gt;new&lt;/span&gt; List&amp;lt;WaitHandle&amp;gt;();&lt;br/&gt;&lt;br/&gt;        &lt;span class="Statement"&gt;while&lt;/span&gt; (start &amp;lt; r.Value.TotalRecordCount)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="Type"&gt;var&lt;/span&gt; asyncResult = Service.BeginGetItems(&lt;span class="Constant"&gt;200&lt;/span&gt;,&lt;br/&gt;                ar =&amp;gt; Service.EndGetItems(ar).Items&lt;br/&gt;                    .ForEach(items.Enqueue), &lt;span class="Constant"&gt;null&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;            handles.Add(asyncResult.AsyncWaitHandle);&lt;br/&gt;            start += &lt;span class="Constant"&gt;200&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        handles.ForEach(h =&amp;gt; h.WaitOne());&lt;br/&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; items.ToList();&lt;br/&gt;    });&lt;/pre&gt;&lt;br/&gt;I'm about 85% happy with this as an approach. I'm not completely happy, however, because of the WaitOne calls, which mean that I'm blocking on a threadpool thread until all the calls complete. Given that this is all wrapped up in a future, I may not actually need to access the data until well after the calls have completed, in which case I am wastefully consuming a threadpool thread for some period of time. So the $64,000 question is, how do I get rid of it? I'm sure there's a way to do it, but my brain has gone on a protest march about all the time I'm forcing it to spend thinking about this stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-3719267444897194651?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/RaiBlm5wfII" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/3719267444897194651/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/08/dynamic-async-batching-with-pfx.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3719267444897194651?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3719267444897194651?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/RaiBlm5wfII/dynamic-async-batching-with-pfx.html" title="Dynamic Async Batching with PFX" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/08/dynamic-async-batching-with-pfx.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXs7cCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-8356075436985041674</id><published>2008-07-30T17:01:00.000+01:00</published><updated>2011-10-03T10:11:10.508+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.508+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Comment Discontent</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DstSmwdKkSqjhqjX4-98K5CuXFk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DstSmwdKkSqjhqjX4-98K5CuXFk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DstSmwdKkSqjhqjX4-98K5CuXFk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DstSmwdKkSqjhqjX4-98K5CuXFk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;There seems to have been a recent &lt;a href="http://blog.uncommons.org/2008/07/25/no-your-code-is-not-so-great-that-it-doesnt-need-comments/"&gt;outbreak&lt;/a&gt; &lt;a href="http://www.carlcrowder.com/blog/?p=34"&gt;in&lt;/a&gt; &lt;a href="http://www.codinghorror.com/blog/archives/001150.html"&gt;blog&lt;/a&gt; &lt;a href="http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.html"&gt;posts&lt;/a&gt; about &lt;a href="http://en.wikipedia.org/wiki/Comment_(computer_programming)"&gt;code commenting&lt;/a&gt;. As is so often the case with topics such as this, everyone has an opinion and they all seem to be different. It's quite an eye-opener seeing some of the explanations, justifications, and outright haranguing used in defence of all sorts of weird and wonderful stances.&lt;br/&gt;&lt;br/&gt;I got a wry smile from &lt;a href="http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.html"&gt;stevey's post&lt;/a&gt;, as I recognise only too well the tendency to write narrative comments. I'm sure there's plenty of code from early in my career still floating around in various company codebases where the code/comment ratio is something embarrassing. I've mostly shaken that off now, though I sometimes have to fight my inner raconteur when writing something I think is neat or clever.&lt;br/&gt;&lt;br/&gt;Jeff Atwood, as is so often the case recently, contradicted his &lt;a href="http://www.codinghorror.com/blog/archives/000749.html"&gt;own previous post&lt;/a&gt; on the matter (replacing the statement "comments can never be replaced by code alone" with "if your feel your code is too complex to understand without comments, your code is probably just bad") and endearingly veered wildly to and fro across a sensible medium&lt;sup&gt;[1]&lt;/sup&gt;, without ever quite hitting it. Coding Horror, indeed.&lt;br/&gt;&lt;br/&gt;So far, so blah; every time an argument on comments flares up we see the same thing. Something I've not noticed before though, either because I wasn't paying attention or because it's a new thing, is a trend amongst the I-don't-need-comments crowd to advocate very long and detailed method names as an alternative.&lt;br/&gt;&lt;br/&gt;As neophyte coders we all have it drilled into us that we must use descriptive names. Programming gospel, as handed down in sacred tomes such as &lt;a href="http://www.amazon.co.uk/Code-Complete-Practical-Handbook-Construction/dp/1556154844"&gt;Code Complete&lt;/a&gt;, tell us not to use names like 'i' and 'tmp' except in very specific circumstances (e.g. loop indexes and tempfile handles). And, without question, this is good solid advice. Take heed, young Padawan, etc.&lt;br/&gt;&lt;br/&gt;But can you take it too far? It's not something I've really come up against, but it seems to be increasingly popular. &lt;a href="http://blog.uncommons.org/2008/07/25/no-your-code-is-not-so-great-that-it-doesnt-need-comments/"&gt;One response to Jeff's post&lt;/a&gt; suggested (only in passing, to be fair) using a function name like &lt;code&gt;newtonRaphsonSquareRoot&lt;/code&gt;. A &lt;a href="http://digg.com/programming/No_your_code_is_not_so_great_that_it_doesn_t_need_comments"&gt;digg comment&lt;/a&gt; (OK, OK, not exactly the fount of all knowledge) vehemently defended the virtue of the frankly-scary &lt;code&gt;RunEndOfMonthReportsUnlessTheMonthStartsOnAFridayIn&lt;br/&gt;WhichCaseRunTheWeeklyReportInstead&lt;/code&gt; (!)&lt;br/&gt;&lt;br/&gt;The argument is that with names like these, you don't need comments, since it is perfectly clear what the function does. Is it perfectly clear at the wrong level though? Function names like this, in my opinion, are so 'clear' that they leak. These are function names that violate the principle of &lt;a href="http://en.wikipedia.org/wiki/Encapsulation_(classes_-_computers)"&gt;encapsulation&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;If I write a square root function, why do I need to burden all my clients with information about how I've implemented it? By naming it &lt;code&gt;newtonRaphsonSquareRoot&lt;/code&gt;, that's exactly what I'm doing. Unless there are specific performance implications/requirements that favour &lt;a href="http://en.wikipedia.org/wiki/Newton%27s_method"&gt;Newton-Raphson&lt;/a&gt;, in most cases my clients just want a damn square root calculated to within a specified tolerance and don't care whether I used Newton's method or one of the &lt;a href="http://en.wikipedia.org/wiki/Methods_of_computing_square_roots"&gt;army of alternatives&lt;/a&gt;. The implementation should be private to the method, and no-one else's business.&lt;br/&gt;&lt;br/&gt;Worse, what if a requirements change means a switch to &lt;a href="http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Reciprocal_of_the_square_root"&gt;Walsh's fast reciprocal method&lt;/a&gt;? Uh-oh, now my method name is completely misleading, so I have to change it. Oops, now I have to change all the client code that calls it! I'd better hope no-one has exposed this with &lt;code&gt;[WebMethodAttribute]&lt;/code&gt; since I wrote it, otherwise there could be thousands of client applications out there relying on it. My funky rename refactoring can't save me now.&lt;br/&gt;&lt;br/&gt;If every tiny change propagates through the system requiring hundreds of source files to change, and possibly external apps as well, you may as well just copy 'n' paste the code everywhere it's needed and doing away with the function completely. Hell, who needs abstraction anyway?&lt;br/&gt;&lt;br/&gt;We all do, of course, which is why I think names like this are a bad smell. The same goes for &lt;code&gt;RunEndOfMonthReportsUnless...&lt;/code&gt; - what happens when the requirements change? This method name couples the public interface (method name) to the private implementation, which is exactly what you're not supposed to do. &lt;code&gt;RunEndOfMonthReports&lt;/code&gt; is probably sufficient. Separate interface and implementation. This is programming 101, people, it shouldn't be beyond our grasp.&lt;br/&gt;&lt;br/&gt;&lt;sup&gt;[1]&lt;/sup&gt;I agree with &lt;a href="http://blog.uncommons.org/2008/07/25/no-your-code-is-not-so-great-that-it-doesnt-need-comments/"&gt;Dan Dyer&lt;/a&gt; that the best choice is as follows:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Comment"&gt;/**&lt;/span&gt;&lt;br/&gt;&lt;span class="Comment"&gt; *  Approximate the square root of n, to within the specified&lt;/span&gt;&lt;br/&gt;&lt;span class="Comment"&gt; *  tolerance, using the Newton-Raphson method.&lt;/span&gt;&lt;br/&gt;&lt;span class="Comment"&gt; */&lt;/span&gt;&lt;br/&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;double&lt;/span&gt; approximateSquareRoot(&lt;span class="Type"&gt;double&lt;/span&gt; n, &lt;span class="Type"&gt;double&lt;/span&gt; tolerance)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;double&lt;/span&gt; root = n / &lt;span class="Constant"&gt;2&lt;/span&gt;;&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (abs(root - (n / root)) &amp;gt; tolerance)&lt;br/&gt;    {&lt;br/&gt;        root = &lt;span class="Constant"&gt;0.5&lt;/span&gt; * (root + (n / root));&lt;br/&gt;    }&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; root;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;The function name is descriptive and clear whilst remaining general enough to allow an alternative implementation. Anyone who cares enough about the implementation (for performance reasons, or simply curiosity) can find enough information in the comment to start their investigation, without having the details jammed in their face every time they call it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-8356075436985041674?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/_3zKX89pqF8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/8356075436985041674/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/07/comment-discontent.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8356075436985041674?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8356075436985041674?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/_3zKX89pqF8/comment-discontent.html" title="Comment Discontent" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/07/comment-discontent.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo8eip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-3176808813846001231</id><published>2008-07-20T23:40:00.000+01:00</published><updated>2011-10-03T10:11:10.472+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.472+01:00</app:edited><title>These...Are Not The Hammer</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Xf-aWsai4kdyE0tT39jQO_XiCuo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xf-aWsai4kdyE0tT39jQO_XiCuo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Xf-aWsai4kdyE0tT39jQO_XiCuo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xf-aWsai4kdyE0tT39jQO_XiCuo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;So, yesterday saw the end of a weird week of Whedon wonderfulness when the third and final episode of &lt;a href="http://www.drhorrible.com/index.html"&gt;Dr Horrible's Sing-Along Blog&lt;/a&gt; was released. All three episodes are now free to view until the end of the day, so run, don't walk, over there now. After all, how often do you get the chance to see a musical comedy about a supervillain who video blogs? With Doogie Howser and Malcolm Reynolds!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-3176808813846001231?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/i3lLEYL5WRI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/3176808813846001231/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/07/theseare-not-hammer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3176808813846001231?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3176808813846001231?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/i3lLEYL5WRI/theseare-not-hammer.html" title="These...Are Not The Hammer" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/07/theseare-not-hammer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXs7eip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-7579687140676126380</id><published>2008-07-01T17:49:00.000+01:00</published><updated>2011-10-03T10:11:10.502+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.502+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term=".Net" /><title>Lexical Closures in C# 3.0</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CEMoV4pg39MKrXxhNttdclHViG4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CEMoV4pg39MKrXxhNttdclHViG4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CEMoV4pg39MKrXxhNttdclHViG4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CEMoV4pg39MKrXxhNttdclHViG4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;There's a &lt;a href="http://dobbscodetalk.com/index.php?show=The-next-big-programming-language-feature-after-closures.html"&gt;slightly weird article&lt;/a&gt; up on &lt;a href="http://dobbscodetalk.com/"&gt;Dobbs Code Talk&lt;/a&gt; this week, speculating that aggregate functions are "the next big programming language feature" after closures. The slight weirdness comes from the fact that both features have been around for decades, and not just in dusty academic languages either.&lt;br/&gt;&lt;br/&gt;Still, there's some interesting discussion in the comments about whether .Net's closures are proper first-class lexically-scoped closures. The answer is yes - but with a fun twist.&lt;br/&gt;&lt;br/&gt;The twist has been around for a long time - &lt;a href="http://blogs.msdn.com/brada/default.aspx"&gt;Brad Abrams&lt;/a&gt; blogged about it &lt;a href="http://blogs.msdn.com/brada/archive/2004/08/03/207164.aspx"&gt;way back in 2004&lt;/a&gt;, for instance - but it's probably worth going over it again, since the recent arrival of LINQ and lambda syntax in C# 3.0 will presumably lead to more people being bitten by this as the use of closures becomes more mainstream.&lt;br/&gt;&lt;br/&gt;A key thing to remember is that C# lambdas are just anonymous delegates in skimpy syntax. Behind the scenes the compiler turns them into classes - if you were looking at disassembled MSIL you wouldn't be able to tell whether the code was written with lambda syntax or anonymous delegate syntax. Therefore, the issue discussed by Brad has not gone anywhere.&lt;br/&gt;&lt;br/&gt;Lets revisit the problem, with a 2008 sheen applied (i.e. I'll use lambda syntax rather than anonymous delegate syntax). What does the following code display?&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;Func&amp;lt;&lt;span class="Type"&gt;int&lt;/span&gt;&amp;gt;[] funcs = &lt;span class="Statement"&gt;new&lt;/span&gt; Func&amp;lt;&lt;span class="Type"&gt;int&lt;/span&gt;&amp;gt;[&lt;span class="Constant"&gt;10&lt;/span&gt;];&lt;br/&gt;&lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class="Constant"&gt;10&lt;/span&gt;; ++i)&lt;br/&gt;{&lt;br/&gt;    funcs[i] = () =&amp;gt; i * i;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;funcs.ForEach(f =&amp;gt; Console.WriteLine(f()));&lt;/pre&gt;&lt;br/&gt;If you answered something along the lines of "prints the square of every number between 0 and 9" you'd be...wrong. Really, try it out. See?&lt;br/&gt;&lt;br/&gt;Now, a lexical closure is supposed to capture its environment, meaning that the lambda stored on the first loop would capture i when i==0, the second loop would capture i when i==1, and so on. If this happened, then executing all the lambdas would indeed result in the squares of the numbers 0-9 being printed. So what gives?&lt;br/&gt;&lt;br/&gt;The problem stems from the fact that the lambda is binding itself to a variable that is accessible outside the closure, which is being changed in every iteration of the loop. The closure doesn't capture the value of i, it captures a reference to i itself, which is mutable.&lt;br/&gt;&lt;br/&gt;You could actually make a case that this is bad code anyway, since it gives two responsibilities to the loop index - control the loop, and act as data in the closures. If we were being pedantic, we could split the responsibilities by creating a new variable, j, to be the closure data each iteration, and let i concentrate on being an index:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class="Constant"&gt;10&lt;/span&gt;; ++i)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; j = i;&lt;br/&gt;    funcs[i] = () =&amp;gt; j * j;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Lo and behold, the code now works! Pedantry rules! Take a look with Reflector or ildasm to see what's going on here. The executive summary is that the compiler captures the environment (i in the first example, j in the second) by creating a member variable within the class it generates for the closure. Previously, since the same instance of i lived for the entire duration of the loop, only one instance of the generated class was created and shared. Now, however, a new instance of the generated class is created in each iteration of the loop (since j is scoped within the loop body and thus we have a new j every time round). Thus, the data is not shared and we get the expected output.&lt;br/&gt;&lt;br/&gt;There are two important points to consider here:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;The problem goes away if you write code more declaratively. Do away with the clunky for loop and everything works OK.&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;Enumerable.Range(&lt;span class="Constant"&gt;0&lt;/span&gt;, &lt;span class="Constant"&gt;10&lt;/span&gt;).Select(x =&amp;gt; x * x);&lt;/pre&gt;&lt;br/&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;It isn't always bad that multiple closures can capture a reference - since one closure can 'see' updates made to the shared data by another closure, you could use this as a coordination mechanism.&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;This is not an issue that's going to crop up every day - the example above is fairly contrived - but knowing about it will save some painful debugging sessions when inevitably you do run into it. The fix is always to take a local copy of the mutable data to coerce the compiler into generating code that creates multiple instances of the class generated to represent the closure.&lt;br/&gt;&lt;br/&gt;Simple, yes? ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-7579687140676126380?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/yz8BGcUT2hk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/7579687140676126380/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/07/lexical-closures-in-c-30.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/7579687140676126380?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/7579687140676126380?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/yz8BGcUT2hk/lexical-closures-in-c-30.html" title="Lexical Closures in C# 3.0" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/07/lexical-closures-in-c-30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo9cSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-3175533077655488697</id><published>2008-06-10T12:47:00.000+01:00</published><updated>2011-10-03T10:11:10.469+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.469+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 5</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CNTooloi5voeK72kANbSjutagR4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CNTooloi5voeK72kANbSjutagR4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CNTooloi5voeK72kANbSjutagR4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CNTooloi5voeK72kANbSjutagR4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;On to the next Project Euler problem (after a bit of a hiatus)...&lt;br/&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=5"&gt;Problem 5&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;blockquote&gt;2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.&lt;br/&gt;&lt;br/&gt;What is the smallest number that is &lt;dfn title="divisible with no remainder"&gt;evenly divisible&lt;/dfn&gt; by all of the numbers from 1 to 20?&lt;/blockquote&gt;&lt;br/&gt;In common with many of the other Euler problems, there's a brute-force way to solve this, and a clean algorithmic way. And in common with my other Euler posts so far, I'll start with the brute-force way ;-)&lt;br/&gt;&lt;br/&gt;This problem can be tackled head-on with the following approach: Start from &lt;em&gt;n&lt;/em&gt;=1 and increment in a loop. Test each value of &lt;em&gt;n&lt;/em&gt; by attempting to divide it by all numbers &lt;em&gt;m&lt;/em&gt; from 1 to 20. The first number to pass the test (i.e. &lt;em&gt;n&lt;/em&gt; mod &lt;em&gt;m&lt;/em&gt; is 0 for all values of &lt;em&gt;m&lt;/em&gt;) is the answer.&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; BruteForceSolver()&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;long&lt;/span&gt; result;&lt;br/&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (result = &lt;span class="Constant"&gt;1&lt;/span&gt;; !Check(result); ++result)&lt;br/&gt;        ;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; result;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; Check(&lt;span class="Type"&gt;long&lt;/span&gt; result)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;1&lt;/span&gt;; i &amp;lt;= &lt;span class="Constant"&gt;20&lt;/span&gt;; ++i)&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Statement"&gt;if&lt;/span&gt; (result % i != &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br/&gt;            &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;This works, but it takes &amp;gt;12 seconds to execute on my PC, so it's not what you'd call efficient (though it is well within the Euler execution time guidelines).&lt;br/&gt;&lt;br/&gt;Some speed gains can be achieved by exploiting the information provided in the question itself. We are told that 2520 is the lowest number evenly divisible by all numbers from 1 to 10. Since the problem space (1 to 20) includes all these numbers, the answer must also be evenly divisible by 2520. This allows much bigger increments each loop - rather than incrementing by 1, why not increment by 2520? And since the answer must be greater than or equal to 2520, why not start the loop there instead of 1? Finally, since we already know that 1 to 10 divide evenly into 2520, each inner loop only needs to check numbers 11 to 20.&lt;br/&gt;&lt;br/&gt;That should speed things up a bit:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; BruteForceSolver()&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;long&lt;/span&gt; result;&lt;br/&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (result = &lt;span class="Constant"&gt;2520&lt;/span&gt;; !Check(result); result += &lt;span class="Constant"&gt;2520&lt;/span&gt;)&lt;br/&gt;        ;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; result;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; Check(&lt;span class="Type"&gt;long&lt;/span&gt; result)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;11&lt;/span&gt;; i &amp;lt;= &lt;span class="Constant"&gt;20&lt;/span&gt;; ++i)&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Statement"&gt;if&lt;/span&gt; (result % i != &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br/&gt;            &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;And indeed, on my machine this is now down to 150ms or so. It's still not a very nice way to tackle the problem, though.&lt;br/&gt;&lt;br/&gt;Thinking about it from a different angle yields an altogether smarter approach. Imagine we are looking for the lowest number evenly divisible by the numbers 1 to 2.&lt;br/&gt;&lt;br/&gt;[1, 2]&lt;br/&gt;&lt;br/&gt;Well that's easy; since there are only two numbers we just find the lowest common multiple (LCM), which in this case is 2 (since 2 % 2 == 0, and 2 % 1 == 0). If we call this sequence s&lt;sub&gt;1&lt;/sub&gt;, we can say that LCM(s&lt;sub&gt;1&lt;/sub&gt;) = 2.&lt;br/&gt;&lt;br/&gt;OK, now imagine we are solving the same problem for s&lt;sub&gt;2&lt;/sub&gt;, which contains the numbers 1 to 3.&lt;br/&gt;&lt;br/&gt;[1, 2, 3]&lt;br/&gt;&lt;br/&gt;You'll notice that s&lt;sub&gt;2&lt;/sub&gt; contains s&lt;sub&gt;1&lt;/sub&gt; in its entirety. LCM(s&lt;sub&gt;2&lt;/sub&gt;) must therefore be a multiple of LCM(s&lt;sub&gt;1&lt;/sub&gt;), so we can rewrite s&lt;sub&gt;2&lt;/sub&gt; as [LCM(s&lt;sub&gt;1&lt;/sub&gt;), 3], or [2, 3] (since we know LCM(s&lt;sub&gt;1&lt;/sub&gt;) = 2). Now we are down to two numbers again, so we can calculate the LCM of 2 and 3, which is 6, so LCM(s&lt;sub&gt;2&lt;/sub&gt;) = 6.&lt;br/&gt;&lt;br/&gt;OK, now we solve the problem for the first 4 numbers (s&lt;sub&gt;3&lt;/sub&gt;).&lt;br/&gt;&lt;br/&gt;[1, 2, 3, 4]&lt;br/&gt;&lt;br/&gt;This sequence contains s&lt;sub&gt;2&lt;/sub&gt;, therefore LCM(s&lt;sub&gt;3&lt;/sub&gt;) is a multiple of LCM(s&lt;sub&gt;2&lt;/sub&gt;). We can rewrite s&lt;sub&gt;3&lt;/sub&gt; as [LCM(s&lt;sub&gt;2&lt;/sub&gt;), 4], or [6, 4]. Thus, LCM(s&lt;sub&gt;3&lt;/sub&gt;) = 12.&lt;br/&gt;&lt;br/&gt;This can be repeated as many times as necessary. Generally, we have s&lt;em&gt;&lt;sub&gt;n&lt;/sub&gt;&lt;/em&gt; = [LCM(s&lt;sub&gt;&lt;em&gt;n&lt;/em&gt;-1&lt;/sub&gt;), &lt;em&gt;n&lt;/em&gt;+1] where &lt;em&gt;n&lt;/em&gt; &amp;gt; 0.&lt;br/&gt;&lt;br/&gt;This looks recursive, but a better way to think of it is as an excellent example of a fold. A fold is one of the fundamental tools of functional programming. In fact, it is perhaps the most fundamental, since map, filter etc can be implemented as right folds&lt;sup&gt;[1]&lt;/sup&gt;.&lt;br/&gt;&lt;br/&gt;I won't inflict my pitiful Photoshop skills on anyone by trying to graphically represent a fold - try looking at &lt;a href="http://en.wikipedia.org/wiki/Fold_(higher-order_function)"&gt;this Wikipedia article&lt;/a&gt; if you want to try and visualise it.&lt;br/&gt;&lt;br/&gt;Broadly, the behaviour of a fold is to apply a combining function to elements in a list (or other data structure) and accumulate the results. That's exactly what we want here - our combining function is LCM, and our accumulating value is the LCM of the whole list. Effectively, for list s&lt;sub&gt;3&lt;/sub&gt; above, we have&lt;br/&gt;&lt;br/&gt;LCM(s&lt;sub&gt;3&lt;/sub&gt;) = LCM(LCM(LCM(1,2),3),4) = 12&lt;br/&gt;&lt;br/&gt;Note how the result of the innermost LCM (applied to values 1 and 2) becomes a parameter to the next LCM, which in turn becomes a parameter to the outermost LCM which returns the result we want.&lt;br/&gt;&lt;br/&gt;By using a fold, we can generalise. In Haskell, the whole problem is a one-liner:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;foldl lcm &lt;span class="Constant"&gt;1&lt;/span&gt; [&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Statement"&gt;..&lt;/span&gt;&lt;span class="Constant"&gt;20&lt;/span&gt;]&lt;/pre&gt;&lt;br/&gt;The 1 passed in as a parameter represents the terminating value to use when the end of the list is reached. It is common for this value to be the first element of the list, so Haskell provides a convenience function that removes the need to specify it as a parameter:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;foldl1 lcm [&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Statement"&gt;..&lt;/span&gt;&lt;span class="Constant"&gt;20&lt;/span&gt;]&lt;/pre&gt;&lt;br/&gt;Not all languages and platforms provide an LCM function right out of the box, so to take this neat Haskell solution and port it to .Net, the LCM function needs to be implemented. This is easily done in terms of the greatest common divisor (GCD) like so:&lt;br/&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Least_common_multiple#Calculating_the_least_common_multiple"&gt;&lt;/a&gt;&lt;br/&gt;&lt;p style="text-align: center"&gt;&lt;a href="http://en.wikipedia.org/wiki/Least_common_multiple#Calculating_the_least_common_multiple"&gt;&lt;img src="http://upload.wikimedia.org/math/4/d/2/4d244548521249d1b5a71941506d5f41.png" height="48" width="183" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br/&gt;.Net doesn't provide a GCD function either, so I'll implement it using &lt;a href="http://en.wikipedia.org/wiki/Euclidean_algorithm"&gt;Euclid's Algorithm&lt;/a&gt; as an extension method on long ints:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; GCD(&lt;span class="Statement"&gt;this&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; a, &lt;span class="Type"&gt;long&lt;/span&gt; b)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (b != &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Type"&gt;long&lt;/span&gt; tmp = b;&lt;br/&gt;        b = a % b;&lt;br/&gt;        a = tmp;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; a;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;With GCD defined, LCM can be implemented as above:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; LCM(&lt;span class="Statement"&gt;this&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; a, &lt;span class="Type"&gt;long&lt;/span&gt; b)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; (a * b) / a.GCD(b);&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;With this in place, it's a simple matter to use .Net's equivalent of fold - a method on IEnumerable&lt;t&gt; called Aggregate - to get the answer&lt;sup&gt;[2]&lt;/sup&gt;: &lt;/t&gt;&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Statement"&gt;return&lt;/span&gt; LongEnumerable.Range(&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;20&lt;/span&gt;)&lt;br/&gt;    .Aggregate(&lt;span class="Constant"&gt;1L&lt;/span&gt;, (curr, next) =&amp;gt; curr.LCM(next));&lt;/pre&gt;&lt;br/&gt;And indeed, the same basic pattern can be used to solve the problem in a number of languages. In F#, given implementations of LCM and GCD as above, we have:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="PreProc"&gt;List&lt;/span&gt;.fold_left lcm &lt;span class="Constant"&gt;1&lt;/span&gt; &lt;span class="Statement"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;..&lt;span class="Constant"&gt;20&lt;/span&gt;&lt;span class="Statement"&gt;]&lt;/span&gt;&lt;/pre&gt;&lt;br/&gt;And in ruby:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="PreProc"&gt;require&lt;/span&gt; &lt;span class="Special"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;rational&lt;/span&gt;&lt;span class="Special"&gt;'&lt;/span&gt;&lt;br/&gt;(&lt;span class="Constant"&gt;1&lt;/span&gt;..&lt;span class="Constant"&gt;20&lt;/span&gt;).inject { |&lt;span class="Identifier"&gt;c&lt;/span&gt;, &lt;span class="Identifier"&gt;n&lt;/span&gt;| c.lcm n }&lt;/pre&gt;&lt;br/&gt;Given that the right algorithm makes this problem a fairly trivial expression in all these languages, it's pretty hard to identify which is the nicest. I think overall I'll give the nod to Haskell, however, for not making me implement LCM and because I find ruby's 'inject' a less intuitive function name than foldr (but that's probably because I learned the technique in Haskell in the first place and am set in my ways...)&lt;br/&gt;&lt;br/&gt;&lt;hr /&gt; &lt;sup&gt;[1]&lt;/sup&gt;For example, in F#:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; filter p lst &lt;span class="Statement"&gt;=&lt;/span&gt;&lt;br/&gt;  &lt;span class="PreProc"&gt;List&lt;/span&gt;.fold_right &lt;span class="Statement"&gt;(fun&lt;/span&gt; x xs &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Statement"&gt;if&lt;/span&gt; p x &lt;span class="Statement"&gt;then&lt;/span&gt; x&lt;span class="Statement"&gt;::&lt;/span&gt;xs &lt;span class="Statement"&gt;else&lt;/span&gt; xs&lt;span class="Statement"&gt;)&lt;/span&gt; lst &lt;span class="Constant"&gt;[]&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; map f lst &lt;span class="Statement"&gt;=&lt;/span&gt;&lt;br/&gt;  &lt;span class="PreProc"&gt;List&lt;/span&gt;.fold_right &lt;span class="Statement"&gt;(fun&lt;/span&gt; x xs &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; f x &lt;span class="Statement"&gt;::&lt;/span&gt; xs&lt;span class="Statement"&gt;)&lt;/span&gt; lst &lt;span class="Constant"&gt;[]&lt;/span&gt;&lt;/pre&gt;&lt;br/&gt;&lt;sup&gt;[2]&lt;/sup&gt;Note that in this code LongEnumerable is just a very simple partial reimplementation of Enumerable, using longs instead of ints&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-3175533077655488697?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/3dhFQFCZQcM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/3175533077655488697/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/06/project-euler-problem-5.html#comment-form" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3175533077655488697?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3175533077655488697?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/3dhFQFCZQcM/project-euler-problem-5.html" title="Project Euler Problem 5" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/06/project-euler-problem-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXoycCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-6965154095096502016</id><published>2008-04-22T13:10:00.000+01:00</published><updated>2011-10-03T10:11:10.498+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.498+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 4: Extra</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1wcsHJTm1pnrP74Daw3UUud-gGk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1wcsHJTm1pnrP74Daw3UUud-gGk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1wcsHJTm1pnrP74Daw3UUud-gGk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1wcsHJTm1pnrP74Daw3UUud-gGk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Couple of things to add to &lt;a href="http://basildoncoder.com/blog/2008/04/21/project-euler-problem-4/"&gt;yesterday's post&lt;/a&gt; about &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=4"&gt;problem 4&lt;/a&gt;. As is so often the case in life, no sooner had I finished the article than I realised there was an obvious additional step I could make, which I'd somehow failed to spot.&lt;br/&gt;&lt;br/&gt;Regarding the C# solution, an easy win having implemented the Reverse extension method would be to add an IsPalindrome extension to the string class too. The implementation is straightforward:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; IsPalindrome(&lt;span class="Statement"&gt;this&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt; s)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; s == s.Reverse();&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;With this done, the where clause in the LINQ query is more readable, and we have a couple of handy reusable string extensions into the bargain.&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;var&lt;/span&gt; result = (&lt;span class="Statement"&gt;from&lt;/span&gt; product &lt;span class="Statement"&gt;in&lt;/span&gt; AllProducts.From(&lt;span class="Constant"&gt;100&lt;/span&gt;).To(&lt;span class="Constant"&gt;999&lt;/span&gt;)&lt;br/&gt;    &lt;span class="Statement"&gt;          where&lt;/span&gt; product.ToString().IsPalindrome()&lt;br/&gt;    &lt;span class="Statement"&gt;          select&lt;/span&gt; product).Max();&lt;/pre&gt;&lt;br/&gt;Also, &lt;a href="http://basildoncoder.com/blog/2008/04/21/project-euler-problem-4/#comment-945"&gt;Sol&lt;/a&gt; commented that the C code could have a direct implementation of a palindrome function, rather than messing about with strrev, since the implementations are very similar. Whilst this series isn't really focussed on the performance benefit of this approach, it does also make the code more expressive, so I'll include it:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; strpalindrome(&lt;span class="Type"&gt;char&lt;/span&gt;* s) {&lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt; *s1, *s2;&lt;br/&gt;&lt;br/&gt;    s1 = s2 = s;&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (*s2)&lt;br/&gt;        s2++;&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (s1 &amp;lt; s2) {&lt;br/&gt;        &lt;span class="Statement"&gt;if&lt;/span&gt; (*(s1++) != *(--s2))&lt;br/&gt;            &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;The loop now looks like this:&lt;br/&gt;&lt;pre&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (i = &lt;span class="Constant"&gt;100&lt;/span&gt;; i &amp;lt; &lt;span class="Constant"&gt;1000&lt;/span&gt;; ++i) {&lt;br/&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (j = i; j &amp;lt; &lt;span class="Constant"&gt;1000&lt;/span&gt;; ++j) {&lt;br/&gt;            &lt;span class="Type"&gt;int&lt;/span&gt; sum = i * j;&lt;br/&gt;            sprintf(s1, &lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, sum);&lt;br/&gt;            &lt;span class="Statement"&gt;if&lt;/span&gt; (strpalindrome(s1) &amp;amp;&amp;amp; sum &amp;gt; largest) {&lt;br/&gt;                largest = sum;&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;/pre&gt;&lt;br/&gt;If you are interested in the Project Euler problems but craving more detailed analysis, &lt;a href="http://joelneely.wordpress.com/"&gt;Joel Neely&lt;/a&gt; is &lt;a href="http://joelneely.wordpress.com/category/project-euler/"&gt;working through&lt;/a&gt; at a similar rate to me, but focusing his efforts on Scala and studying each problem and its solution in greater depth rather than flitting from language to language. Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-6965154095096502016?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/Jeb_IM3sRig" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/6965154095096502016/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/project-euler-problem-4-extra.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/6965154095096502016?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/6965154095096502016?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/Jeb_IM3sRig/project-euler-problem-4-extra.html" title="Project Euler Problem 4: Extra" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/project-euler-problem-4-extra.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXoyfSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-683295475349604269</id><published>2008-04-22T00:53:00.000+01:00</published><updated>2011-10-03T10:11:10.495+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.495+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 4</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QJgbczSa8h53wobuMemzaHIiPUI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QJgbczSa8h53wobuMemzaHIiPUI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QJgbczSa8h53wobuMemzaHIiPUI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QJgbczSa8h53wobuMemzaHIiPUI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=4"&gt;Problem 4&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; is as follows:&lt;br/&gt;&lt;blockquote&gt;A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.&lt;br/&gt;&lt;br/&gt;Find the largest palindrome made from the product of two 3-digit numbers.&lt;/blockquote&gt;&lt;br/&gt;Bit of an easy one, this. The approach is pretty simple to understand - first calculate all the products of every pair of numbers between 100 and 999, then filter for the palindromic ones, and finally select the largest. The only even vaguely tricky bit is determining if the number is palindromic. The easiest check is to simply convert the number to a string, and check if the string is equal to itself when reversed.&lt;br/&gt;&lt;br/&gt;To shake myself out of C#/python complacency, I decided to write my first attempt at this in good old C. I'm a bit rusty so this took a few goes to get right (the shame).&lt;br/&gt;&lt;br/&gt;First, I need a string reverse function. For those of us that learned to program when C and C++ were king (before that upstart Java came long and ousted languages with pointers from classrooms up and down the land), this is bread and butter.&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;char&lt;/span&gt;* strrev(&lt;span class="Type"&gt;char&lt;/span&gt;* s) { &lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt; *s1, *s2; &lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt; c;                           &lt;br/&gt;&lt;br/&gt;    s1 = s2 = s; &lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (*s2) &lt;br/&gt;        s2++;                           &lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (s1 &amp;lt; s2) { &lt;br/&gt;        c = *(--s2); &lt;br/&gt;        *s2 = *s1; &lt;br/&gt;        *s1++ = c; &lt;br/&gt;    } &lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; s; &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;If you can't read that, shame on you, go and pick up a copy of &lt;a href="http://www.amazon.co.uk/C-Programming-Language-2nd/dp/0131103628/"&gt;K&amp;amp;R&lt;/a&gt; and read it until you weep. In the meantime, basically what happens here is I set pointers to the start (s1) and end (s2) of the original string (s), then swap the pointed-to characters using a temporary variable (c) and move both pointers 1 character towards each other. Repeat until they meet in the middle.&lt;br/&gt;&lt;br/&gt;In this day and age of immutable strings, this old friend now feels a little weird - although I retain (and eventually return) the original pointer, I have in fact modified the actual string that was passed in. Contrast this with C's trendy modern progeny, where you can't change a string at all and have to use a StringB[uilder|uffer] when mutating strings (unless lousy performance makes you smile, of course).&lt;br/&gt;&lt;br/&gt;Still, now it is fairly simple to solve the problem. A nested for loop will let me calculate all the products, and then I just need to convert the results to strings and do the palindrome test. I keep track of the largest palindromic number found so far, and print it at the end.&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; main() { &lt;br/&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; i, j; &lt;br/&gt;    &lt;span class="Type"&gt;int&lt;/span&gt; largest = -&lt;span class="Constant"&gt;1&lt;/span&gt;; &lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt; s1[&lt;span class="Constant"&gt;7&lt;/span&gt;]; &lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt; s2[&lt;span class="Constant"&gt;7&lt;/span&gt;];                           &lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (i = &lt;span class="Constant"&gt;100&lt;/span&gt;; i &amp;lt; &lt;span class="Constant"&gt;1000&lt;/span&gt;; ++i) { &lt;br/&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (j = i; j &amp;lt; &lt;span class="Constant"&gt;1000&lt;/span&gt;; ++j) { &lt;br/&gt;            &lt;span class="Type"&gt;int&lt;/span&gt; sum = i * j; &lt;br/&gt;            sprintf(s1, &lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, sum); &lt;br/&gt;            strcpy(s2, s1); &lt;br/&gt;            strrev(s2); &lt;br/&gt;            &lt;span class="Statement"&gt;if&lt;/span&gt; (strcmp(s1, s2) == &lt;span class="Constant"&gt;0&lt;/span&gt; &amp;amp;&amp;amp; sum &amp;gt; largest) { &lt;br/&gt;                largest = sum; &lt;br/&gt;            } &lt;br/&gt;        } &lt;br/&gt;    }                           &lt;br/&gt;&lt;br/&gt;    printf(&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;%d&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;, largest);                           &lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;; &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Note I'm using the much-maligned strcpy function here (the cause of most of the buffer overflow attacks that were so endemic a few years back), but since I completely control the input it's no problem. Also note the use of sprintf to convert the int to a string, and I have to make a copy of the resulting string since my strrev function is destructive. The char arrays are of size 7, since the largest possible product in the problem space is 999*999=998001 which is 6 digits - plus 1 for the null terminator. Which I didn't forget about at all in my first attempt at this, nosirree.&lt;br/&gt;&lt;br/&gt;To make the code a bit more 'modern' I could do the allocation and copy in the strrev function, so that the passed-in string remains unchanged and a new string gets returned, but without a garbage collector to rely on this potentially leads to memory leaks (since strrev allocates the memory but relies on the caller to free it - easy to forget!). Anyway, I'm wallowing in nostalgia here so who cares about modern idioms.&lt;br/&gt;&lt;br/&gt;Whilst I chose C for this on a whim, it is (as always) enlightening to write a little C now and then, as it reminds you of the cost of things that are often taken for granted. Some people &lt;em&gt;still&lt;/em&gt; don't understand why a StringBuilder offers better performance (trust me, I have interviewed more than a few of them), and are happy to write string manipulation code using immutable strings that results in countless allocations and destructions taking place, for no justifiable reason. Writing some string manipulation (or anything else) in C is a nice way to regain a bit of insight and perspective if you are spoiled by quad-core PCs and high-falutin' generational garbage collectors and smartass runtimes that don't let you write past the end of an array.&lt;br/&gt;&lt;br/&gt;So, now we've got a nuts 'n' bolts reference implementation, let's look at some more exotic approaches.&lt;br/&gt;&lt;br/&gt;As regular readers will have noticed by now, I'm fairly keen on LINQ - so it should be no surprise that C# is my next port of call. I was amused to recall that the .Net string class lacks a Reverse method so I had to write my own for this, about 20 minutes after I finished pontificating about the clean healthy virtue of doing so in C! (I didn't plan it this way, honest.)&lt;br/&gt;&lt;br/&gt;There are of course many ways of writing a string reversal routine, but rather than attempt to mimic the fairly idiomatic C code above, I did the simple thing:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt; Reverse(&lt;span class="Statement"&gt;this&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt; s) &lt;br/&gt;{ &lt;br/&gt;    &lt;span class="Type"&gt;char&lt;/span&gt;[] ch = s.ToCharArray(); &lt;br/&gt;    Array.Reverse(ch); &lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt;(ch); &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Since the Array class contains a Reverse method, I can just convert my string to an array (of chars), reverse that, then create a new string from it. Done. Things to meditate on regarding this approach:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;It relies on a char array. Strings may look like a native type these days, but I have to expose their dark and shameful lineage to get the job done here.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;The throwback nature of this implementation does not, of course, extend as far as modifying the parameter. A new string is returned and the original remains intact. The garbage collector will take care of deallocation.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;This is an extension method on System.String, so I can use it naturally on any string.&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;Whatever faults it may have, it's definitely easier to read than the C code, since the syntax is much closer to the problem domain. This is a recurring theme when looking at expressiveness. The C code has to specify the entire algorithm for reversing the string, whereas here the Array.Reverse method allows us to ignore the details of &lt;em&gt;how&lt;/em&gt; the string is reversed. For the purposes of this problem, we don't really care how the string is reversed, just that it &lt;em&gt;is&lt;/em&gt; reversed.&lt;br/&gt;&lt;br/&gt;It's still warty, however, in that we have to know to turn the string into an array first, which may be completely non-intuitive to someone who's never tangled with C-style strings.&lt;br/&gt;&lt;br/&gt;With this minor omission from the .Net libraries sorted, the problem can be solved with a single compound LINQ query:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;return&lt;/span&gt; (&lt;span class="Statement"&gt;from&lt;/span&gt; product &lt;span class="Statement"&gt;in&lt;/span&gt; &lt;br/&gt;            ( &lt;br/&gt;             &lt;span class="Statement"&gt;from&lt;/span&gt; i &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(&lt;span class="Constant"&gt;100&lt;/span&gt;, &lt;span class="Constant"&gt;900&lt;/span&gt;) &lt;br/&gt;             &lt;span class="Statement"&gt;from&lt;/span&gt; j &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(i, &lt;span class="Constant"&gt;1000&lt;/span&gt; - i) &lt;br/&gt;             &lt;span class="Statement"&gt;select&lt;/span&gt; i * j) &lt;br/&gt;        &lt;span class="Statement"&gt;where&lt;/span&gt; product.ToString() == product.ToString().Reverse() &lt;br/&gt;        &lt;span class="Statement"&gt;select&lt;/span&gt; product).Max();&lt;/pre&gt;&lt;br/&gt;I think that's pretty concise, and quite readable too. The main thing I don't like about it is the use of Enumerable.Range, which takes 'start' and 'count' parameters rather than 'from' and 'to', which would look more natural in this case. &lt;br/&gt;&lt;br/&gt;Parameters aside, it's interesting to note the relative clumsiness of the twin calls to Enumerable.Range. Back when looking at &lt;a href="http://basildoncoder.com/blog/2008/03/22/project-euler-problems-1-and-2/"&gt;problem 1&lt;/a&gt;, replacing a for loop with a more declarative alternative made the code considerably more expressive. In this case, however, I don't think it helps quite so much. Once again, it's to do with the nature of the problem domain - a nested for loop is quite a natural way to represent the process of generating the products, so the benefit of a declarative approach is less marked.&lt;br/&gt;&lt;br/&gt;How to improve it? For fun, lets go the whole hog and make a simple fluent interface to improve readability of the LINQ query. This is what we want:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;return&lt;/span&gt; (&lt;span class="Statement"&gt;from&lt;/span&gt; product &lt;span class="Statement"&gt;in&lt;/span&gt; AllProducts.From(&lt;span class="Constant"&gt;100&lt;/span&gt;).To(&lt;span class="Constant"&gt;999&lt;/span&gt;) &lt;br/&gt;        &lt;span class="Statement"&gt;where&lt;/span&gt; product.ToString() == product.ToString().Reverse() &lt;br/&gt;        &lt;span class="Statement"&gt;select&lt;/span&gt; product).Max();&lt;/pre&gt;&lt;br/&gt;Nifty, huh? Well actually I have my reservations about fluent interfaces, but it's quite the fashion these days so I thought I'd give it a chance. The example above is trivial to achieve. On a class called AllProducts we need a static method called From which acts as a factory method, and an instance method called To which returns an IEnumerable&amp;lt;int&amp;gt; for use in the LINQ query. The class looks like this:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;class&lt;/span&gt; AllProducts &lt;br/&gt;{ &lt;br/&gt;    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; m_from; &lt;br/&gt;    &lt;span class="Type"&gt;private&lt;/span&gt; AllProducts(&lt;span class="Type"&gt;int&lt;/span&gt; @from) &lt;br/&gt;    { &lt;br/&gt;        m_from = @from; &lt;br/&gt;    }                    &lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; AllProducts From(&lt;span class="Type"&gt;int&lt;/span&gt; from) &lt;br/&gt;    { &lt;br/&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; AllProducts(@from); &lt;br/&gt;    }                    &lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="Type"&gt;int&lt;/span&gt;&amp;gt; To(&lt;span class="Type"&gt;int&lt;/span&gt; to) &lt;br/&gt;    { &lt;br/&gt;        &lt;span class="Type"&gt;int&lt;/span&gt; inclusiveTo = to + &lt;span class="Constant"&gt;1&lt;/span&gt;; &lt;span class="Comment"&gt;// to is inclusive&lt;/span&gt;                    &lt;br/&gt;&lt;br/&gt;        &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Statement"&gt;from&lt;/span&gt; i &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range( &lt;br/&gt;                   m_from, inclusiveTo - m_from) &lt;br/&gt;               &lt;span class="Statement"&gt;from&lt;/span&gt; j &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(i, inclusiveTo - i) &lt;br/&gt;               &lt;span class="Statement"&gt;select&lt;/span&gt; i * j; &lt;br/&gt;    } &lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Fluent interfaces are definitely this season's black. I heard about a guy who wrote a mocking library without using fluent interfaces for expectations, and 500 angry TDD advocates chased him out of the building with pitchforks.&lt;br/&gt;&lt;br/&gt;I'm still a bit wary though, tweedy programmer as I am - I just get a bit nervous about writing hideously contorted classes with a mixture of static and instance methods, some returning the this ref, some returning arbitrary IEnumerables, some acting as factories - and all so the calling code can prance about in a tailored coat and a cool pair of shades. A noble goal, to be sure, but is the price too high? I guess we'll know in a year or two when some maintenance programmer has to try and debug it.&lt;br/&gt;&lt;br/&gt;Enough of the lousy clothes metaphor. To finish up what turned out to be a longer post than expected, here's an F# solution I hacked together before getting sidetracked with the whole fluent thing. I read a blog post &lt;a href="http://geekswithblogs.net/Erik/archive/2008/02/18/119727.aspx"&gt;here&lt;/a&gt; about problem 4 (&lt;em&gt;&lt;strong&gt;warning&lt;/strong&gt; - also contains solution to problem 6&lt;/em&gt;) but didn't like it too much. It seems to be quite common when reading F# code on the web for there to be a reliance on Seq.unfold - I'm not sure it's always the right tool. Then again, my F# is sketchy at best for the moment, so maybe I should shut up. For balance, however, this is my solution without using unfold.&lt;br/&gt;&lt;br/&gt;Note first that F#, as a .Net language, also lacks a built-in way to reverse strings. The implementation is extremely similar to the C# approach above:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; rev &lt;span class="Statement"&gt;(&lt;/span&gt;s:&lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Statement"&gt;)&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;br/&gt;    &lt;span class="Statement"&gt;let&lt;/span&gt; ch &lt;span class="Statement"&gt;=&lt;/span&gt; s.&lt;span class="Constant"&gt;ToCharArray()&lt;/span&gt; &lt;br/&gt;    &lt;span class="Statement"&gt;let&lt;/span&gt; ra &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="PreProc"&gt;Array&lt;/span&gt;.rev ch &lt;br/&gt;    &lt;span class="Statement"&gt;let&lt;/span&gt; r &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt;&lt;span class="Statement"&gt;(&lt;/span&gt;ra&lt;span class="Statement"&gt;)&lt;/span&gt; &lt;br/&gt;    r&lt;/pre&gt;&lt;br/&gt;The actual implementation involves two helpers: a small recursive function to produce all possible products of the numbers contained in two lists, and a simple check to see if a string is equal to itself reversed.&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; &lt;span class="Constant"&gt;Euler4&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;br/&gt;    &lt;span class="Statement"&gt;let&lt;/span&gt; &lt;span class="Statement"&gt;rec&lt;/span&gt; allProducts l1 l2 &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;let&lt;/span&gt; mul a lst &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;br/&gt;            &lt;span class="PreProc"&gt;List&lt;/span&gt;.map &lt;span class="Statement"&gt;(fun&lt;/span&gt; x &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; a &lt;span class="Statement"&gt;*&lt;/span&gt; x&lt;span class="Statement"&gt;)&lt;/span&gt; lst &lt;br/&gt;        &lt;span class="Statement"&gt;match&lt;/span&gt; l1 &lt;span class="Statement"&gt;with&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;|&lt;/span&gt; &lt;span class="Constant"&gt;[]&lt;/span&gt; &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Constant"&gt;[]&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;|&lt;/span&gt; h&lt;span class="Statement"&gt;::&lt;/span&gt;t &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="Statement"&gt;(&lt;/span&gt;mul h l2&lt;span class="Statement"&gt;)&lt;/span&gt; @ &lt;span class="Statement"&gt;(&lt;/span&gt;allProducts t l2&lt;span class="Statement"&gt;)&lt;/span&gt;               &lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;let&lt;/span&gt; isPalindrome x &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;let&lt;/span&gt; str &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="PreProc"&gt;Int32&lt;/span&gt;.to_string x &lt;br/&gt;        str &lt;span class="Statement"&gt;=&lt;/span&gt; rev str&lt;/pre&gt;&lt;br/&gt;With the plumbing in place, we can use the very groovy forward pipe operator to chain together some very readable code. The only thing to note in here is the reverse ordering of the parameters in the call to compare - this is because we want the results in descending order, so that the largest is at the head of the list and easily accessible with List.hd.&lt;br/&gt;&lt;pre&gt;    allProducts &lt;span class="Statement"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;100&lt;/span&gt;..&lt;span class="Constant"&gt;999&lt;/span&gt;&lt;span class="Statement"&gt;]&lt;/span&gt; &lt;span class="Statement"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;100&lt;/span&gt;..&lt;span class="Constant"&gt;999&lt;/span&gt;&lt;span class="Statement"&gt;]&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt; &lt;span class="PreProc"&gt;List&lt;/span&gt;.filter isPalindrome &lt;br/&gt;        &lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt; &lt;span class="PreProc"&gt;List&lt;/span&gt;.sort &lt;span class="Statement"&gt;(fun&lt;/span&gt; x y &lt;span class="Statement"&gt;=&lt;/span&gt; compare y x&lt;span class="Statement"&gt;)&lt;/span&gt; &lt;br/&gt;        &lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt; &lt;span class="PreProc"&gt;List&lt;/span&gt;.hd&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-683295475349604269?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/mGvJNhIjxOE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/683295475349604269/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/project-euler-problem-4.html#comment-form" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/683295475349604269?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/683295475349604269?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/mGvJNhIjxOE/project-euler-problem-4.html" title="Project Euler Problem 4" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/project-euler-problem-4.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo8cCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-3903771830257376035</id><published>2008-04-21T13:51:00.000+01:00</published><updated>2011-10-03T10:11:10.478+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.478+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><title>Test-specific Shims in Production Code</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/44e_YRZx19mkTF9Dozmz4kUFOTk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/44e_YRZx19mkTF9Dozmz4kUFOTk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/44e_YRZx19mkTF9Dozmz4kUFOTk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/44e_YRZx19mkTF9Dozmz4kUFOTk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;We're currently on a fairly major kick to increase automated test coverage of our software. This doesn't just mean 'get the unit test coverage up to scratch', it also means we are working towards full end-to-end integration testing using, amongst other tools, some front-end automation tools such as &lt;a href="http://en.wikipedia.org/wiki/QuickTest_Professional"&gt;QTP&lt;/a&gt; and &lt;a href="http://selenium.openqa.org/"&gt;Selenium&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Of course, nothing is ever easy when trying to polish away the tarnish of ancient code. One particular problem we face regularly is patching up code that breaks the fragile expectations of some of these automation tools.&lt;br/&gt;&lt;br/&gt;Some of our applications - including the one &lt;a href="http://basildoncoder.com/blog/2008/03/21/the-pg-wodehouse-method-of-refactoring/"&gt;I am working to refactor&lt;/a&gt; - contain UI widgets that use a lot of custom painting routines and conceal data pretty well. One widget, for instance, needs to display data with a fast refresh rate and so uses a &lt;a href="http://en.wikipedia.org/wiki/Double_buffering#Double_Buffering_in_Computer_Graphics"&gt;double-buffered&lt;/a&gt; approach to avoid flicker. The data it displays, however, is not stored anywhere; it is discarded as soon as it is rendered. And since the whole widget view is rendered as a bitmap and blitted to screen, there's no convenient hierarchy of panels, labels, text boxes, or any other standard controls.&lt;br/&gt;&lt;br/&gt;This, the Automated QA folks tell me, causes a problem since QTP mainly works by reflecting on properties exposed by controls to get at their data. So, if QTP wants to read some data from a text box, it accesses the Text property of that text box. Simple. But this particular widget doesn't have the equivalent of a Text property.&lt;br/&gt;&lt;br/&gt;This isn't really an oversight from a purely functional point of view, since no part of the actual application code ever needs to get data from the widget - it's a display mechanism only, not an interactive widget like a text box. Data is received from a web service, processed a bit, and dumped into the widget. The widget is the last object to do anything with the data - no other part of the app ever needs it again.&lt;br/&gt;&lt;br/&gt;Since there are no properties on the widget exposing the data, QTP can't get at it.&lt;br/&gt;&lt;br/&gt;Of course, there are ways to keep QTP happy. We can add a few properties to the widget and keep some data around in member variables, or we can write some extensions for QTP that allow it to access some of the widget's internals. The second way is probably the 'right' way since it keeps test-related code external to the application code - but it's more time-consuming, and also has a training cost since most developers aren't going to be familiar with QTP's API.&lt;br/&gt;&lt;br/&gt;This leaves the first option. Traditionally I've always been a bit wary of having what is effectively test code (since it only exists for testing purposes) deployed with production code. Furthermore, doesn't it undermine the tests themselves, since they are dependent on code that never gets executed in production?&lt;br/&gt;&lt;br/&gt;On the other hand, in some instances it may be the more pragmatic thing to do. It's difficult to justify spending a day or two writing a few hundred lines of QTP extension code when the same effect can be garnered by adding a single read-only property. It still doesn't quite sit right for me though, and I can't find much in the way of authoritative literature that argues one way or the other.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-3903771830257376035?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/gGDTef9sL7I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/3903771830257376035/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/test-specific-shims-in-production-code.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3903771830257376035?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/3903771830257376035?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/gGDTef9sL7I/test-specific-shims-in-production-code.html" title="Test-specific Shims in Production Code" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/test-specific-shims-in-production-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo9fip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-2968580459765606243</id><published>2008-04-14T14:50:00.000+01:00</published><updated>2011-10-03T10:11:10.466+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.466+01:00</app:edited><title>Bash History Spelunking</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xcVIWg6X8wnpAXL0fDB-jrwltPs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xcVIWg6X8wnpAXL0fDB-jrwltPs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xcVIWg6X8wnpAXL0fDB-jrwltPs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xcVIWg6X8wnpAXL0fDB-jrwltPs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Learned from &lt;a href="http://www.weiqigao.com/blog/2008/04/11/whats_in_your_history.html"&gt;Weiqi&lt;/a&gt;, who learned from &lt;a href="http://blog.kagesenshi.org/2008/04/me-me.html" target="_blank"&gt;KageSenshi&lt;/a&gt;, about a &lt;a href="http://planet.fedoraproject.org/" target="_blank" rel="nofollow"&gt;Fedora Planet&lt;/a&gt; shell history meme - post the results of running the following command on your linux box:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;history &lt;span class="Statement"&gt;|&lt;/span&gt; awk &lt;span class="Statement"&gt;'&lt;/span&gt;&lt;span class="Constant"&gt;{a[$2]++ } END{for(i in a){print a[i] " " i}}&lt;/span&gt;&lt;span class="Statement"&gt;'|&lt;/span&gt;sort&lt;br/&gt;-rn&lt;span class="Statement"&gt;|&lt;/span&gt;head&lt;/pre&gt;&lt;br/&gt;I won't bother repeating the inevitable warning about the dangers of executing random shell scripts you find on the Internet, because I'm lazy and mean. Anyway, here's the results from my webhosting box:&lt;br/&gt;&lt;pre&gt;231 ll&lt;br/&gt;171 vim&lt;br/&gt;132 cd&lt;br/&gt;50 screen&lt;br/&gt;43 cat&lt;br/&gt;39 tail&lt;br/&gt;34 ls&lt;br/&gt;34 cls&lt;br/&gt;32 exit&lt;br/&gt;31 wget&lt;/pre&gt;&lt;br/&gt;'ll' is an alias for 'ls -l', and 'cls' an alias for 'clear'. No real surprises otherwise - I use vim for development over ssh, I tail my logs occasionally, and live in GNU Screen.&lt;br/&gt;&lt;br/&gt;Here's the output from my home box:&lt;br/&gt;&lt;pre&gt;254 ll&lt;br/&gt;181 cd&lt;br/&gt;148 sudo&lt;br/&gt;123 rm&lt;br/&gt;123 ffmpeg&lt;br/&gt;86 screen&lt;br/&gt;83 ls&lt;br/&gt;75 cls&lt;br/&gt;72 vim&lt;br/&gt;60 find&lt;/pre&gt;&lt;br/&gt;Quite similar actually, guess I'm set in my ways. The ffmpeg count is a bit of an anomaly, since I used it a lot recently to re-encode a bunch of &lt;a href="http://en.wikipedia.org/wiki/Futurama"&gt;Futurama&lt;/a&gt; rips for my mobile.&lt;br/&gt;&lt;br/&gt;Not sure what to do with this remarkable intel, however. Perhaps I'll use the data to generate an &lt;a href="http://www.docuverse.com/blog/donpark/2007/01/19/identicon-explained"&gt;Identicon&lt;/a&gt; and use it as a favicon? Or, perhaps not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-2968580459765606243?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/fMbKn8PV1Cw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/2968580459765606243/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/bash-history-spelunking.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2968580459765606243?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2968580459765606243?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/fMbKn8PV1Cw/bash-history-spelunking.html" title="Bash History Spelunking" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/bash-history-spelunking.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXozcSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-5993157233802949200</id><published>2008-04-08T16:34:00.000+01:00</published><updated>2011-10-03T10:11:10.489+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.489+01:00</app:edited><title>Evil = Important. Apparently.</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bAlgKJy4F81Wxo6Rz-EY5aiOSQ4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bAlgKJy4F81Wxo6Rz-EY5aiOSQ4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bAlgKJy4F81Wxo6Rz-EY5aiOSQ4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bAlgKJy4F81Wxo6Rz-EY5aiOSQ4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;OK, I know I shouldn't even &lt;em&gt;acknowledge&lt;/em&gt; spam blogs, but this one amused me. Some filthy credit-crunch link bait site took an extract from my &lt;a href="http://basildoncoder.com/blog/2008/04/07/project-euler-problem-3/"&gt;previous post&lt;/a&gt; (this is obviously what happens when you say the phrase 'credit card' ... oops) and ran it though an automated word substitution program. The result is fascinating. It turned this:&lt;br/&gt;&lt;blockquote&gt;… you buy something from Amazon, you are protected by the fact that evil black-hats can’t find the prime factors of your encryption key fast enough to steal your credit card number (OK, bit of a generalisation, but that’s the gist). …&lt;/blockquote&gt;&lt;br/&gt;into this:&lt;br/&gt;&lt;blockquote&gt;… you take something from Amazon, you are secure by the fact that important black-hats can’t connexion the matureness factors of your writing key alacritous adequacy to advise your assign calculate sort (OK, discernment of a generalisation, but that’s the gist). …&lt;/blockquote&gt;&lt;br/&gt;Let's review the highlights. 'Buy' replaced with 'take', 'evil' replaced with 'important', 'steal' replaced with 'advise'? Someone's book of synonyms is bound in human hide with a skull on the front.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-5993157233802949200?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/1qKivTFGnxY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/5993157233802949200/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/evil-important-apparently.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/5993157233802949200?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/5993157233802949200?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/1qKivTFGnxY/evil-important-apparently.html" title="Evil = Important. Apparently." /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/evil-important-apparently.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo-fip7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-2297036404341508822</id><published>2008-04-07T13:38:00.000+01:00</published><updated>2011-10-03T10:11:10.456+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.456+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problem 3</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DV4aXQJ68It3iPeA4lBYD_111eU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DV4aXQJ68It3iPeA4lBYD_111eU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DV4aXQJ68It3iPeA4lBYD_111eU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DV4aXQJ68It3iPeA4lBYD_111eU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Next up in the list of Project Euler problems is this one:&lt;br/&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=3"&gt;Problem 3&lt;/a&gt; &lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;blockquote&gt;The prime factors of 13195 are 5, 7, 13 and 29.&lt;br/&gt;&lt;br/&gt;What is the largest prime factor of the number 600851475143?&lt;/blockquote&gt;&lt;br/&gt;This, obviously, is a factorisation problem. There is a colossal amount of material on the web for dealing with prime factorisation - a simple &lt;a href="http://www.google.co.uk/search?q=prime+factorization"&gt;google search&lt;/a&gt; pulls up lots of information. Prime factorisation (and the difficulty of doing it with sufficiently large numbers) is at the heart of the cryptographic methods we currently use on the internet - every time you buy something from Amazon, you are protected by the fact that evil black-hats can't find the prime factors of your encryption key fast enough to steal your credit card number (OK, bit of a generalisation, but that's the gist).&lt;br/&gt;&lt;br/&gt;One of the key phrases in the above paragraph is 'sufficiently large numbers'. For a computer, 600851475143 is not a particularly big number, so this problem can be brute-forced fairly easily. Of course, not all brute force approaches are created equal. The most naive algorithm would be something along the lines of a three-pass sweep - firstly test &lt;em&gt;every single number&lt;/em&gt; between 2 and 600851475143 to see if it divides cleanly into 600851475143 (pass 1); then test each factor from pass 1 to see if it is prime (pass 2); and finally take the biggest of the pass 2 numbers to get your answer (pass 3).&lt;br/&gt;&lt;br/&gt;This would work, but it sucks.&lt;br/&gt;&lt;br/&gt;Fortunately, it's easy to optimise. Let the prime factors of our number N be f&lt;sub&gt;1&lt;/sub&gt;, f&lt;sub&gt;2&lt;/sub&gt; ... f&lt;sub&gt;n&lt;/sub&gt;. If I start with the lowest prime number and work up from there looking for a factor, I know that the first factor I find will be prime (since if it wasn't prime, it would have factors of its own, which by definition would also be factors of our target number). This number is f&lt;sub&gt;1&lt;/sub&gt;. I can divide the target number by f&lt;sub&gt;1&lt;/sub&gt; and then factorise the result to find f&lt;sub&gt;2&lt;/sub&gt;. Continuing this process will result in a list of prime factors, and then it's simply a case of selecting the largest.&lt;br/&gt;&lt;br/&gt;I can optimise further by not resetting the factor to the lowest prime number each time - since having found f&lt;sub&gt;1&lt;/sub&gt; I know that there aren't any smaller factors, so I don't have to waste time looking for them. Here's the implementation in python:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;primeFactors&lt;/span&gt;(n, factor):&lt;br/&gt;    factors = []&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (n % factor != 0):&lt;br/&gt;        factor = factor + 1&lt;br/&gt;&lt;br/&gt;    factors.append(factor)&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; n &amp;gt; factor:&lt;br/&gt;        factors.extend(primeFactors(n / factor, factor))&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; factors&lt;br/&gt;&lt;br/&gt;&lt;span class="Statement"&gt;print&lt;/span&gt; max(primeFactors(600851475143, 2))&lt;/pre&gt;&lt;br/&gt;Note that in the recursive call the current factor is retained, so that the code doesn't repeat itself.&lt;br/&gt;&lt;br/&gt;This executes pretty quickly, but it could be better. For a start, since 600851475143 is odd there's no need to start with the only even prime number (2). Instead, I could just start at 3, and in the while loop skip over even numbers. This would cut the number of tested numbers in half.&lt;br/&gt;&lt;br/&gt;A more efficient trial division approach, however, would be to generate a list of primes, divide 600851475143 by each prime to find the prime factors, then simply select the largest. To use this solution, a prime number generator is needed.&lt;br/&gt;&lt;br/&gt;This is an interesting diversion - I've peeked at some of the other Project Euler problems and know that prime numbers will pop up again, so it may prove useful to have a generator handy for when I get to those. Some languages, like Ruby, have library functions that can give you primes, but other languages don't. If you're not interested in generating primes and just want to know the answer to problem 3, execute the code above and you're free to get down from the table.&lt;br/&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;A Random Walk Off-Topic &lt;/strong&gt;&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;The simplest way to generate primes is known as the &lt;a href="http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes"&gt;Sieve of Eratosthenes&lt;/a&gt; after the Greek mathematician who invented it. In principle it's straightforward - take a list of all integers up to an arbitrary limit, then starting from 2 (the smallest prime), mark all the numbers that are multiples of 2. Then move to the next unmarked number (i.e. 3) and mark all the multiples of 3. Then you move to the next unmarked number (5, since 4 was marked as a multiple of 2) and mark all multiples. And so on, until you get to the end of your list. Whatever numbers remain unmarked are all the primes up to your arbitrary limit.&lt;br/&gt;&lt;br/&gt;.Net lacks a built-in prime generator, so to demonstrate the algorithm I'll create a simple C# implementation. The list of numbers is represented as an array of booleans, all set to true by default except indexes 0 and 1 (since we aren't interested in evaluating those numbers as prime).&lt;br/&gt;&lt;br/&gt;The other requirement for a funky contemporary .Net implementation is, of course, to expose the results with IEnumerable. This achieves two things - firstly, it lets the sieve class control enumeration and thus skip over the marked numbers (making the calling code cleaner), and secondly it lets me use LINQ to query it.&lt;br/&gt;&lt;br/&gt;So, here's the code:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; SieveOfEratosthenes&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt;[] m_numbers;&lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;public&lt;/span&gt; SieveOfEratosthenes(&lt;span class="Type"&gt;long&lt;/span&gt; limit)&lt;br/&gt;    {&lt;br/&gt;        m_numbers = &lt;span class="Statement"&gt;new&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt;[limit + &lt;span class="Constant"&gt;1&lt;/span&gt;];&lt;br/&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;long&lt;/span&gt; l = &lt;span class="Constant"&gt;2&lt;/span&gt;; l &amp;lt; m_numbers.LongLength; ++l)&lt;br/&gt;        {&lt;br/&gt;            m_numbers[l] = &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;2&lt;/span&gt;; i != -&lt;span class="Constant"&gt;1&lt;/span&gt;;&lt;br/&gt;                i = Array.FindIndex(m_numbers, i + &lt;span class="Constant"&gt;1&lt;/span&gt;,&lt;br/&gt;                    b =&amp;gt; b == &lt;span class="Constant"&gt;true&lt;/span&gt;))&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; j = i * &lt;span class="Constant"&gt;2&lt;/span&gt;; j &amp;lt; m_numbers.Length; j += i)&lt;br/&gt;                m_numbers[j] = &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="Type"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="Type"&gt;long&lt;/span&gt;&amp;gt; Primes()&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;long&lt;/span&gt; i = &lt;span class="Constant"&gt;2&lt;/span&gt;; i &amp;lt; m_numbers.LongLength; ++i)&lt;br/&gt;            &lt;span class="Statement"&gt;if&lt;/span&gt; (m_numbers[i])&lt;br/&gt;                &lt;span class="Statement"&gt;yield&lt;/span&gt; &lt;span class="Statement"&gt;return&lt;/span&gt; i;&lt;br/&gt;    }&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Fairly straightforward. Basically, I start by marking 2 as prime. Then, an inner loop sets all multiples of 2 to false, since no (other) even numbers are prime. Each time round the loop, we find the next true element of the array (which will have a prime index), and mark all multiples false as per the description above. The loop terminates when FindIndex fails to find any more true elements.&lt;br/&gt;&lt;br/&gt;This results in an array where the only elements with a value of true are those with a prime index. This makes the actual IEnumerable generator very easy to write - it yield returns the index whenever it finds a true element.&lt;br/&gt;&lt;br/&gt;There's a problem with this code, however, that makes it unusable with Euler problem 3 (at least in .Net - hence why I called it a 'diversion' earlier, rather than an alternative solution). In .Net, you can't create an array with 600851475143 elements, since an array with 600851475143 elements is way above the maximum array size limit of 2GB. Even if each element is only a single byte, 600851475143 bytes is about 560GB.&lt;br/&gt;&lt;br/&gt;Therefore, you can't create a sieve big enough to solve the problem.&lt;br/&gt;&lt;br/&gt;When using trial division it seems that it is enough to only generate primes up to the square root of N, though there are cases when this is not true (e.g. where N=15, sqrt(N) =  ~3.873, but the largest prime factor of 15 is 5), and I don't have the maths (yet!) to know how big a fudge-factor is needed. I've seen a solution on the Project Euler forum that generates primes up to sqrt(N) + 10, which solves the example of N=15 above, but does it solve ALL cases? Another approach might be to generate the list of primes such that the largest prime in the list is the first prime &amp;gt; sqrt(N) - but now I'm completely guessing.&lt;br/&gt;&lt;br/&gt;Still, for numbers that fit inside the 2GB limit, we can find the largest factor easily.&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;&lt;/span&gt;&lt;span class="Type"&gt;var&lt;/span&gt; sieve = &lt;span class="Statement"&gt;new&lt;/span&gt; SieveOfEratosthenes(&lt;span class="Constant"&gt;15&lt;/span&gt;);&lt;/pre&gt;&lt;br/&gt;Now I have my IEnumerable sieve, I can craft a LINQ query to find the largest factor. All I need to do is filter my list of primes for those which divide directly into 15 and call the Max() method:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;return&lt;/span&gt; (&lt;span class="Statement"&gt;from&lt;/span&gt; p &lt;span class="Statement"&gt;in&lt;/span&gt; sieve.Primes()&lt;br/&gt;        &lt;span class="Statement"&gt;where&lt;/span&gt; &lt;span class="Constant"&gt;15&lt;/span&gt; % p == &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;br/&gt;        &lt;span class="Statement"&gt;select&lt;/span&gt; p).Max();&lt;/pre&gt;&lt;br/&gt;Done! And I have a handy reusable prime generator for later on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-2297036404341508822?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/Yr1swm0vUGg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/2297036404341508822/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/04/project-euler-problem-3.html#comment-form" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2297036404341508822?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/2297036404341508822?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/Yr1swm0vUGg/project-euler-problem-3.html" title="Project Euler Problem 3" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>14</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/04/project-euler-problem-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo_fyp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-1708543955765626807</id><published>2008-03-25T18:06:00.000Z</published><updated>2011-10-03T10:11:10.447+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.447+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><title>The Lightbulb Moment</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FgOEM0VXI6K9mBMbRuOPLLG8R7g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FgOEM0VXI6K9mBMbRuOPLLG8R7g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FgOEM0VXI6K9mBMbRuOPLLG8R7g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FgOEM0VXI6K9mBMbRuOPLLG8R7g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.weiqigao.com/blog/"&gt;Weiqi Gao&lt;/a&gt; has a &lt;a href="http://www.weiqigao.com/blog/2008/03/24/scala_still_uncomfortable_after_five_years.html"&gt;post&lt;/a&gt; up today discussing the trials of grokking &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. Scala is a language I want to take a much closer look at later this year, since I want to become current on the &lt;a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine"&gt;JVM&lt;/a&gt; again (having not been on talking terms with it since using J2SE 1.4 around the summer of 2003) without being particularly keen on tangling with the Java language itself.&lt;br/&gt;&lt;br/&gt;One of the key features of Scala is the functional programming style it brings to the JVM. It's actually quite common to use certain functional idioms in Java - e.g. passing around a function as a parameter - but the syntax is clunky and verbose (unless and until closures get confirmed in 1.7, that is, and maybe even then).&lt;br/&gt;&lt;br/&gt;For example, take a look at this very simple idiomatic code for spinning off a thread to perform an expensive operation:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;new&lt;/span&gt; Thread (&lt;span class="Statement"&gt;new&lt;/span&gt; Runnable() {&lt;br/&gt;    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; run() {&lt;br/&gt;        someObj.doExpensiveOperation();&lt;br/&gt;    }&lt;br/&gt;}).start();&lt;/pre&gt;&lt;br/&gt;Now that's not the most hideous code I've ever seen, but it's a bit...wordy. Compare it to this equivalent implementation in Java's closest mainstream relative, C#:&lt;br/&gt;&lt;pre&gt;&lt;span class="Statement"&gt;new&lt;/span&gt; Thread(x =&amp;gt; someObj.DoExpensiveOperation()).Start();&lt;/pre&gt;&lt;br/&gt;I much prefer this syntax, even taking into account the throwaway lambda parameter that's only there to satisfy the ThreadStart signature. The Scala syntax is even nicer, however:&lt;br/&gt;&lt;pre&gt;spawn({ someObj.doSomethingExpensive })&lt;/pre&gt;&lt;br/&gt;This is the sort of thing that piques my interest about the language - expressive syntax and a very funky concurrency model will get my attention, &lt;em&gt;especially&lt;/em&gt; when running on something as mainstream as the JVM and with full interoperability with the frankly staggeringly-vast  Java library ecosystem. I like F# on the &lt;a href="http://en.wikipedia.org/wiki/Common_Language_Runtime"&gt;CLR&lt;/a&gt; for similar reasons.&lt;br/&gt;&lt;br/&gt;But I digress; what I wanted to talk about was a point made by Weiqi, when discussing the pattern-matching capabilities of Scala:&lt;br/&gt;&lt;blockquote&gt;Pattern matching in Scala is exactly the point at which I would spend time trying to understand it, trying to master it, trying to learn to use it. I understand the syntax. I understand the explanation that the speakers in presentations gave. I do get to the part where I say "This is cool." But I never get to the point where I would see a problem and say "This problem is best solved with pattern matching, let me fire up Scala and code the solution."&lt;/blockquote&gt;&lt;br/&gt;This strikes a chord for me, as I have gone through that stage once or twice myself with other features in other languages and yet can't quite put my finger on how I get past it. I don't think it's something you consciously do - it's just something you keep grafting away at until suddenly you realise that the technique, whatever it is, has become part of your armoury.&lt;br/&gt;&lt;br/&gt;Closures are an obvious example I can think of in my own background. I was raised as a straight-down-the-middle C++ man, way back in the early/mid-90s, cutting my teeth on Borland Turbo C++ 3 on Windows 3.1. When I first started to play with functional languages it took a long time for me to 'get it', and even when I understood what a closure was after a couple of weekends hacking around in OCaml, I couldn't envisage when I'd ever need one.&lt;br/&gt;&lt;br/&gt;Soon after, whilst working on a Konfabulator widget in javascript, I noticed I was using them all the time. I suddenly had much more insight into what ruby blocks were doing. It wasn't so much that I noticed the lights go on - &lt;em&gt;they'd been on for some time&lt;/em&gt; and I hadn't realised.&lt;br/&gt;&lt;br/&gt;People commonly refer to the 'lightbulb moment' or 'the lights went on' as being the point where a flash of inspiration hits and everything suddenly makes sense. I don't like this metaphor. If I need to go to the bathroom in the middle of the night, when the lights go on I squint in pain and stagger around just as blindly as I did before. But then I acclimatise, and all becomes clear. And so it is, I think, with learning alien concepts - you need a bit of time to adjust to the dazzling light.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-1708543955765626807?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/Va8EbXBddNg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/1708543955765626807/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/03/lightbulb-moment.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1708543955765626807?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1708543955765626807?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/Va8EbXBddNg/lightbulb-moment.html" title="The Lightbulb Moment" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/03/lightbulb-moment.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXs6eSp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-8778379628843244729</id><published>2008-03-22T17:33:00.000Z</published><updated>2011-10-03T10:11:10.511+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.511+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Mathematics" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><category scheme="http://www.blogger.com/atom/ns#" term="Project Euler" /><title>Project Euler Problems 1 and 2</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DD842olW08j1jeeEmx9l6rz5r4E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DD842olW08j1jeeEmx9l6rz5r4E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DD842olW08j1jeeEmx9l6rz5r4E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DD842olW08j1jeeEmx9l6rz5r4E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Browsing through &lt;a href="http://natehoellein.blogspot.com/"&gt;Nate Hoellein's blog&lt;/a&gt; recently led me to &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt;. This is a problem - I have a horrendous feeling I'm about to get addicted to it, to the cost of just about everything else that normally occupies my free time. Ack.&lt;br/&gt;&lt;br/&gt;Still, at least it provides some blogging material. I'm going to start working my way through the list, and try to create idiomatic solutions in a number of languages. I won't always look for the most efficient solution, since I'm also interested in expressiveness (see &lt;a href="http://basildoncoder.com/blog/2008/01/26/fab-fib/"&gt;here&lt;/a&gt; and &lt;a href="http://basildoncoder.com/blog/2008/02/22/code-can-be-beautiful/"&gt;here&lt;/a&gt; for previous posts on the subject).&lt;br/&gt;&lt;br/&gt;To start with, here's some code and thoughts for problems 1 and 2.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=1"&gt;&lt;em&gt;&lt;strong&gt;Problem 1&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;br/&gt;&lt;blockquote&gt;Add all the natural numbers below 1000 that are multiples of 3 or 5.&lt;/blockquote&gt;&lt;br/&gt;This is generally regarded as the easiest Euler problem, so shouldn't present too many problems. Mainstream software development is still dominated by imperative languages and styles, so the most recognisable solution to this would be a straightforward for-loop. Here is an imperative C# solution:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;int&lt;/span&gt; result = &lt;span class="Constant"&gt;0&lt;/span&gt;;&lt;br/&gt;&lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="Type"&gt;int&lt;/span&gt; i = &lt;span class="Constant"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class="Constant"&gt;1000&lt;/span&gt;; ++i)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (i % &lt;span class="Constant"&gt;3&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt; || i % &lt;span class="Constant"&gt;5&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt;)&lt;br/&gt;        result += i;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Simple enough, but as with all for-loops the guts are a little too visible. I have to explicitly declare and increment an accumulator variable as well as the loop counter. A functional style (Haskell in this case) allows a more declarative solution:&lt;br/&gt;&lt;pre&gt;sum &lt;span class="Statement"&gt;$&lt;/span&gt; filter (&lt;span class="Statement"&gt;\&lt;/span&gt;n &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; n &lt;span class="Statement"&gt;`mod`&lt;/span&gt; &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Statement"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;||&lt;/span&gt; n &lt;span class="Statement"&gt;`mod`&lt;/span&gt; &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Statement"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Statement"&gt;$&lt;/span&gt; [&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Statement"&gt;..&lt;/span&gt;&lt;span class="Constant"&gt;999&lt;/span&gt;]&lt;/pre&gt;&lt;br/&gt;Or, with list comprehensions:&lt;br/&gt;&lt;pre&gt;sum [n &lt;span class="Statement"&gt;|&lt;/span&gt; n &lt;span class="Statement"&gt;&amp;lt;-&lt;/span&gt; [&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Statement"&gt;..&lt;/span&gt;&lt;span class="Constant"&gt;999&lt;/span&gt;], n &lt;span class="Statement"&gt;`mod`&lt;/span&gt; &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Statement"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;||&lt;/span&gt; n &lt;span class="Statement"&gt;`mod`&lt;/span&gt; &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Statement"&gt;==&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;]&lt;/pre&gt;&lt;br/&gt;In both cases, the loop is replaced by a list generated from Haskell's range operator. [1..999] creates a list containing every integer between 1 and 999 inclusive. The modulo test is basically the same, though Haskell lacks a modulo operator (% in most C-family languages) so the mod function is used instead.&lt;br/&gt;&lt;br/&gt;Just for fun, here's an F# solution too:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; sum &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="PreProc"&gt;List&lt;/span&gt;.fold_left &lt;span class="Statement"&gt;(&lt;/span&gt;+&lt;span class="Statement"&gt;)&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;br/&gt;&lt;span class="Statement"&gt;let&lt;/span&gt; mod35 &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Statement"&gt;fun&lt;/span&gt; x &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; x % &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;||&lt;/span&gt; x % &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;&lt;span class="PreProc"&gt;List&lt;/span&gt;.filter mod35 &lt;span class="Statement"&gt;[&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;..&lt;span class="Constant"&gt;999&lt;/span&gt;&lt;span class="Statement"&gt;]&lt;/span&gt; &lt;span class="Statement"&gt;|&lt;/span&gt;&lt;span class="Statement"&gt;&amp;gt;&lt;/span&gt; sum&lt;/pre&gt;&lt;br/&gt;This could be compressed into a one-liner like the Haskell solutions, but it would be a bit long for my taste. Also note F# is slightly hamstrung by the lack of a built-in sum function, so I have to define my own using fold. Another F# solution is &lt;a href="http://blogs.msdn.com/chrsmith/archive/2007/10/23/Project-Euler-in-F_2300_-_2D00_-Problem-1.aspx"&gt;here&lt;/a&gt;, but I prefer mine. There's a very nice snippet in the comments of that page, though, which I like even more:&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;&lt;span class="PreProc"&gt;Seq&lt;/span&gt;.fold1 &lt;span class="Statement"&gt;(&lt;/span&gt;+&lt;span class="Statement"&gt;)&lt;/span&gt; &lt;span class="Statement"&gt;{for&lt;/span&gt; i &lt;span class="Statement"&gt;in&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;..&lt;span class="Constant"&gt;999&lt;/span&gt; &lt;span class="Statement"&gt;when&lt;/span&gt; i % &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Statement"&gt;*&lt;/span&gt; i % &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;-&amp;gt;&lt;/span&gt; i&lt;span class="Error"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br/&gt;Interestingly, C# is gaining some fairly powerful functional techniques lately, in particular LINQ. I can use the new Enumerable class to mimic range syntax and filter functionality from other languages, and lambdas to keep the code concise.&lt;br/&gt;&lt;pre&gt;Enumerable.Range(&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;999&lt;/span&gt;).Where(&lt;br/&gt;        f =&amp;gt; f % &lt;span class="Constant"&gt;3&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt; || f % &lt;span class="Constant"&gt;5&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt;).Sum();&lt;/pre&gt;&lt;br/&gt;Note the similarity between F#/Haskell's lambda syntax and that of C#. It's very cool that a mainstream C-derivative language is getting this sort of syntax added to it.&lt;br/&gt;&lt;br/&gt;Alternatively, I could use LINQ query expressions for a different approach:&lt;br/&gt;&lt;pre&gt;&lt;span class="Type"&gt;var&lt;/span&gt; nums = &lt;span class="Statement"&gt;from&lt;/span&gt; n &lt;span class="Statement"&gt;in&lt;/span&gt; Enumerable.Range(&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;999&lt;/span&gt;)&lt;br/&gt;           &lt;span class="Statement"&gt;where&lt;/span&gt; n % &lt;span class="Constant"&gt;3&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt; || n % &lt;span class="Constant"&gt;5&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt;&lt;br/&gt;           &lt;span class="Statement"&gt;select&lt;/span&gt; n;&lt;br/&gt;nums.Sum();&lt;/pre&gt;&lt;br/&gt;Fun!&lt;br/&gt;&lt;br/&gt;It should be noted that all the Project Euler problems I've seen so far have mathematical solutions, meaning if you are able to classify the problem correctly it is straightforward to work out the answer with pen and paper. In this case, the problem is based around an arithmetic progression, and there are powerful formulae for reasoning about those. If you're interested, check out the &lt;a href="http://projecteuler.net/index.php?section=forum&amp;amp;id=1"&gt;forum&lt;/a&gt; for problem 1.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=2"&gt;&lt;em&gt;&lt;strong&gt;Problem 2&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;br/&gt;&lt;blockquote&gt;Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:&lt;br/&gt;&lt;p style="text-align: center"&gt;1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...&lt;/p&gt;&lt;br/&gt;Find the sum of all the even-valued terms in the sequence which do not exceed four million.&lt;/blockquote&gt;&lt;br/&gt;Ooh, Fibonacci. I've &lt;a href="http://basildoncoder.com/blog/2008/01/26/fab-fib/"&gt;been here before&lt;/a&gt;. Using the Haskell code from that post makes problem 2 a snip:&lt;br/&gt;&lt;pre&gt;fib &lt;span class="Statement"&gt;=&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;:&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt; &lt;span class="Statement"&gt;:&lt;/span&gt; zipWith (&lt;span class="Statement"&gt;+&lt;/span&gt;) fib (tail fib)&lt;br/&gt;sum &lt;span class="Statement"&gt;$&lt;/span&gt; filter even &lt;span class="Statement"&gt;$&lt;/span&gt; takeWhile (&lt;span class="Statement"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Constant"&gt;4000000&lt;/span&gt;) fib&lt;/pre&gt;&lt;br/&gt;Given the lazy Fibonacci generator in the first line,  this just uses standard Haskell functions from the Prelude to do all the work - reading right to left, takeWhile pulls data from the fib sequence until the test fails (i.e. we've reached 4,000,000), filter even does exactly what it says on the tin, and sum does the business on the result.&lt;br/&gt;&lt;br/&gt;C# could solve problem 1 very neatly - can it keep up the pace in problem 2? Actually, yes it can, after a fashion. The lazy Fibonacci generator can be implemented using the yield statement added in C# 2.0. This is much more efficient than the naive recursive solution I looked at in my previous post about Fibonacci sequences. Once I have the generator, the LINQ statement is very concise and quite similar to the Haskell code - C# 3.0 even has TakeWhile!&lt;br/&gt;&lt;pre&gt;IEnumerable&amp;lt;&lt;span class="Type"&gt;long&lt;/span&gt;&amp;gt; Fibs()&lt;br/&gt;{&lt;br/&gt;    &lt;span class="Type"&gt;long&lt;/span&gt; a = &lt;span class="Constant"&gt;0&lt;/span&gt;, b = &lt;span class="Constant"&gt;1&lt;/span&gt;;&lt;br/&gt;&lt;br/&gt;    &lt;span class="Statement"&gt;while&lt;/span&gt; (&lt;span class="Constant"&gt;true&lt;/span&gt;)&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="Statement"&gt;yield&lt;/span&gt; &lt;span class="Statement"&gt;return&lt;/span&gt; b;&lt;br/&gt;&lt;br/&gt;        b = a + b;&lt;br/&gt;        a = b - a;&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;Fibs().TakeWhile(f =&amp;gt; f &amp;lt; &lt;span class="Constant"&gt;4000000&lt;/span&gt;).Where(f =&amp;gt; f % &lt;span class="Constant"&gt;2&lt;/span&gt; == &lt;span class="Constant"&gt;0&lt;/span&gt;).Sum();&lt;/pre&gt;&lt;br/&gt;The more I use C# 3.0, the more I like it - there's quite a bit of power in there.&lt;br/&gt;&lt;br/&gt;As with problem 1, there are some fascinating mathematical tricks that can be utilised when solving problem 2, and I recommend you check out the &lt;a href="http://projecteuler.net/index.php?section=forum&amp;amp;id=2"&gt;forum&lt;/a&gt;. It's particularly cool to see how the Golden Ratio can be brought into play when working with Fibonacci sequences - I had no idea these techniques existed. So much to learn!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-8778379628843244729?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/KssFpUqVVNM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/8778379628843244729/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/03/project-euler-problems-1-and-2.html#comment-form" title="15 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8778379628843244729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/8778379628843244729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/KssFpUqVVNM/project-euler-problems-1-and-2.html" title="Project Euler Problems 1 and 2" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>15</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/03/project-euler-problems-1-and-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo_eCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-1184472032644454904</id><published>2008-03-21T23:01:00.000Z</published><updated>2011-10-03T10:11:10.440+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.440+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Engineering" /><category scheme="http://www.blogger.com/atom/ns#" term="Coding" /><title>The P.G. Wodehouse Method Of Refactoring</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xj0fzaWl_4gyAvV30dxnt4NH2_s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xj0fzaWl_4gyAvV30dxnt4NH2_s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xj0fzaWl_4gyAvV30dxnt4NH2_s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xj0fzaWl_4gyAvV30dxnt4NH2_s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I am much given to ruminating on refactoring at the moment, as one of my current projects is a major overhaul of a fairly large (&amp;gt;31,000 lines) application which has exactly the kind of dotted history any experienced developer has learned to fear - written by many different people, including short-term contractors, at a time in the company's life when first-mover advantage was significantly more important than coding best-practice, and without any consistent steer on the subjects of structure, coding conventions, unit tests, and so on.&lt;br/&gt;&lt;br/&gt;In other words, here be dragons.&lt;br/&gt;&lt;br/&gt;In fairness, the application &lt;em&gt;works&lt;/em&gt; and has been a critical part of a company that has gone from nothing to market-leading multinational in 7 years, so it has certainly pulled its weight. It is in desperate need of a spring-clean though, and my team volunteered to spend 3 months evicting the cobwebs and polishing the brasswork.&lt;br/&gt;&lt;br/&gt;Yes, &lt;em&gt;volunteered&lt;/em&gt; - it's a fascinating challenge, though perhaps not something you'd want to make a career of.&lt;br/&gt;&lt;br/&gt;Now, the first mistake to avoid here is the compulsion to throw it away and rewrite from scratch. So often when confronted with a vast seething moiling spiritless mass of code a developer throws his hands into the air and declares it a lost cause. &lt;strong&gt;How seductive is the thought that 31,000 lines of code could be thrown away and replaced with ~15,000 lines of clean, well-designed, &lt;a href="http://basildoncoder.com/blog/2008/02/22/code-can-be-beautiful/"&gt;beautiful code&lt;/a&gt;?&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Sadly, that's often a path to disaster. It's almost a rule of the game. &lt;a href="http://www.jwz.org/"&gt;jwz&lt;/a&gt; left Netscape because he knew their decision to rewrite from scratch was doomed. &lt;a href="http://www.joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt; wrote a &lt;a href="http://www.joelonsoftware.com/articles/fog0000000069.html"&gt;rant&lt;/a&gt; about the same decision - in fact, the Netscape rewrite is commonly cited as a major factor in Netscape losing the first browser war.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;The problem is that warty old code isn't always just warty - it's &lt;em&gt;battle-scarred&lt;/em&gt;.&lt;/strong&gt; It has years of tweaks and bug-fixes in there to deal with all sorts of edge conditions and obscure environments. Throw that out and replace it with pristine new code, and you'll often find that a load of very old issues suddenly come back to haunt you.&lt;br/&gt;&lt;br/&gt;So, a total rewrite is out. This means working with the old code, and finding ways to wrestle it into shape. Naturally, &lt;em&gt;&lt;a href="http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052"&gt;Working Effectively With Legacy Code&lt;/a&gt;&lt;/em&gt; now has an even more firmly established place on my 'critical books' bookshelf than it did before.&lt;br/&gt;&lt;br/&gt;Inspiration came from a less well-known book, however. Buried in Chapter 10 of &lt;em&gt;&lt;a href="http://www.amazon.co.uk/Code-Reading-Perspective-Effective-Development/dp/0201799405"&gt;Code Reading&lt;/a&gt;&lt;/em&gt; is a single paragraph suggesting that it can be useful when working with unfamiliar code to paste it into a word processor and zoom out, getting a 'bird's eye' view.&lt;br/&gt;&lt;blockquote&gt;One other interesting way to look at a whole lot of source code quickly under Windows is to load it into Microsoft Word and then set the zoom factor to 10%. Each page of code will appear at about the size of a postage stamp, and you can get a surprising amount of information about the code's structure from the shape of the lines.&lt;br/&gt;&lt;p align="right"&gt;(Spinellis, 2003)&lt;/p&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;br/&gt;The idea is that this lets you immediately identify potential trouble spots - if you see pages where the code is all bunched up on the right, it indicates massive nesting and over-long functions. If you see heavy congestion, it indicates dense code. It's also easy to spot giant switch statements and other crimes against humanity.&lt;br/&gt;&lt;br/&gt;Of course, you don't actually need MS Word to do this - the Print Preview in Open Office is more than sufficient, and no doubt most office suites can do the same.&lt;br/&gt;&lt;p style="text-align: center"&gt;&lt;img src="http://basildoncoder.com/images/print-preview-birds-eye-view.png" alt="" /&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;This 50,000ft view could be a useful tool in tracking progress. I mean sure, we can have our build system spit out &lt;a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;cyclomatic complexity&lt;/a&gt; and code size metrics, but wouldn't it be neat if we could do a weekly bird's-eye printout of the source code and pin it up on the wall, giving a nice simple visual representation of the simplification of the code?&lt;br/&gt;&lt;br/&gt;Except, of course, that with average page lengths of 45 lines we'd need almost 700 pages each time, and a hell of a lot of wall space.&lt;br/&gt;&lt;br/&gt;A better solution would be to print a class per page. At the start of the project, the application had about 150 classes, and the refactoring effort is focussed on about 80 of those. Initially, gigantic classes would be an incomprehensible smudge of grey, but as the refactoring process starts tidying the code and factoring out into other classes, &lt;strong&gt;the weekly printout would start to literally come into focus&lt;/strong&gt;, hopefully ending up with many pages actually containing readable code (which happens roughly when the class is small enough to fit on no more than 3 pages at normal size).&lt;br/&gt;&lt;br/&gt;The first time we pinned up the printouts, I suddenly recalled a Douglas Adams foreword reprinted in &lt;em&gt;&lt;a href="http://www.amazon.co.uk/Salmon-Doubt-Hitchhiking-Galaxy-Last/dp/0330323121"&gt;The Salmon of Doubt&lt;/a&gt;&lt;/em&gt;. Adams was a great fan of P.G. Wodehouse, and explained Wodehouse's interesting drafting technique:&lt;br/&gt;&lt;blockquote&gt;It is the next stage of writing—the relentless revising, refining, and polishing—that turned his works into the marvels of language we know and love. When he was writing a book, he used to pin the pages in undulating waves around the wall of his workroom. Pages he felt were working well would be pinned up high, and those that still needed work would be lower down the wall. His aim was to get the entire manuscript up to the picture rail before he handed it in.&lt;br/&gt;&lt;p align="right"&gt;(Adams, 2002)&lt;/p&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;br/&gt;Hmm, isn't redrafting a literary cousin of refactoring? In many ways, I think it is - so &lt;strong&gt;why not apply this technique to refactoring?&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;And we've made it so. We tied a piece of string horizontally across the wall - that's our 'picture rail'. Every week we reprint the classes we have been working on, and replace the old printouts. Then we move them up towards the string, in accordance with how happy we are with the view.&lt;br/&gt;&lt;br/&gt;Obviously, this doesn't replace all the other tools we have for evaluating code quality - e.g. the aforementioned metrics, unit tests, manual QA, and so on. It does, however, make for a brilliant way of tracking our &lt;em&gt;subjective &lt;/em&gt;satisfaction with the class. &lt;strong&gt;Software quality tools can never completely replace the gut instinct of a developer&lt;/strong&gt; - you might have massive test coverage, but that won't help with subjective measures such as &lt;a href="http://en.wikipedia.org/wiki/Code_smell"&gt;code smells&lt;/a&gt;. With Wodehouse-style refactoring, we can now easily keep track of which code we are happy with, and which code we remain deeply suspicious of.&lt;br/&gt;&lt;br/&gt;As an added benefit, all those pages nicely cover up the hideous wall colour. Bonus!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-1184472032644454904?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/HAuk4s6z0Ho" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/1184472032644454904/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/03/pg-wodehouse-method-of-refactoring.html#comment-form" title="70 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1184472032644454904?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1184472032644454904?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/HAuk4s6z0Ho/pg-wodehouse-method-of-refactoring.html" title="The P.G. Wodehouse Method Of Refactoring" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>70</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/03/pg-wodehouse-method-of-refactoring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcDQXo-eCp7ImA9WhdUFk4.&quot;"><id>tag:blogger.com,1999:blog-6463868755041106203.post-1877348851176420007</id><published>2008-03-18T23:51:00.000Z</published><updated>2011-10-03T10:11:10.450+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T10:11:10.450+01:00</app:edited><title>Arthur C. Clarke, 16/12/1917 - 18/03/2008: Indistinguishable From Magic</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gwVRrRQtLnauGyeauCx9aEpmNpk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gwVRrRQtLnauGyeauCx9aEpmNpk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gwVRrRQtLnauGyeauCx9aEpmNpk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gwVRrRQtLnauGyeauCx9aEpmNpk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Sad news - &lt;a href="http://news.bbc.co.uk/1/hi/uk/7304004.stm"&gt;the legendary Arthur C. Clarke has died&lt;/a&gt;. He'll be greatly missed; Clarke novels occupy a full shelf of my floor-to-ceiling bookcase, and &lt;em&gt;&lt;a href="http://en.wikipedia.org/wiki/Rendezvous_with_rama"&gt;Rendezvous With Rama&lt;/a&gt;&lt;/em&gt; stands proud as the finest sci-fi it has ever been my pleasure to read.&lt;br/&gt;&lt;br/&gt;Aside from his very visible mastery of sci-fi, however, there is much to remember Clarke for. He is responsible for popularising the concept of &lt;a href="http://en.wikipedia.org/wiki/Geostationary_orbit"&gt;geostationary orbit&lt;/a&gt;, which is very important for practical global telecommunications. When you watch the Olympics on TV this summer, you can thank Clarke for the fact that you haven't had to go to China to see it.&lt;br/&gt;&lt;br/&gt;Perhaps best of all, though, is his now-infamous &lt;a href="http://en.wikipedia.org/wiki/Clarke's_three_laws"&gt;Third Law&lt;/a&gt;:&lt;br/&gt;&lt;blockquote&gt;Any sufficiently advanced technology is indistinguishable from magic.&lt;/blockquote&gt;&lt;br/&gt;Clarke's Third Law has been quoted, referenced, and paraphrased copiously since he coined it, and it is almost axiomatic for many technologists. As a software engineer, I get a wry enjoyment from Gehm's Corollary, i.e. "any technology distinguishable from magic is insufficiently advanced" - a sobering thought when confidently hacking away on the next big thing!&lt;br/&gt;&lt;br/&gt;If your users don't think your software is magic, then you have room for improvement. I believe Clarke would have approved of that sentiment. R.I.P.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6463868755041106203-1877348851176420007?l=blog.basildoncoder.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/basildoncoder/sLzB/~4/EcULErb_N4Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.basildoncoder.com/feeds/1877348851176420007/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.basildoncoder.com/2008/03/arthur-c-clarke-16121917-18032008.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1877348851176420007?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6463868755041106203/posts/default/1877348851176420007?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/basildoncoder/sLzB/~3/EcULErb_N4Q/arthur-c-clarke-16121917-18032008.html" title="Arthur C. Clarke, 16/12/1917 - 18/03/2008: Indistinguishable From Magic" /><author><name>Russ Gray</name><uri>https://profiles.google.com/102559471807447493728</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-C3TM0_MXEkA/AAAAAAAAAAI/AAAAAAAABfs/rEKhU8SKwRE/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://blog.basildoncoder.com/2008/03/arthur-c-clarke-16121917-18032008.html</feedburner:origLink></entry></feed>

