

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rodrigo Kumpera Weblog &#187; mono</title>
	<atom:link href="http://www.kumpera.net/blog/index.php/tag/mono/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kumpera.net/blog</link>
	<description>Meus achados sobre tecnologia</description>
	<lastBuildDate>Thu, 14 Jul 2011 15:45:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Implementando Haskell em VMs tradicionais (parte 2)</title>
		<link>http://www.kumpera.net/blog/index.php/2010/01/09/implementando-haskell-em-vms-tradicionais-parte-2/</link>
		<comments>http://www.kumpera.net/blog/index.php/2010/01/09/implementando-haskell-em-vms-tradicionais-parte-2/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 23:30:36 +0000</pubDate>
		<dc:creator>kumpera</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Programming language Theory]]></category>
		<category><![CDATA[language design]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://www.kumpera.net/blog/?p=149</guid>
		<description><![CDATA[Retomando a questão sobre como implementar Haskell em VMs tradicionais, vamos ver um dos aspectos mais complicados, thunking, de implementar de forma eficiente. Um dos aspectos que surpreende a maioria dos que usam Haskell pela primeira vez é o fato da linguagem ser lazy evaluated, isto é, o valor de uma expressão só é computado [...]]]></description>
			<content:encoded><![CDATA[<p>Retomando a questão sobre <a href="http://www.kumpera.net/blog/index.php/2009/09/10/implementando-haskell-em-vms-tradicionais-parte-1/">como implementar Haskell em VMs tradicionais</a>, vamos ver um dos aspectos mais complicados, thunking, de implementar de forma eficiente. Um dos aspectos que surpreende a maioria dos que usam Haskell pela primeira vez é o fato da linguagem ser lazy evaluated, isto é, o valor de uma expressão só é computado quando for usado, mesmo entre chamadas funções. Vejamos um exemplo simples:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">square a <span style="color: #339933; font-weight: bold;">=</span> a <span style="color: #339933; font-weight: bold;">*</span> a
&nbsp;
square<span style="color: #339933; font-weight: bold;">_</span>of<span style="color: #339933; font-weight: bold;">_</span>sum a b <span style="color: #339933; font-weight: bold;">=</span> square <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">+</span> b<span style="color: green;">&#41;</span></pre></div></div>

<p>Nesse exemplo, quando square_of_sum chama square, o parâmetro passado não é o resultado de a + b, mas sim algo próximo a uma closure que irá calcular a + b. Quando square for avaliada, ela precisará do valor de &#8216;a&#8217;, então usará a closure que recebeu como parâmetro para tal. Ou melhor, funciona quase assim, Haskell implementa um mecanismo chamado call-by-need, que resolve o valor uma única vez na primeira vez que for necessário memorizando o resultado. Isso significa que no caso de square &#8216;a&#8217; será avaliada uma única vez. Por conta da memorização, não usamos o termo closure, mais sim thunk para descrever o que uma função passa para outra.</p>
<p>Outro detalhe importante, chamadas de função também são lazy evaluated, então tanto square, quanto square_of_sum na verdade retornam thunks para os valores em questão. Essa coisa toda pode parecer extremamente ineficiente a primeira vista e de fato é. Tanto que o GHC gera código sem uso de thunk sempre que conseguir provar que um pedaço de código pode ser strict evaluated [1].</p>
<p>Antes de imaginar como implementar isso em uma VM como a CLR, vamos traduzir nosso exemplo para C# [2]:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">&nbsp;
<span style="color: #FF0000;">class</span> Thunk<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
	T value<span style="color: #008000;">;</span>
	Func<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> closure<span style="color: #008000;">;</span>
	<span style="color: #FF0000;">bool</span> resolved<span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> Thunk <span style="color: #000000;">&#40;</span>Func<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> closure<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">closure</span> <span style="color: #008000;">=</span> closure<span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> T Value <span style="color: #000000;">&#123;</span>
		get <span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>resolved<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
				value <span style="color: #008000;">=</span> closure <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
				resolved <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span>
				closure <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0600FF;">return</span> value<span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> square <span style="color: #000000;">&#40;</span>Thunk <span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> a<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #008000;">new</span> Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> a.<span style="color: #0000FF;">Value</span> <span style="color: #008000;">*</span> a.<span style="color: #0000FF;">Value</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> square_of_sum <span style="color: #000000;">&#40;</span>Thunk <span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> a, Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> a_plus_b <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> a.<span style="color: #0000FF;">Value</span> <span style="color: #008000;">+</span> b.<span style="color: #0000FF;">Value</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #0600FF;">return</span> square <span style="color: #000000;">&#40;</span>a_plus_b<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//Já que square produz um thunk, não precisamos criar outro.</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Bem confuso, de certo. Primeiro a implementação de Thunk, simples e direta, já square_of_sum precisa de uma variável local para ficar minimamente legível. Uma coisa é fato, C# não foi feita para ser usada com lazy evaluation.</p>
<p>Existe alguns problema quanto a eficiencia de fazer dessa forma. O maior deles é como lidar quando alguns valores já estão resolvidos e temos ainda assim criar um thunk para satisfazer o função chamada. A forma como GHC lida isso é passando todos parâmetros boxed de forma que é possível misturar thunks e valores sem problema. A função square, do nosso exemplo anterior ficaria assim:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">&nbsp;
Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> square <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> a<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #008000;">new</span> Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #FF0000;">int</span> val<span style="color: #008000;">;</span>
		<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>a <span style="color: #008000;">is</span> <span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>
			val <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span><span style="color: #000000;">&#41;</span>a<span style="color: #008000;">;</span>
		<span style="color: #0600FF;">else</span>
			val <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span><span style="color: #000000;">&#41;</span>a<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
		<span style="color: #0600FF;">return</span> val <span style="color: #008000;">*</span> val<span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Outra forma de também lidar com esse problema é criar duas versões da mesma função, uma que recebe valores resolvidos e outra apenas thunks. Fazer dessa forma é vantagem quando podemos provar o uso estrito dos valores em questão. Por fim, acho que o maior problema ser achar uma forma de representar um thunk usando o mínimo possível de memória.</p>
<p>No nosso exemplo, em uma plataforma 32bits, Trunk<T> usa 20 bytes, Func<T> usa mais 40 e outros 8 da closure[3]. Ou seja, começa usando 68, coisa pacas. Podemos fazer algumas mudanças nisso. Dado que não existe null em Haskell podemos remover o atributo resolved e simplesmente verificar se closure é ou não null. Segundo, em vez criar 1 delegate toda vez podemos fazer caching dele e armazenar as variáveis capturadas no próprio thunk. Algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">abstract <span style="color: #FF0000;">class</span> Thunk<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">public</span> abstract T Value <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #FF0000;">class</span> ThunkWithVars<span style="color: #008000;">&lt;</span>T,V<span style="color: #008000;">&gt;</span> <span style="color: #008000;">:</span> Thunk<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
	T value<span style="color: #008000;">;</span>
	Func<span style="color: #008000;">&lt;</span>V, T<span style="color: #008000;">&gt;</span> closure<span style="color: #008000;">;</span>
	V vars<span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> ThunkWithVars <span style="color: #000000;">&#40;</span>Func<span style="color: #008000;">&lt;</span>V,T<span style="color: #008000;">&gt;</span> closure, V vars<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">closure</span> <span style="color: #008000;">=</span> closure<span style="color: #008000;">;</span>
		<span style="color: #0600FF;">this</span>.<span style="color: #0000FF;">vars</span> <span style="color: #008000;">=</span> vars<span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> T Value <span style="color: #000000;">&#123;</span>
		get <span style="color: #000000;">&#123;</span>
			<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>closure <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
				value <span style="color: #008000;">=</span> closure <span style="color: #000000;">&#40;</span>vars<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
				closure <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span>
				vars <span style="color: #008000;">=</span> <span style="color: #0600FF;">default</span> <span style="color: #000000;">&#40;</span>V<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
			<span style="color: #000000;">&#125;</span>
			<span style="color: #0600FF;">return</span> value<span style="color: #008000;">;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0600FF;">static</span> Func<span style="color: #008000;">&lt;</span>Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span>, <span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> square_resolve <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>a<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> a.<span style="color: #0000FF;">Value</span> <span style="color: #008000;">*</span> a.<span style="color: #0000FF;">Value</span><span style="color: #008000;">;</span>
&nbsp;
Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> square <span style="color: #000000;">&#40;</span>Thunk <span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> a<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0600FF;">return</span> <span style="color: #008000;">new</span> ThunkWithVars<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span>, Thunk<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;&gt;</span> <span style="color: #000000;">&#40;</span>square_resolve, a<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Usando essa codificação Thunk continua usando 20 bytes porém nos livramos dos demais objetos, um ganho de 70% no final das contas. Poderíamos economizar outros 4 se juntarmos as variáveis closure e value em uma só caso T fosse do tipo referência &#8211; ou manter o resultado boxed. Mesmo sem isso, 20 bytes já é um valor razoável, conseguir o mesmo em uma JVM é basicamente impossível sem muita ginástica.</p>
<p>Qual a performance dessa solução? Segundo o pessoal do GHC, em média 95%-98% dos thunks gerados são resolvidos. Com um generational GC, a maioria vira lixo efêmero. Ou seja, não existe muita razão para uma VM tradicional ser mais lenta que a do GHC, o principal fator nesse caso é, sem dúvida, o compilador, que pode gerar pedaços de código inteiros sem uso de thunk.</p>
<p>[1] É muito comum em Haskell gerar código que não funciona sem lazy evaluation, como geradores de listas infinitas.<br />
[2] Nesse exemplo vou trapacear e tornar as funções mono-mórficas e usar int no lugar de Number para simplificar o código.<br />
[3] Nesse caso estou ignorando quanto de memória as variáveis capturadas usam.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kumpera.net/blog/index.php/2010/01/09/implementando-haskell-em-vms-tradicionais-parte-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implementando Haskell em VMs tradicionais (parte 1)</title>
		<link>http://www.kumpera.net/blog/index.php/2009/09/10/implementando-haskell-em-vms-tradicionais-parte-1/</link>
		<comments>http://www.kumpera.net/blog/index.php/2009/09/10/implementando-haskell-em-vms-tradicionais-parte-1/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 00:49:24 +0000</pubDate>
		<dc:creator>kumpera</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[language design]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[clr]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[jvm]]></category>

		<guid isPermaLink="false">http://www.kumpera.net/blog/?p=138</guid>
		<description><![CDATA[Outro dia uma discussão me levou a pensar se era possível implementar Haskell em cima de uma VM tradicional, tal qual JVM ou CLR, de forma eficiente. Em termos dos mecanismos que a VM precisa suportar de forma eficiente os principais são tail call, thunking, type classes e algebraic types. Nesse artigo vou apenas discutir [...]]]></description>
			<content:encoded><![CDATA[<p>Outro dia uma discussão me levou a pensar se era possível implementar Haskell em cima de uma VM tradicional, tal qual JVM ou CLR, de forma eficiente. Em termos dos mecanismos que a VM precisa suportar de forma eficiente os principais são tail call, thunking, type classes e algebraic types. Nesse artigo vou apenas discutir um deles, type classes.</p>
<p>Uma type class para os acostumados com OO pode ser vista como uma interface cuja implementações são externas aos tipos que estão atrelados. Um exemplo bem simples é Eq, que permite compar objetos do mesmo tipo:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">class</span> <span style="color: #cccc00; font-weight: bold;">Eq</span> a <span style="color: #06c; font-weight: bold;">where</span>
    <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">==</span><span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">/=</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">::</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">Bool</span>
    x <span style="color: #339933; font-weight: bold;">/=</span> y <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">not</span> <span style="color: green;">&#40;</span>x <span style="color: #339933; font-weight: bold;">==</span> y<span style="color: green;">&#41;</span>
    x <span style="color: #339933; font-weight: bold;">==</span> y <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">not</span> <span style="color: green;">&#40;</span>x <span style="color: #339933; font-weight: bold;">/=</span> y<span style="color: green;">&#41;</span></pre></div></div>

<p>Para nos não iniciado em Haskell, linha um define a classe Eq e diz que ela possui um parâmetro polimófico; linha 2 diz que Eq tem 2 funções, &#8220;==&#8221; e &#8220;/=&#8221; cuja assinatura são dois valores do tipo &#8216;a&#8217; e retorna um booleano; por fim, linhas 3 e 4 são implementações padrão das funções. Seria o equivalente, em pseudo-C#, ao seguinte:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">interface</span> Eq<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
   <span style="color: #FF0000;">bool</span> <span style="color: #0600FF;">operator</span><span style="color: #008000;">==</span> <span style="color: #000000;">&#40;</span>T a, T b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> <span style="color: #008000;">!</span><span style="color: #000000;">&#40;</span>a <span style="color: #008000;">!=</span> b<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
   <span style="color: #FF0000;">bool</span> <span style="color: #0600FF;">operator</span><span style="color: #008000;">!=</span> <span style="color: #000000;">&#40;</span>T a, T b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> <span style="color: #008000;">!</span><span style="color: #000000;">&#40;</span>a <span style="color: #008000;">==</span> b<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Uma das vantagens de type classes no Haskell é que elas podem fornecer implementações padrão para alguns de seus métodos. Bom, agora que temos Eq definida, para dizer que Listas a implementa usamos algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">instance</span> <span style="color: #cccc00; font-weight: bold;">Eq</span> a <span style="color: #339933; font-weight: bold;">=&gt;</span> <span style="color: #cccc00; font-weight: bold;">Eq</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #06c; font-weight: bold;">where</span>
    <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">==</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">=</span> True
    <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">==</span> <span style="color: green;">&#40;</span>y:ys<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> x<span style="color: #339933; font-weight: bold;">==</span>y <span style="color: #339933; font-weight: bold;">&amp;&amp;</span> xs<span style="color: #339933; font-weight: bold;">==</span>ys
    <span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">==</span> <span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">=</span> False</pre></div></div>

<p>Aqui vemos uma das melhores características do Haskell é explorada, que é pattern matching &#8211; e isso também é assunto para outro artigo. Como pode se notar, uma implementação de uma dada type class não está embutida na definição do tipo em questão, ou seja, não podemos interfaces como a CLR ou a JVM suportam.</p>
<p>A idéia é representar type classes de forma semelhante a como o ghc faz, usando dictionary passing[1], que é bem simples de entender e implementar. Para cada type class que uma função recebe nos seus parâmetros, passamos junto um objeto que representa as operações em questão. Em C# teríamos:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">interface</span> Eq<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #FF0000;">bool</span> op_eq <span style="color: #000000;">&#40;</span>T a, T b<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #FF0000;">bool</span> op_neq <span style="color: #000000;">&#40;</span>T a, T b<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #FF0000;">class</span> Eq_Int <span style="color: #008000;">:</span> Eq<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> op_eq <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> a, <span style="color: #FF0000;">int</span> b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> a <span style="color: #008000;">==</span> b<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> op_eq <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> a, <span style="color: #FF0000;">int</span> b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> a <span style="color: #008000;">!=</span> b<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #FF0000;">int</span> Fun<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#40;</span>Eq<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> dict, T a, T b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>dict.<span style="color: #0000FF;">op_eq</span> <span style="color: #000000;">&#40;</span>a, b<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Existe alguns problemas aqui, primeiro que estamos passando um parâmetro extra e segundo que não é possível eliminar a verificar por null pointer caso op_eq seja inlined. A solução é razoavelmente simples no caso do C#:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">struct</span> Eq_Int <span style="color: #008000;">:</span> Eq<span style="color: #008000;">&lt;</span><span style="color: #FF0000;">int</span><span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> op_eq <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> a, <span style="color: #FF0000;">int</span> b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> a <span style="color: #008000;">==</span> b<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> op_neq <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">int</span> a, <span style="color: #FF0000;">int</span> b<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> a <span style="color: #008000;">!=</span> b<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #FF0000;">int</span> Fun<span style="color: #008000;">&lt;</span>T, TD<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#40;</span>T a, T b<span style="color: #000000;">&#41;</span> where TD<span style="color: #008000;">:</span> Eq<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #0600FF;">default</span> <span style="color: #000000;">&#40;</span>TD<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">op_eq</span> <span style="color: #000000;">&#40;</span>a, b<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF;">return</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>A grande mudança aqui é tornar a instância da typeclass um valuetype e construir um valor default para satisfazer o compilador. É uma pena que não podemos simplesmente chamar um método estático e TD, o que é uma limitação boba da CLR. Essa solução não é possível na JVM devido a inexistência de valuetypes e generics.</p>
<p>E quanto a performance dessa solução? Bom, no caso do mono, o JIT&#8217;er reconhece as chamadas como não virtuais e é capaz de fazer inline de forma bem agressiva &#8211; exatamente como desejado. Eu pensei em fazer um comparativo dessa solução com o equivalente em Java, mostrando como a CLR permite codificar tipos muito mais ricos e interessantes que a JVM &#8211; e como isso se traduz em performance. Mas realmente não estou afim de criar motivo para um flamewar por parte dos javeiros de plantão.</p>
<p>[1]Esse é o paper original que descreve type classes e a técnica utilizada: http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps.gz</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kumpera.net/blog/index.php/2009/09/10/implementando-haskell-em-vms-tradicionais-parte-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Code swarm: representando visualmente um projeto</title>
		<link>http://www.kumpera.net/blog/index.php/2008/10/02/code-swarm-representando-visualmente-um-projeto/</link>
		<comments>http://www.kumpera.net/blog/index.php/2008/10/02/code-swarm-representando-visualmente-um-projeto/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 17:52:34 +0000</pubDate>
		<dc:creator>kumpera</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[code swarm]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[moonlight]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.kumpera.net/blog/?p=104</guid>
		<description><![CDATA[Como podemos produzir uma representação visual da evolução de um projeto? O pessoal do projeto code swarm tem uma ótima resposta. Um vídeo gerado a partir do histórico de commits do projeto.
O mais legal disso tudo é que o software é de código aberto, então qualquer um pode produzir vídeos também. Resolvi então fazer uma [...]]]></description>
			<content:encoded><![CDATA[<p>Como podemos produzir uma representação visual da evolução de um projeto? O pessoal do projeto <a href="http://code.google.com/p/codeswarm/">code swarm</a> tem uma ótima resposta. Um vídeo gerado a partir do histórico de commits do projeto.</p>
<p>O mais legal disso tudo é que o software é de código aberto, então qualquer um pode produzir vídeos também. Resolvi então fazer uma série deles baseados no mono. Abaixo está o primeiro deles, mostrando o moonlight. Fico devendo o áudio para o próximo.</p>
<p><object width="640" height="480"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1867774&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=1867774&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="480"></embed></object><br /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kumpera.net/blog/index.php/2008/10/02/code-swarm-representando-visualmente-um-projeto/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

