

<?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; C</title>
	<atom:link href="http://www.kumpera.net/blog/index.php/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kumpera.net/blog</link>
	<description>Meus achados sobre tecnologia</description>
	<lastBuildDate>Mon, 30 Aug 2010 12:00:15 +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>Escrevendo um JIT em menos de 40 linhas de C#</title>
		<link>http://www.kumpera.net/blog/index.php/2010/08/30/escrevendo-um-jit-em-menos-de-40-linhas-de-c/</link>
		<comments>http://www.kumpera.net/blog/index.php/2010/08/30/escrevendo-um-jit-em-menos-de-40-linhas-de-c/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 12:00:15 +0000</pubDate>
		<dc:creator>kumpera</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[compilers]]></category>
		<category><![CDATA[jit]]></category>
		<category><![CDATA[x86]]></category>

		<guid isPermaLink="false">http://www.kumpera.net/blog/?p=157</guid>
		<description><![CDATA[O desafio é escrever um programa capaz de gerar o código nativo para uma função &#8220;int foo () { return 10; }&#8221; e executá-lo. Parece impossível, mas não é. E com um pouco de esforço não deve consumir muito tempo também. Para isso vamos precisar saber algumas coisas antes.
Primeiro, é necessário saber um pouco de [...]]]></description>
			<content:encoded><![CDATA[<p>O desafio é escrever um programa capaz de gerar o código nativo para uma função &#8220;int foo () { return 10; }&#8221; e executá-lo. Parece impossível, mas não é. E com um pouco de esforço não deve consumir muito tempo também. Para isso vamos precisar saber algumas coisas antes.</p>
<p>Primeiro, é necessário saber um pouco de assembly e entender como funciona a <a href="http://en.wikipedia.org/wiki/X86_calling_conventions">calling convention</a> de um pc 32bit. Feito isso o próximo passo é baixar os manuais da plataforma, sejam os da Intel ou da AMD. Estou acostumado com os da Intel, inclusive tenho eles em árvore morta.</p>
<p>Depois disso, precisamos aprender a usar a ferramenta mais importante para quem quer se aventurar nessa área, o disassembler. No meu caso, usei o objdump da gnu. Instalei via macports no OSX é o gobjdmp por algum motivo.</p>
<p>São dois comandos essenciais que vamos usar, o primeiro é o &#8220;gobjdump -d&#8221; que disassembla um binário padrão da plataforma, vamos usá-lo para roubar o assembly necessário para nossa função a ser compilada. O segundo é &#8220;gobjdump -D -b binary -m i386&#8243; que desassembla um blog binário não estruturado, essa usamos para fazer dump em arquivos do nosso código gerado e verificar seu o conteúdo.</p>
<p>Feito isso, compilamos o código C da nossa função e o assembly dela é algo como:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="asm" style="font-family:monospace;">&lt;_foo&gt;<span style="color: #339933;">:</span>
    <span style="color: #00007f; font-weight: bold;">push</span>   <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
    <span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #339933;">,%</span><span style="color: #00007f;">ebp</span>
    <span style="color: #00007f; font-weight: bold;">sub</span>    $<span style="color: #0000ff;">0x8</span><span style="color: #339933;">,%</span><span style="color: #00007f;">esp</span>
    <span style="color: #00007f; font-weight: bold;">mov</span>    $<span style="color: #0000ff;">0xa</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
    <span style="color: #00007f; font-weight: bold;">leave</span>  
    <span style="color: #00007f; font-weight: bold;">ret</span></pre></td></tr></table></div>

<p>Curto e simples, entender oque cada instrução faz deixo como exercício ao leitor porém. Para gerar essa seqüência em runtime precisamos saber como encodificar cada instrução e um manual da arquitetura é a melhor forma para tal. Por sorte não é necessário saber de nenhuma das formas avançadas de ModRM.</p>
<p>Mas primeiro precisamos alocar um bloco de memória no qual podemos escrever e executar. No caso de sistemas unix usamos a função mmap que permite mapear um bloco anônimo de memória [1] no processo corrente. Com C# no OSX isso é tão trivial quanto o seguinte[2]:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;">	<span style="color: #000000;">&#91;</span>DllImport <span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;libc&quot;</span>, EntryPoint<span style="color: #008000;">=</span><span style="color: #666666;">&quot;mmap&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">extern</span> IntPtr mmap <span style="color: #000000;">&#40;</span>IntPtr addr, IntPtr len, <span style="color: #FF0000;">int</span> prot, <span style="color: #FF0000;">int</span> flags, <span style="color: #FF0000;">uint</span> off_t<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #FF0000;">int</span> prot <span style="color: #008000;">=</span> 0x1 <span style="color: #008000;">|</span> 0x2 <span style="color: #008000;">|</span> 0x4<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//PROT_READ | PROT_WRITE | PROT_EXEC</span>
	<span style="color: #FF0000;">int</span> flag <span style="color: #008000;">=</span> 0x1000 <span style="color: #008000;">|</span> 0x0002<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//MAP_ANON | MAP_PRIVATE</span>
	var res <span style="color: #008000;">=</span> mmap <span style="color: #000000;">&#40;</span>IntPtr.<span style="color: #0000FF;">Zero</span>, <span style="color: #000000;">&#40;</span>IntPtr<span style="color: #000000;">&#41;</span><span style="color: #FF0000;">4096</span>, prot , flags, <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Para escrever nesse bloco de memória recém alocado usamos UnmanagedMemoryStream que é uma bela mão na roda para esses casos. Por fim, para invocarmos o código usamos outra facilidade do framework, o método </i>Marshal.GetDelegateForFunctionPointer</i>. Quando fiz isso em Java a alguns anos esses 3 passos foram muito mais difíceis.</p>
<p>Enfim, chega de enrolação, o código completo para nosso super JIT é o seguinte:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.CompilerServices</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Runtime.InteropServices</span><span style="color: #008000;">;</span>
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.IO</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">delegate</span> <span style="color: #FF0000;">int</span> NoArgsReturnInt <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
<span style="color: #FF0000;">class</span> Test <span style="color: #000000;">&#123;</span>
	<span style="color: #000000;">&#91;</span>DllImport <span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;libc&quot;</span>, EntryPoint<span style="color: #008000;">=</span><span style="color: #666666;">&quot;mmap&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">extern</span> IntPtr mmap <span style="color: #000000;">&#40;</span>IntPtr addr, IntPtr len, <span style="color: #FF0000;">int</span> prot, <span style="color: #FF0000;">int</span> flags, <span style="color: #FF0000;">uint</span> off_t<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
	<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">unsafe</span> <span style="color: #0600FF;">void</span> Main <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #FF0000;">int</span> prot <span style="color: #008000;">=</span> 0x1 <span style="color: #008000;">|</span> 0x2 <span style="color: #008000;">|</span> 0x4<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//PROT_READ | PROT_WRITE | PROT_EXEC</span>
		<span style="color: #FF0000;">int</span> flag <span style="color: #008000;">=</span> 0x1000 <span style="color: #008000;">|</span> 0x0002<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//MAP_ANON | MAP_PRIVATE</span>
		var res <span style="color: #008000;">=</span> mmap <span style="color: #000000;">&#40;</span>IntPtr.<span style="color: #0000FF;">Zero</span>, <span style="color: #000000;">&#40;</span>IntPtr<span style="color: #000000;">&#41;</span><span style="color: #FF0000;">4096</span>, prot , flags, <span style="color: #FF0000;">0</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		var mem <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> UnmanagedMemoryStream <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #FF0000;">byte</span><span style="color: #008000;">*</span><span style="color: #000000;">&#41;</span>res, <span style="color: #FF0000;">4096</span>, <span style="color: #FF0000;">4096</span>, FileAccess.<span style="color: #0000FF;">ReadWrite</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #008080; font-style: italic;">//push ebp</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x50 <span style="color: #008000;">+</span> 0x05<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #008080; font-style: italic;">//mov esp, ebp</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x89<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0xE5<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #008080; font-style: italic;">//mov 10, eax</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0xB8 <span style="color: #008000;">+</span> 0x00<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x0A<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x00<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x00<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0x00<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #008080; font-style: italic;">//leave</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0xC9<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		<span style="color: #008080; font-style: italic;">//ret</span>
		mem.<span style="color: #0000FF;">WriteByte</span> <span style="color: #000000;">&#40;</span>0xC3<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		NoArgsReturnInt dele <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>NoArgsReturnInt<span style="color: #000000;">&#41;</span>Marshal.<span style="color: #0000FF;">GetDelegateForFunctionPointer</span> <span style="color: #000000;">&#40;</span>res, <span style="color: #008000;">typeof</span> <span style="color: #000000;">&#40;</span>NoArgsReturnInt<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		Console.<span style="color: #0000FF;">WriteLine</span> <span style="color: #000000;">&#40;</span>dele <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>Incrivelmente simples e curto. Tudo bem que não dá nem para chamar de um brinquedo, porém seu propósito é explorar os princípios básicos por traz de um JIT compiler. Um próximo passo para ele seria gerar 1 função que recebe 2 ints e os soma. Ou tornar o código<br />
menos tosco e mais OO.</p>
<p>[1] mmap permite que bloco de memória seja mapeado para um arquivo<br />
[2] Os valores de prot e flag são específicos ao OSX, então talvez não funcionem em outros derivados unix. Esses valores costumam ficar em /usr/include/sys/mman.h</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kumpera.net/blog/index.php/2010/08/30/escrevendo-um-jit-em-menos-de-40-linhas-de-c/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>Ode ao C</title>
		<link>http://www.kumpera.net/blog/index.php/2009/01/12/ode-ao-c/</link>
		<comments>http://www.kumpera.net/blog/index.php/2009/01/12/ode-ao-c/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 02:34:40 +0000</pubDate>
		<dc:creator>kumpera</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[anger management]]></category>
		<category><![CDATA[language design]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[type systems]]></category>

		<guid isPermaLink="false">http://www.kumpera.net/blog/?p=123</guid>
		<description><![CDATA[A parte que mais odeio no C é ser minha melhor opção. Sim, sério, para aquilo que faço hoje em dia, realmente não existe linguagem melhor. E isso de deixa maluco pois se trata de uma linguagem anacrônica, cheia de problemas enormes que aparentemente toda comunidade de PLR esqueceu de tentar resolver.
Para quem já programou [...]]]></description>
			<content:encoded><![CDATA[<p>A parte que mais odeio no C é ser minha melhor opção. Sim, sério, para aquilo que faço hoje em dia, realmente não existe linguagem melhor. E isso de deixa maluco pois se trata de uma linguagem anacrônica, cheia de problemas enormes que aparentemente toda comunidade de PLR esqueceu de tentar resolver.</p>
<p>Para quem já programou em C, ou mesmo C++, e em uma linguagem de alto nível tais quais C#, Haskell ou LISP sabe o tamanho do sofrimento que é trabalhar com uma ferramenta tão primitiva. Aos incautos não estou me referindo nem me referindo as vantagens óbvias dessas linguagens como gerenciamento automático de lixo, um sistema de tipos rico ou tipagem ou dinâmica[1].</p>
<p>Quando se programa próximo do metal ter um controle e visão muito clara daquilo que é gerado é muito importante, então coisas como verificações inseridas pelo compilador, não ter controle fino sobre a representação dos dados ou simplesmente não podem burlar o sistema de tipos inviabilizam o uso de uma linguagem &#8211; por mais estranho que pareça.</p>
<p>Entretanto usar destes argumentos para defender as relíquias que são C e C++ é temerário. Ambas linguagens foram construídas sob as bases do que era avançado em termos de compiladores nos anos 70 e para a capacidade de processamos do começo dos anos 90. Muita coisa mudou de lá para cá, menos o fato de C++ demorar horrores para compilar.</p>
<p>A primeira grande falha do C, e uma que chama muito a atenção, é o sistema de módulos e compilação separada. Que realmente não existe. Em ambas as linguagens se usa inclusão textual de cabeçalhos com declarações supostamente exportadas por outros módulos do sistema e pronto. O problema disso é óbvio se já tiver trabalhado em projetos grandes. O tempo de compilação individual aumenta sem razão aparente, conflitos com o nome de símbolos ocorrem e, em geral, atrapalham a vida de todos.</p>
<p>Continuando com a questão de processamento de texto. Macros em C provavelmente são o recurso mais importante da linguagem, aquele que a tira da lista de inúteis. É bem freqüente encontrar uma infinidade de truques feitos usando macros para sanar a falta de expressividade da linguagem. Porém tão comum quanto é encontrar gente frustada com a dificuldade de depurar um sistema rico em macros. Ao mesmo tempo, programando um dia com LISP qualquer um enxerga que um grande sistema de macros faz qualquer linguagem medíocre ir muito longe.</p>
<p>Por fim, minha última reclamação é devido ao fato de estar em 2009 e ainda ser obrigado a usar uma linguagem sem inferência de tipos. O artigo do Robin Milner tem quase 31 anos e ainda assim sou obrigado a pagear o compilador com aquilo que ele consegue descobrir sozinho. Inferência de tipos é um recurso ainda mais importante quando falamos de sistemas de tipos mais ricos.</p>
<p>Ainda assim, por algum motivo que me escapa, não existe um substituto usável para C ou C++. Talvez seja pelo fato de tal linguagem não possuir muito acadêmico em termos de papers e PHDs, ou que a enorme parte da comunidade de programadores destas linguagens é cega por achar que são o último biscoito do pacote.</p>
<p>[1]Ou latente, caso tenha um fetiche pelo Fowler.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kumpera.net/blog/index.php/2009/01/12/ode-ao-c/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
