Alice, Bob, and Mallory: The Thrush combinator in C#metasyntacticstag:alicebobandmallory.com,2005:TypoTypo2011-03-09T13:13:30+01:00Jonas Elfströmurn:uuid:b02ff8f0-44fb-44ca-a309-eb0fd074a4952009-10-06T20:35:00+02:002011-03-09T13:13:30+01:00The Thrush combinator in C#<p>Last year I read <a href="http://github.com/raganwald/homoiconic/blob/master/README.markdown">Reg "Raganwald'" Braithwaite's</a> excellent post <a href="http://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown#readme">The Thrush</a> and he explains it as </p>
<blockquote>
<p>The thrush is written Txy = yx. It reverses evaluation.</p>
</blockquote>
<p>Back then I didn't even consider trying to implement it in C#. That was before I digged deeper into <a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx">lambda expressions</a> and <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx">extension methods</a> in C# 3.0 and way before last night when I read Debasish Ghosh's post on how to <a href="http://debasishg.blogspot.com/2009/09/thrush-combinator-in-scala.html">implement the Thrush in Scala</a>. After reading that my first thought was if it was possible to do the same in C#. Here's my attempt.</p>
<p>At first I struggled with the static typing and headed for an easy way out using Object in the extension method of Object:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> object Into(this Object obj,
Func<object, object> f)
{ <span style="color:#080;font-weight:bold">return</span> f.Invoke(obj); }</pre></td>
</tr></table>
<p><br>
My goal was to translate the Ruby example</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>(<span style="color:#00D">1</span>..<span style="color:#00D">100</span>).select(&<span style="color:#A60">:odd?</span>).inject(&<span style="color:#A60">:+</span>).into { |x| x * x }</pre></td>
</tr></table>
<p><br>
in Raganwald's post to C#.</p>
<blockquote>
<p>Which reads "Take the numbers from 1 to 100, keep the odd ones, take the sum of those, and then answer the square of that number."</p>
</blockquote>
<p>But with the Object based extension method I had to do some ugly casts.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var r = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Where(x => Odd(x)).Sum().Into(x => (<span style="color:#0a5;font-weight:bold">int</span>)x * (<span style="color:#0a5;font-weight:bold">int</span>)x);</pre></td>
</tr></table>
<p><br>
With som added typing I could do: </p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var result = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Where(x => Odd(x)).Sum().Into(x => x * x);</pre></td>
</tr></table>
<p><br>
That merely moved the cast to the extension method and also made it work for integers only.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> <span style="color:#0a5;font-weight:bold">int</span> Into(this Object obj, Func<<span style="color:#0a5;font-weight:bold">int</span>, <span style="color:#0a5;font-weight:bold">int</span>> f)
{ <span style="color:#080;font-weight:bold">return</span> f.Invoke((<span style="color:#0a5;font-weight:bold">int</span>)obj); }</pre></td>
</tr></table>
<p><br>
Then I remembered generics and method type inference which finally led to a decent Thrush combinator in C#.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> T Into<T>(this T obj, Func<T, T> f)
{ <span style="color:#080;font-weight:bold">return</span> f(obj); }</pre></td>
</tr></table>
<p><br>
The casts are gone and it's also, as far as I can see, as flexible as the one in Ruby.<br><br>
Contrived example follows:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>var test = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">ball</span><span style="color:#710">"</span></span>;
var ball = test.Into(s => <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Are we having a </span><span style="color:#710">"</span></span> + s + <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20"> yet?</span><span style="color:#710">"</span></span>);</pre></td>
</tr></table>
<p><br>
<strong>The odd part</strong></p>
<p>The <em>Odd(x)</em> method call in the calculation above is a plain static method.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>private <span style="color:#088;font-weight:bold">static</span> <span style="color:#0a5;font-weight:bold">bool</span> Odd(<span style="color:#0a5;font-weight:bold">int</span> n)
{ <span style="color:#080;font-weight:bold">return</span> (n % <span style="color:#00D">2</span> != <span style="color:#00D">0</span>); }</pre></td>
</tr></table>
<p><br>
If you want an even more terse syntax you could try an ext. method on IEnumerable like this:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> IEnumerable<<span style="color:#0a5;font-weight:bold">int</span>> Odd(this IEnumerable<<span style="color:#0a5;font-weight:bold">int</span>> en)
{ <span style="color:#080;font-weight:bold">return</span> en.Where(n => n % <span style="color:#00D">2</span> != <span style="color:#00D">0</span>); }</pre></td>
</tr></table>
<p><br>
Gives:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var result = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Odd().Sum().Into(x => x * x);</pre></td>
</tr></table>
<p><br>
<!--Also as a general alternative to <code>.Sum()</code> I could have used <code>.Aggregate((x, y) => x + y))</code> but I found it a bit verbose.-->
In C# I don't think it's possible to pull off the Symbol#to_proc stuff that Ruby does. That's the <em>&:</em> in the <em>select(&:odd?)</em> and the <em>inject(&:+)</em> in the Ruby example. Raganwald has a great <a href="http://weblog.raganwald.com/2007/11/fun-with-symboltoproc.html">post</a> on that too.</p>
<p><font style="color:red;font-weight:bold">Edit</font></p>
<p>Check out <a href="http://stackoverflow.com/questions/1528319/operators-as-method-parameters-in-c-and-the-thrush-combinator">Jon Skeet's nice answer</a> on StackOverflow to my question on how to make this even more Ruby-like. I have to try out that Operator class later though.</p>
<p><font style="color:red;font-weight:bold">Edit 2009-10-07</font></p>
<p>One thing I found a bit surprising is that by implementing the Into ext. method in this way it not only works for all objects based on <code>System.Object</code> but it also works for <a href="http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx">value types</a>.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
</pre></td>
<td class="code"><pre><span style="color:#0a5;font-weight:bold">int</span> n=<span style="color:#00D">4711</span>;
<span style="color:#0a5;font-weight:bold">int</span> oddOrZero = n.Into(x => x % <span style="color:#00D">2</span> !=<span style="color:#00D">0</span> ? x : <span style="color:#00D">0</span>); <span style="color:#777">// 4711</span>
n = <span style="color:#00D">4712</span>;
oddOrZero = n.Into(x => x % <span style="color:#00D">2</span> != <span style="color:#00D">0</span> ? x : <span style="color:#00D">0</span>); <span style="color:#777">// 0</span></pre></td>
</tr></table>
<p><br>
<font style="color:red;font-weight:bold">Edit 2009-10-12</font></p>
<p>My confusion did stem from my lack of understanding of <a href="http://msdn.microsoft.com/en-us/library/bb383977(loband).aspx">extension methods</a>. Ex. methods are in fact not extending <code>System.Object</code> or any other type, they are "<a href="http://blogs.msdn.com/ericlippert/about.aspx">nothing more than a pleasant syntax for calling a static method</a>" in case no instance method with the same name can be found.</p><p>Last year I read <a href="http://github.com/raganwald/homoiconic/blob/master/README.markdown">Reg "Raganwald'" Braithwaite's</a> excellent post <a href="http://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown#readme">The Thrush</a> and he explains it as </p>
<blockquote>
<p>The thrush is written Txy = yx. It reverses evaluation.</p>
</blockquote>
<p>Back then I didn't even consider trying to implement it in C#. That was before I digged deeper into <a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx">lambda expressions</a> and <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx">extension methods</a> in C# 3.0 and way before last night when I read Debasish Ghosh's post on how to <a href="http://debasishg.blogspot.com/2009/09/thrush-combinator-in-scala.html">implement the Thrush in Scala</a>. After reading that my first thought was if it was possible to do the same in C#. Here's my attempt.</p>
<p>At first I struggled with the static typing and headed for an easy way out using Object in the extension method of Object:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> object Into(this Object obj,
Func<object, object> f)
{ <span style="color:#080;font-weight:bold">return</span> f.Invoke(obj); }</pre></td>
</tr></table>
<p><br>
My goal was to translate the Ruby example</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>(<span style="color:#00D">1</span>..<span style="color:#00D">100</span>).select(&<span style="color:#A60">:odd?</span>).inject(&<span style="color:#A60">:+</span>).into { |x| x * x }</pre></td>
</tr></table>
<p><br>
in Raganwald's post to C#.</p>
<blockquote>
<p>Which reads "Take the numbers from 1 to 100, keep the odd ones, take the sum of those, and then answer the square of that number."</p>
</blockquote>
<p>But with the Object based extension method I had to do some ugly casts.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var r = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Where(x => Odd(x)).Sum().Into(x => (<span style="color:#0a5;font-weight:bold">int</span>)x * (<span style="color:#0a5;font-weight:bold">int</span>)x);</pre></td>
</tr></table>
<p><br>
With som added typing I could do: </p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var result = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Where(x => Odd(x)).Sum().Into(x => x * x);</pre></td>
</tr></table>
<p><br>
That merely moved the cast to the extension method and also made it work for integers only.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> <span style="color:#0a5;font-weight:bold">int</span> Into(this Object obj, Func<<span style="color:#0a5;font-weight:bold">int</span>, <span style="color:#0a5;font-weight:bold">int</span>> f)
{ <span style="color:#080;font-weight:bold">return</span> f.Invoke((<span style="color:#0a5;font-weight:bold">int</span>)obj); }</pre></td>
</tr></table>
<p><br>
Then I remembered generics and method type inference which finally led to a decent Thrush combinator in C#.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> T Into<T>(this T obj, Func<T, T> f)
{ <span style="color:#080;font-weight:bold">return</span> f(obj); }</pre></td>
</tr></table>
<p><br>
The casts are gone and it's also, as far as I can see, as flexible as the one in Ruby.<br><br>
Contrived example follows:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>var test = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">ball</span><span style="color:#710">"</span></span>;
var ball = test.Into(s => <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">Are we having a </span><span style="color:#710">"</span></span> + s + <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20"> yet?</span><span style="color:#710">"</span></span>);</pre></td>
</tr></table>
<p><br>
<strong>The odd part</strong></p>
<p>The <em>Odd(x)</em> method call in the calculation above is a plain static method.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>private <span style="color:#088;font-weight:bold">static</span> <span style="color:#0a5;font-weight:bold">bool</span> Odd(<span style="color:#0a5;font-weight:bold">int</span> n)
{ <span style="color:#080;font-weight:bold">return</span> (n % <span style="color:#00D">2</span> != <span style="color:#00D">0</span>); }</pre></td>
</tr></table>
<p><br>
If you want an even more terse syntax you could try an ext. method on IEnumerable like this:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
</pre></td>
<td class="code"><pre>public <span style="color:#088;font-weight:bold">static</span> IEnumerable<<span style="color:#0a5;font-weight:bold">int</span>> Odd(this IEnumerable<<span style="color:#0a5;font-weight:bold">int</span>> en)
{ <span style="color:#080;font-weight:bold">return</span> en.Where(n => n % <span style="color:#00D">2</span> != <span style="color:#00D">0</span>); }</pre></td>
</tr></table>
<p><br>
Gives:</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>
</pre></td>
<td class="code"><pre>var result = Enumerable.Range(<span style="color:#00D">1</span>, <span style="color:#00D">100</span>).Odd().Sum().Into(x => x * x);</pre></td>
</tr></table>
<p><br>
<!--Also as a general alternative to <code>.Sum()</code> I could have used <code>.Aggregate((x, y) => x + y))</code> but I found it a bit verbose.-->
In C# I don't think it's possible to pull off the Symbol#to_proc stuff that Ruby does. That's the <em>&:</em> in the <em>select(&:odd?)</em> and the <em>inject(&:+)</em> in the Ruby example. Raganwald has a great <a href="http://weblog.raganwald.com/2007/11/fun-with-symboltoproc.html">post</a> on that too.</p>
<p><font style="color:red;font-weight:bold">Edit</font></p>
<p>Check out <a href="http://stackoverflow.com/questions/1528319/operators-as-method-parameters-in-c-and-the-thrush-combinator">Jon Skeet's nice answer</a> on StackOverflow to my question on how to make this even more Ruby-like. I have to try out that Operator class later though.</p>
<p><font style="color:red;font-weight:bold">Edit 2009-10-07</font></p>
<p>One thing I found a bit surprising is that by implementing the Into ext. method in this way it not only works for all objects based on <code>System.Object</code> but it also works for <a href="http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx">value types</a>.</p>
<table class="CodeRay"><tr>
<td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><a href="#n1" name="n1">1</a>
<a href="#n2" name="n2">2</a>
<a href="#n3" name="n3">3</a>
<a href="#n4" name="n4">4</a>
</pre></td>
<td class="code"><pre><span style="color:#0a5;font-weight:bold">int</span> n=<span style="color:#00D">4711</span>;
<span style="color:#0a5;font-weight:bold">int</span> oddOrZero = n.Into(x => x % <span style="color:#00D">2</span> !=<span style="color:#00D">0</span> ? x : <span style="color:#00D">0</span>); <span style="color:#777">// 4711</span>
n = <span style="color:#00D">4712</span>;
oddOrZero = n.Into(x => x % <span style="color:#00D">2</span> != <span style="color:#00D">0</span> ? x : <span style="color:#00D">0</span>); <span style="color:#777">// 0</span></pre></td>
</tr></table>
<p><br>
<font style="color:red;font-weight:bold">Edit 2009-10-12</font></p>
<p>My confusion did stem from my lack of understanding of <a href="http://msdn.microsoft.com/en-us/library/bb383977(loband).aspx">extension methods</a>. Ex. methods are in fact not extending <code>System.Object</code> or any other type, they are "<a href="http://blogs.msdn.com/ericlippert/about.aspx">nothing more than a pleasant syntax for calling a static method</a>" in case no instance method with the same name can be found.</p>Reginald Braithwaiteurn:uuid:4c174538-229a-47b1-9f05-b7a856d9deb82009-10-07T00:52:31+02:002009-10-07T08:06:59+02:00Comment on The Thrush combinator in C# by Reginald Braithwaite<p>Great post!</p>