<?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>CØdeZØne! &#187; concorrência</title>
	<atom:link href="http://leandrosilva.com.br/category/concorrencia/feed/" rel="self" type="application/rss+xml" />
	<link>http://leandrosilva.com.br</link>
	<description>Coisas sobre desenvolvimento de software</description>
	<lastBuildDate>Mon, 23 Aug 2010 13:04:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Entendendo um tiquinho de self()</title>
		<link>http://leandrosilva.com.br/2009/09/26/entendendo-um-tiquinho-de-self/</link>
		<comments>http://leandrosilva.com.br/2009/09/26/entendendo-um-tiquinho-de-self/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 22:37:31 +0000</pubDate>
		<dc:creator>Leandro Silva</dc:creator>
				<category><![CDATA[concorrência]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[programação funcional]]></category>

		<guid isPermaLink="false">http://leandrosilva.com.br/?p=457</guid>
		<description><![CDATA[Uma confusão bem comum quando se começa a escrever programas concorrentes em Erlang é quanto ao uso da BIF (built-in function) self(). Mais especificamente, quanto ao seu retorno. A BIF self() é analoga ao this do Java, por exemplo, que é capaz de responder quem é o objeto contenedor do método atualmente em execução. Semelhantemente, [...]]]></description>
			<content:encoded><![CDATA[<p>Uma confusão bem comum quando se começa a escrever programas concorrentes em Erlang é quanto ao uso da <em>BIF</em> (built-in function) <strong><code>self()</code></strong>. Mais especificamente, quanto ao seu retorno.</p>
<p>A <em>BIF</em> <strong><code>self()</code></strong> é analoga ao <strong><code>this</code></strong> do Java, por exemplo, que é capaz de responder quem é o objeto contenedor do método atualmente em execução. Semelhantemente, em Erlang, <strong><code>self()</code></strong> é capaz de dizer quem é o processo contenedor da função atualmente em <span style="text-decoration: line-through;">execução</span> avaliação. Assim, se você chamar <strong><code>self()</code></strong> no Erlang shell, você vai receber como retorno o <strong><code>Pid</code></strong> (identificador de processo) do próprio Erlang shell.</p>
<p>Faça um teste no seu Erlang shell:</p>
<pre class="brush: bash;">
1&gt; self().
</pre>
<p>Você deve ter recebido algo semelhante a <strong><code>&lt;0.31.0&gt;</code></strong> com retorno. Isto porque o Erlang shell nada mais é do que um processo Erlang com um comportamento <a href="http://en.wikipedia.org/wiki/Read-eval-print_loop" target="_blank">REPL</a>.</p>
<p>Ok. Agora, o que acontece se você tiver um programa com um único módulo em que há duas funções que trocam mensagens entre dois processos? Qual seria o retorno de <strong><code>self()</code></strong> nestas duas funções?</p>
<h3>Um pequeno exemplo</h3>
<p><em> </em>Vejamos um exemplo bem simples deste caso extraído do livro <a href="http://www.amazon.com/gp/product/0596518188/ref=pd_lpo_k2_dp_sr_1?pf_rd_p=486539851&amp;pf_rd_s=lpo-top-stripe-1&amp;pf_rd_t=201&amp;pf_rd_i=193435600X&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_r=05FTR2BVN92ZF31Y1408" target="_blank">Erlang Programming</a>:</p>
<pre class="brush: java;">
-module(add_two).
-export([start/0, request/1, loop/0]).

start() -&gt;
  process_flag(trap_exit, true),
  Pid = spawn_link(add_two, loop, []),
  register(add_two, Pid),
  {ok, Pid}.

request(Int) -&gt;
  add_two ! {request, self(), Int},
  receive
    {result, Result}       -&gt; Result;
    {'EXIT', _Pid, Reason} -&gt; {error, Reason}
    after 1000             -&gt; timeout
  end.

loop() -&gt;
  receive
    {request, Pid, Msg} -&gt;
       Pid ! {result, Msg + 2}
  end,
  loop().
</pre>
<p>De maneira bem objetiva, o que este código faz é o seguinte:</p>
<p>1- Quando um <em>processo já existente</em> <em>&#8211; que no nosso caso será o próprio Erlang shell &#8211;</em> faz uma chamada à função <strong><code>start()</code></strong>, um <em>novo processo</em> é gerado, tendo como ponto de partida a função <strong><code>loop()</code></strong>, o seu identificador é associado à variável <strong><code>Pid</code></strong> e, por fim, ele recebe o apelido <strong><code>add_two</code></strong>.</p>
<p>2- Todas as vezes que a função <strong><code>request(Int)</code></strong> é chamada, uma mensagem é enviada para o processo <strong><code>add_two</code></strong>, para que este some 2 ao número passado como parâmetro e envie o resultado de volta ao processo solicitante.</p>
<p>3- Sempre que o processo <strong><code>add_two</code></strong> recebe uma nova mensagem, esta é capturada na sentença <strong><code>receive ... end</code></strong> da função <strong><code>loop()</code></strong>, que verifica se é um &#8220;pedido de soma&#8221;, e então, envia o resultado da soma ao processo solicitante, identificado por <strong><code>Pid</code></strong>.</p>
<h3>A confusão</h3>
<p>Bem simples mesmo, certo? Então, por que acontece a tal confusão?</p>
<p>A confusão acontece, porque o retorno de <strong><code>self()</code></strong> não é o mesmo em todas as funções deste módulo. Isto porque a função <strong><code>loop()</code></strong>, apesar de estar contida no mesmo módulo que as funções <strong><code>start()</code></strong> e <strong><code>request(Int)</code></strong>, não está <span style="text-decoration: line-through;">rodando</span> sendo avaliada no mesmo processo que elas estão. A função <strong><code>loop()</code></strong> está sendo avaliada no processo <strong><code>add_two</code></strong>, enquanto que <strong><code>start()</code></strong> e <strong><code>request()</code></strong> estão sendo avaliadas no primeiro processo <em>&#8211; o Erlang shell</em>. Assim, <strong><code>self()</code></strong> em <strong><code>loop()</code></strong> retorna um identificador de processo diferente do que retornaria as demais funções.</p>
<p>Quer tirar a prova?</p>
<h3>Mais um simples exemplo, só que desta vez, esclarecedor!</h3>
<p>Eu adicionei um bocado de &#8220;prints&#8221; no código que apresentei anteriormente e se você executá-lo agora, terá a prova do que foi discutido. <em>(Tá tudo bem, você não precisa de uma prova a estas alturas do campeonato, mas vai ser divertido.)</em></p>
<pre class="brush: java;">
-module(add_two).
-export([start/0, request/1, loop/0]).

start() -&gt;
io:format(&quot;: start -&gt; self() = ~w~n&quot;, [self()]),
  process_flag(trap_exit, true),
  Pid = spawn_link(add_two, loop, []),
  io:format(&quot;: start -&gt; Pid  = ~w~n&quot;, [Pid]),
  register(add_two, Pid),
  {ok, Pid}.

request(Int) -&gt;
  io:format(&quot;: request -&gt; self() = ~w~n&quot;, [self()]),
  add_two ! {request, self(), Int},
  receive
    {result, Result}       -&gt; Result;
    {'EXIT', _Pid, Reason} -&gt; {error, Reason}
    after 1000             -&gt; timeout
  end.

loop() -&gt;
  receive
    {request, Pid, Msg} -&gt;
       io:format(&quot;: loop/receive -&gt; self() = ~w~n&quot;, [self()]),
       io:format(&quot;: loop/receive -&gt; Pid    = ~w~n&quot;, [Pid]),
       Pid ! {result, Msg + 2}
  end,
  loop().
</pre>
<p>Após fazer a devida compilação, faz o seguinte teste no Erlang shell:</p>
<p>1- Veja o identificador de processo <em>(aka Pid)</em> do Erlang shell:</p>
<pre class="brush: bash;">
1&gt; self().
</pre>
<p>2- Inicie o processo <strong><code>add_two</code></strong>:</p>
<pre class="brush: bash;">
2&gt; add_two:start().
</pre>
<p>3- Chame a função <strong><code>request(Int)</code></strong>:</p>
<pre class="brush: bash;">
3&gt; add_two:request(10).
</pre>
<p>Executou? Comparou os <em>Pids</em>? Viu a diferença de escopo entre as três funções? Pois muito bem, então fica aqui a lição:</p>
<p><em>&#8220;Módulos servem para agrupar funções com um mesmo escopo conceitual, mas nem sempre com o mesmo escopo de processo&#8221;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://leandrosilva.com.br/2009/09/26/entendendo-um-tiquinho-de-self/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Você deveria considerar Erlang para seu próximo grande projeto</title>
		<link>http://leandrosilva.com.br/2009/09/08/voce-deveria-considerar-erlang-para-seu-proximo-grande-projeto/</link>
		<comments>http://leandrosilva.com.br/2009/09/08/voce-deveria-considerar-erlang-para-seu-proximo-grande-projeto/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 02:49:44 +0000</pubDate>
		<dc:creator>Leandro Silva</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[concorrência]]></category>
		<category><![CDATA[engenharia]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[pragmatismo]]></category>
		<category><![CDATA[programação funcional]]></category>

		<guid isPermaLink="false">http://leandrosilva.com.br/?p=433</guid>
		<description><![CDATA[Ao ler o título deste post, talvez você esteja se perguntando: por que eu deveria considerar Erlang para meu próximo grande projeto? Bem, meu objetivo com este post é te apresentar alguns importantes motivos para fazer isto. Erlang nasceu no laboratório de ciência da computação da Ericsson na década de 1980, influenciada por linguagens como [...]]]></description>
			<content:encoded><![CDATA[<p>Ao ler o título deste post, talvez você esteja se perguntando: <em>por que eu deveria considerar </em><a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)" target="_blank"><em>Erlang</em></a><em> para meu próximo grande projeto?</em> Bem, meu objetivo com este post é te apresentar alguns importantes motivos para fazer isto.</p>
<p><img class="aligncenter" src="http://erlang.org/images/erlang.gif" alt="" width="114" height="96" /></p>
<p>Erlang nasceu no laboratório de ciência da computação da Ericsson na década de 1980, influenciada por linguagens como ML, Ada, Module, Prolog e Smalltalk, quando um time de três cientistas <em>&#8211; entre eles, o grande <a href="http://armstrongonsoftware.blogspot.com/" target="_blank">Joe Armstrong</a> &#8211;</em> receberam a missão de descobrir qual seria a melhor linguagem de programação para escrever a próxima geração de sistemas de telecom. Após dois anos de investigação e prototipação, estes cientistas descobriram que nenhuma linguagem era completa o bastante para tal objetivo e, conclusivamente, decidiram criar uma nova linguagem. Nasceu então Erlang, <em>the Ericsson Language</em>.</p>
<p>De lá pra cá, Erlang tem sido evoluida e usada para escrever grandes sistemas críticos, porque é exatamente nesse cenário que Erlang faz mais sentido. Se seu projeto é construir um sistema crítico, altamente tolerante a falhas, com disponibilidade 24&#215;7 e veloz como o papa-léguas, sim, Erlang é para você. Mas se não é bem esta sua necessidade, se você quer apenas construir um pequeno sistema, com baixa concorrência, poucos usuários, pouca necessidade de performance e possibilidade de passar horas <em>down</em> em manutenção, não, você não precisa de Erlang. <span style="text-decoration: line-through;">Que tal Basic?</span></p>
<p>Diferente de algumas linguagens que nascem para encontrar um nicho, Erlang nasceu com um problema a ser resolvido, com requisitos a serem atendidos. Tolerância a falhas, concorrência realmente pesada, computação distribuída, atualização da aplicação sem derrubá-la, sistemas de tempo real, este é o nicho de Erlang; foi para isto que Erlang nasceu.</p>
<p><strong>Quem usa Erlang atualmente?</strong></p>
<p>Além da Ericsson, é lógico, há algumas outras grandes empresas e projetos usando Erlang, como por exemplo:</p>
<p>- <em>Facebook</em>, no backend de seu sistema de chat, lidando com 100 milhõs de usuários ativos;<br />
- <em>Delicious</em>, que tem mais de 5 milhões de usuários e mais de 150 milhões de bookmarks;<br />
- <em>Amazon SimpleDB</em>, o serviço de dados do seu poderoso EC2;<br />
- <em>Motorola</em>, <em>CouchDB</em>, <em>RabbitMQ</em>, <em>Ejabbed</em>, etc.</p>
<p><strong>Ok, mas Erlang é propriedade da Ericsson?</strong></p>
<p>Não, felizmente, não. Em 1998 a Ericsson tornou Erlang open source sob a licença EPL.</p>
<p>Quer mais uma boa notícia? Você não precisa de um servidor de aplicações para rodar sua aplicação Erlang, nem mesmo uma pesada IDE para escrevê-las. Tudo o que você precisa é de uma distribuição de Erlang para sua plataforma, seja Mac OS X, Linux, Windows, Solaris, ou qualquer outro sistema <em>Unix-like</em>, que traz consigo máquina virtual, compilador e vasta bibliotéca de módulos muito úteis <em>&#8211; além do banco de dados <a href="http://en.wikipedia.org/wiki/Mnesia" target="_blank">Mnesia</a></em>; e um editor de textos de sua preferência <em>&#8211; <a href="http://macromates.com" target="_blank">TextMate</a>, por exemplo, tem um ótimo bundle para Erlang.</em></p>
<p><strong>Algumas características de Erlang</strong></p>
<p><em>1- Expressividade e beleza</em></p>
<p>Há quem diga que não, mas Erlang é uma linguagem muito bonita &#8212; <em>ao menos pra mim.</em> Dado as já citadas influências de Erlang, ela é uma linguagem bem expressiva e declarativa, que encoraja a escrita de código simples e objetivo, o que certamente torna seu código fácil de ler, de escrever e de organizar [em módulos reutilizáveis]. O snippet abaixo é um exemplo de implementação do famoso fatorial:</p>
<pre class="brush: java;">
-module(sample1).
-export([fac/1]).

fac(0) -&gt; 1;
fac(N) -&gt; N * fac(N-1).
</pre>
<p><em>2- Forte uso de recursividade</em></p>
<p>Isto certamente é uma herança da veia funcional de Erlang que torna o código muito menos imperativo e mais declarativo. Mas além da beleza declarativa óbvia, é importante saber que Erlang foi projetada para lidar com iterações recursivas gigantescas sem qualquer degradação <em>&#8211; e sem estourar o &#8220;heap&#8221; de memória.</em></p>
<p><em>3- Livre de efeito colateral</em></p>
<p>Uma das grandes capacidades dadas por Erlang é a construção de sistemas altamente concorrentes rodando em processadores com multiplos núcleos. Isto não combina nada com efeito colateral, por isso, em Erlang, uma vez que um dado valor tenha sido atribuído a uma variável, esta não poderá mais ser modificada <em>&#8211; ou seja, estão mais para o que conhecemos por constantes do que para o que conhecemos por variaveis.</em></p>
<p>Se você já escreveu código concorrênte sabe o quanto tê-lo livre de efeitos colaterais te faz livre de dores de cabeça. Poucas coisas são tão deprimentes quanto debugar código concorrênte repleto de efeitos colaterais.</p>
<p><em>4- Pattern matching</em></p>
<p><a href="http://en.wikipedia.org/wiki/Pattern_matching" target="_blank">Pattern matching</a> em Erlang é usado para associar valores a variáveis, controlar fluxo de execução de programs, extrair valores de estruturas de dados compostas e lidar com argumentos de funções. Mais um ponto para código declarativo e expressividade. Vejamos o código abaixo:</p>
<pre class="brush: java;">
-module(sample2).
-export([convert_length/1]).

convert_length(Length) -&gt;
    case Length of
        {centimeter, X} -&gt;
            {inch, X / 2.54};
        {inch, Y} -&gt;
            {centimeter, Y * 2.54}
    end.
</pre>
<p>Fala por si, não?</p>
<p><em>5- Concorrência baseada em passagem de mensagens (a.k.a. Actors)</em></p>
<p>Acho que concorrência baseada em <a href="http://en.wikipedia.org/wiki/Message_passing" target="_blank">passagem de mensagem</a> entre <a href="http://en.wikipedia.org/wiki/Actor_model" target="_blank">atores</a> é uma das features mais populares de Erlang. Vejamos o porque com o famoso exemplo do Ping-Pong:</p>
<pre class="brush: java;">
-module(sample3).

-export([start/0, ping/2, pong/0]).

ping(0, Pong_PID) -&gt;
    Pong_PID ! finished,
    io:format(&quot;Ping finished~n&quot;, []);

ping(N, Pong_PID) -&gt;
    Pong_PID ! {ping, self()},
    receive
        pong -&gt;
            io:format(&quot;Ping received pong~n&quot;, [])
    end,
    ping(N - 1, Pong_PID).

pong() -&gt;
    receive
        finished -&gt;
            io:format(&quot;Pong finished~n&quot;, []);
        {ping, Ping_PID} -&gt;
            io:format(&quot;Pong received ping~n&quot;, []),
            Ping_PID ! pong,
            pong()
    end.

start() -&gt;
    Pong_PID = spawn(sample3, pong, []),
    spawn(sample3, ping, [3, Pong_PID]).
</pre>
<p>Neste pequeno snippet podemos observar algumas características de Erlang já citadas neste post, tal como <em>pattern matching</em> na captura das mensagens e recursividade no controle das iterações.</p>
<p>Agora, falando do aspecto concorrente em sim, algumas coisas são particularmente interessantes aqui:</p>
<p>a. Em Erlang, a concorrência acontece entre processos leves, diferente de linguagens como C++ e Java, que baseiam sua concorrência em threads nativas de sistema operacional [caríssimas];<br />
b. Em Erlang, há um tipo de dado chamado <em>PID</em>, o qual é o identificador do processo paralelo (mais conhecido como Actor) e para o qual as mensagens podem ser enviadas.</p>
<p>Releia o código acima com estas informações em mente e veja como concorrência em Erlang é algo completamente descomplicado e natural. Depois, pense no mesmo código implementado em C#, Java ou C++.</p>
<p><strong>Gostei de Erlang, há algum livro para eu começar a estudar?</strong></p>
<p>Sim, há dois livros excepcionais. <a href="http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X" target="_blank">Um</a>, do próprio criador da linguagem, Joe Armstrong:</p>
<p><img class="aligncenter" src="http://ecx.images-amazon.com/images/I/41XOOpdBzKL._SL500_AA240_.jpg" alt="" width="240" height="240" /></p>
<p>E <a href="http://www.amazon.com/Erlang-Programming-Francesco-Cesarini/dp/0596518188/ref=pd_sim_b_3" target="_blank">outro</a> de Francesco Cesarini e Simon Thompson:</p>
<p><img class="aligncenter" title="Erlang Programming" src="http://covers.oreilly.com/images/9780596518189/cat.gif" alt="" width="180" height="236" /></p>
<p>Além disso, há o próprio <a href="http://erlang.org/starting.html" target="_blank">material on line</a> que é muito bom e barato. <img src='http://leandrosilva.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Conclusão</strong></p>
<p>Erlang possui muitas outras características e informações bem interessantes, mas que me falta espaço neste post para citar e apresentar, senão ele ficará absurdamente gigantesco para o meu gosto. Mas acredito que pelo que já apresentei até aqui, você já tenha motivos suficientes para pensar em Erlang com carinho e conciderá-la para seu próximo grande projeto.</p>
<p>Em breve devo escrever algo sobre <a href="http://en.wikipedia.org/wiki/Open_Telecom_Platform_%28OTP%29" target="_blank">OTP</a>, já que neste post apresentei características mais inerentes à linguagem em si e nem tanto sobre a plataforma.</p>
<p>Até mais!</p>
]]></content:encoded>
			<wfw:commentRss>http://leandrosilva.com.br/2009/09/08/voce-deveria-considerar-erlang-para-seu-proximo-grande-projeto/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
