<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx</link><description>Other posts in the series: Part I - Background Part II - Tuples Part III - Records Part IV - Type Unions Part V - The Match operator Tuples are a way for you not to name things. In Object Oriented languages you got to name everything. If you need to represent</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>AC# library to write functional code - Part II - Tuples | Air Condition Service and Supplies in Your City</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8370734</link><pubDate>Wed, 09 Apr 2008 05:00:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8370734</guid><dc:creator>AC# library to write functional code - Part II - Tuples | Air Condition Service and Supplies in Your City</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://airconditioner.crutoo.com/2008/04/08/ac-library-to-write-functional-code-part-ii-tuples/"&gt;http://airconditioner.crutoo.com/2008/04/08/ac-library-to-write-functional-code-part-ii-tuples/&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8372741</link><pubDate>Wed, 09 Apr 2008 19:57:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8372741</guid><dc:creator>Jacob</dc:creator><description>&lt;p&gt;What about:&lt;/p&gt;
&lt;p&gt;internal static bool DSEquals&amp;lt;T&amp;gt;(T left, T right) {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;if (left == null &amp;amp;&amp;amp; right == null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return true;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;if (left == null &amp;amp;&amp;amp; right != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return false;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;var len = left as IEnumerable;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;var ren = right as IEnumerable;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;if (len == null &amp;amp;&amp;amp; ren == null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return left.Equals(right);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;if (len != null &amp;amp;&amp;amp; ren != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return SequenceEqual(len, ren);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;return false;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
</description></item><item><title>Great work! What about anonymous types?</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8398992</link><pubDate>Wed, 16 Apr 2008 16:47:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398992</guid><dc:creator>Adam Cooper</dc:creator><description>&lt;p&gt;Luca,&lt;/p&gt;
&lt;p&gt;Thanks so much for sharing this, both your posts and the source code. &lt;/p&gt;
&lt;p&gt;I really like your idea of bringing some (more) of F#'s goodness to C#. I spent some time investigating if F# was the right tool for some of our company projects and, while I think F# is fantastic, our domain is one of storing and retrieving lots of hierarchical data, a domain which is ideal for an object-oriented language like C#. So C# is the clear choice for us (in the vast majority of cases). However, there are quite a few aspects of functional programming I'm really beginning to admire. &lt;/p&gt;
&lt;p&gt;I've never been happy with the OO paradigm of many-inputs-one-output, and I find your Tuples solution exciting. Can you comment on how your Tuples implementation differs from anonymous types in C#?&lt;/p&gt;
&lt;p&gt;Thanks and keep up the good work,&lt;/p&gt;
&lt;p&gt;Adam Cooper&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8399162</link><pubDate>Wed, 16 Apr 2008 19:26:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8399162</guid><dc:creator>lucabol</dc:creator><description>&lt;p&gt;Thanks for the kind words.&lt;/p&gt;
&lt;p&gt;There are two differences:&lt;/p&gt;
&lt;p&gt;1. Anonymous types allow you to give a name to each property, while tuple don't.&lt;/p&gt;
&lt;p&gt;2. You cannot return anonymous types from methods or passing them as parameters. So their used is limited to the body of a method.&lt;/p&gt;
&lt;p&gt;Overall anonymous types are a mix of tuples and records. I'll talk about records in an upcoming post.&lt;/p&gt;
</description></item><item><title>A C# library to write functional code - Part III - Records</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8415054</link><pubDate>Mon, 21 Apr 2008 20:35:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8415054</guid><dc:creator>Luca Bolognese's WebLog</dc:creator><description>&lt;p&gt;Previous posts: Part I - Background Part II - Tuples Now that we know what Tuples are, we can start talking&lt;/p&gt;
</description></item><item><title>Community Convergence XLIII</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8419905</link><pubDate>Wed, 23 Apr 2008 23:58:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8419905</guid><dc:creator>Charlie Calvert's Community Blog</dc:creator><description>&lt;p&gt;Welcome to the forty-third issue of Community Convergence. The last few weeks have been consumed by the&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8421117</link><pubDate>Thu, 24 Apr 2008 11:12:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8421117</guid><dc:creator>Configurator</dc:creator><description>&lt;p&gt;I'm wondering: Doesn't CheckNull cause an infinite loop?&lt;/p&gt;
&lt;p&gt;Usually when checking null, I would use ReferenceEquals(t, null) because == would call the type's operator ==, which checks for null causing an infinite loop.&lt;/p&gt;
&lt;p&gt;If CheckNull accepted an object and wasn't generic, if would use object's ==, which works for null. But since it's generic it should use the == that you supplied.&lt;/p&gt;
&lt;p&gt;Am I missing something here?&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8421174</link><pubDate>Thu, 24 Apr 2008 12:04:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8421174</guid><dc:creator>Eamon Nerbonne</dc:creator><description>&lt;p&gt;I've also needed to build these things, and have also run into some of the same issues you seem to have here - like the surprising unhandiness of structs (and even more surprising slowness).&lt;/p&gt;
&lt;p&gt;Incidentally, your hash-code is no good. &amp;nbsp;You don't want to use a symmetric combination of two hash codes, since that means that F.Tuple(true,false) is equal to F.Tuple(false, true) in terms of hashcode. &amp;nbsp;A non-symmetric combination is probably best; but the instantly obvious subtraction is definitely not a good idea, since that means that all tuples of two elements with identical members have a hash-code of 0.&lt;/p&gt;
&lt;p&gt;I choose to scale the hashcode with a prime number. &amp;nbsp;Trial and error on my test-set (consisting of lower-case strings which may not be representative for others) found that 137 is fine; so that's what I use, but I haven't researched the issue.&lt;/p&gt;
&lt;p&gt;Further, if your tuples will be used extensively in things like lookup tables, then hash-code calculation becomes relevant: &amp;nbsp;you might want to store the hashcode once and reuse it (which can also help speed up equality comparisons when these are performed outside of a hash table).&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8422197</link><pubDate>Thu, 24 Apr 2008 20:11:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8422197</guid><dc:creator>lucabol</dc:creator><description>&lt;p&gt;It doesn't go into an infinite loop because it is generic. We cannot call the overload == because at that point in the code we don't know what it is. So we box it and 'compare the pointer' insted. The commented IL for the function should clarify:&lt;/p&gt;
&lt;p&gt;.method public hidebysig static void CheckNull&amp;lt;T&amp;gt;(!!T t) cil managed&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;.maxstack 2&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;.locals init (&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[0] bool CS$4$0000)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0000: nop &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0001: ldarg.0 &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0002: box !!T // We box it&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0007: ldnull &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0008: ceq // We compare it&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_000a: ldc.i4.0 &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_000b: ceq &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_000d: stloc.0 &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_000e: ldloc.0 &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_000f: brtrue.s L_0017&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0011: newobj instance void [mscorlib]System.ArgumentNullException::.ctor()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0016: throw &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;L_0017: ret &lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8422200</link><pubDate>Thu, 24 Apr 2008 20:12:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8422200</guid><dc:creator>lucabol</dc:creator><description>&lt;p&gt;Eamon: I know my hash is bad. I was too lazy to produce a better one :)&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8434235</link><pubDate>Mon, 28 Apr 2008 07:42:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8434235</guid><dc:creator>David Nelson</dc:creator><description>&lt;p&gt;The problem with your &amp;quot;this should never be null&amp;quot; logic is that it prevents the user from ever writing code like this:&lt;/p&gt;
&lt;p&gt;Tuple&amp;lt;int, int&amp;gt; MyMethod()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; Tuple&amp;lt;int, int&amp;gt; result = null;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; // Some code which may or may not set result&lt;/p&gt;
&lt;p&gt; &amp;nbsp; if(result == null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Some other code which always sets the result&lt;/p&gt;
&lt;p&gt; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; return result;&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;This is a reasonably common pattern. Your code is checking for null in the wrong place. It is not unreasonable that any Tuple reference might &amp;nbsp;sometimes be null. Tuples should only be checked for null where it is sure that they should never be null.&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8435756</link><pubDate>Mon, 28 Apr 2008 20:27:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8435756</guid><dc:creator>lucabol</dc:creator><description>&lt;p&gt;Hi David,&lt;/p&gt;
&lt;p&gt;I used this code to learn functional programming. In that style variables are immutable, which makes the code you present invalid. So, in my scenario, my decision makes sense.&lt;/p&gt;
&lt;p&gt;In a more generic sense, you have to trade off the annoyance of not being able to write the code you present and the annoyance of not catching bugs because you return false instead of throwing. Reasonable people can come up in different places in that debate.&lt;/p&gt;
</description></item><item><title>Tuples vs. Dictionaries</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8457166</link><pubDate>Sun, 04 May 2008 04:56:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8457166</guid><dc:creator>John Mertus</dc:creator><description>&lt;p&gt;Why not just return a dictionary from the function. &amp;nbsp;The key of the dictionary are the names of the elements of the class, the value objects. &amp;nbsp;For example&lt;/p&gt;
&lt;p&gt; &amp;nbsp;var Person = GetPerson(&amp;lt;some id&amp;gt;);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;int age = Person[&amp;quot;age&amp;quot;]).ToInt32()&lt;/p&gt;
&lt;p&gt; &amp;nbsp;string name = Person[&amp;quot;FirstName&amp;quot;].ToString();&lt;/p&gt;
&lt;p&gt;(Here .ToInt32 is the damn extension C# should have for objects, why the hell doesn't it)&lt;/p&gt;
&lt;p&gt;Of course &amp;nbsp; &lt;/p&gt;
&lt;p&gt; &amp;nbsp;The big problem is the data binding becomes a var in the java sense; that it is like a late binding and fails at runtime not compile time. &amp;nbsp; But it gives a better syntax and is more readable than tuples.&lt;/p&gt;
</description></item><item><title>re: A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8458850</link><pubDate>Mon, 05 May 2008 01:47:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8458850</guid><dc:creator>David Nelson</dc:creator><description>&lt;p&gt;@John&lt;/p&gt;
&lt;p&gt;&amp;quot;Here .ToInt32 is the damn extension C# should have for objects, why the hell doesn't it&amp;quot;&lt;/p&gt;
&lt;p&gt;Because the vast majority of types cannot be reasonably represented by an Int32. Presumably if such a ToInt32 method existed, these types would all have to throw an exception. Why would you want to add a parsing method to every single object which will fail most of the time?&lt;/p&gt;
</description></item><item><title>The Quest for Quick-and-Easy Immutable Value Objects in C#</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8572140</link><pubDate>Tue, 03 Jun 2008 23:59:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8572140</guid><dc:creator>adamjcooper.com/blog</dc:creator><description>&lt;p&gt;The Quest for Quick-and-Easy Immutable Value Objects in C#&lt;/p&gt;
</description></item><item><title>A C# library to write functional code - Part V - The Match operator</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx#8732830</link><pubDate>Tue, 15 Jul 2008 12:46:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8732830</guid><dc:creator>Luca Bolognese's WebLog</dc:creator><description>&lt;p&gt;Other posts in the series: Part I - Background Part II - Tuples Part III - Records Part IV - Type Unions&lt;/p&gt;
</description></item></channel></rss>