<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Elemar DEV</title>
	<atom:link href="http://elemarjr.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://elemarjr.net</link>
	<description>Tecnologia e desenvolvimento .net</description>
	<lastBuildDate>Fri, 24 Feb 2012 14:22:12 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='elemarjr.net' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5ea29b775e2b805f0f1e9fbebf132906?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Elemar DEV</title>
		<link>http://elemarjr.net</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://elemarjr.net/osd.xml" title="Elemar DEV" />
	<atom:link rel='hub' href='http://elemarjr.net/?pushpress=hub'/>
		<item>
		<title>Brincando com o MongoDB (usando C#)</title>
		<link>http://elemarjr.net/2012/02/23/brincando-com-o-mongodb-usando-c/</link>
		<comments>http://elemarjr.net/2012/02/23/brincando-com-o-mongodb-usando-c/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 23:39:15 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2294</guid>
		<description><![CDATA[Olá pessoal. Tudo certo!? Esse é um post “just for fun”. A ideia principal é explorar a utilização de MongoDB em aplicações C#. O que é MongoDB?! Usando a definição do site oficial: MongoDB (from &#34;humongous&#34;) is a scalable, high-performance, open source NoSQL database. Written in C++! Como aprender MongoDB? MongoDB oferece um shell online [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2294&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo!?</p>
<p>Esse é um post “just for fun”. A ideia principal é explorar a utilização de MongoDB em aplicações C#.</p>
<h2>O que é MongoDB?!</h2>
<p>Usando a definição do <a href="http://www.mongodb.org/">site oficial</a>:</p>
<blockquote><p>MongoDB (from &quot;hu<strong>mongo</strong>us&quot;) is a scalable, high-performance, <a href="http://www.mongodb.org/display/DOCS/Source+Code">open source</a> NoSQL database. Written in C++!</p>
</blockquote>
<h2>Como aprender MongoDB?</h2>
<p>MongoDB oferece um <em>shell </em>online para aprendizado básico de seus conceitos. Recomendo fortemente que você faça o tutorial antes de continuar. Isso vai ajudar você a entender alguns dos principais conceitos desse banco. Combinado?!</p>
<p>O mais bacana no tutorial on-line é que não é necessário instalar nada em seu computador.</p>
<h2>Instalando MongoDB em seu computador</h2>
<p>Agora que você já aprendeu a utilizar o MongoDB, é hora de ter o banco instalado e funcionando em seu computador.</p>
<p>Faça o download da versão mais adequada para seu sistema (disponível em <a title="http://www.mongodb.org/downloads" href="http://www.mongodb.org/downloads">http://www.mongodb.org/downloads</a>) e execute o tutorial oficial (<a title="http://www.mongodb.org/display/DOCS/Quickstart" href="http://www.mongodb.org/display/DOCS/Quickstart">http://www.mongodb.org/display/DOCS/Quickstart</a>).</p>
<h2>Preparando um projeto para consultar o Mongo</h2>
<p>Agora que você tem o Mongo instalado em seu sistema, é hora de aprender a operar o banco a partir de um projeto em C#.</p>
<p><font color="#ff0000">IMPORTANTE: Mantenha o Mongo em execução enquanto estiver brincando no C#.</font></p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image17.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb17.png?w=504&#038;h=258" width="504" height="258" /></a></p>
<p>No seu projeto em C# (para brincar, recomendo uma aplicação console), adicione uma referência Nuget usando a opção <em>Add Library Package Reference </em>(Se você não conhece NuGet, é mais do que hora de aprender acessando <a title="http://nuget.org/" href="http://nuget.org/">http://nuget.org/</a>) para o pacote MongoCSharpDriver.</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image18.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb18.png?w=504&#038;h=337" width="504" height="337" /></a></p>
<p>Esse procedimento irá adicionar referência para duas DLLs em seu projeto. Observe:</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image19.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb19.png?w=201&#038;h=244" width="201" height="244" /></a></p>
<h2>Criando um “documento” (a forma mais simples)</h2>
<p>Se você seguiu meu conselho e fez o tutorial on-line, já sabe que um banco mongo tem coleções de documentos. </p>
<p>A forma mais direta de criar um documento é assim:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b3e1171d-bc21-47fc-8bd8-8f20fe33149d" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
private static BsonDocument CreateDummyDocument()
{
           
    var result = new BsonDocument
        {
            {&quot;name&quot;, &quot;Joca 123 da Silva 4&quot; },
            {&quot;address&quot;, new BsonDocument
                {
                    {&quot;street&quot;, &quot;Rua dos Loucos&quot;},
                    {&quot;city&quot;, &quot;MongoDBlandia&quot;},
                    {&quot;state&quot;, &quot;TS&quot;}
                }
            }
        };
    return result;
}

</pre>
</pre>
</div>
<p><em>BsonDocument </em>é definido nas referências que adicionamos. Observe a sensibilidade do desenvolvedor da API em permitr a definição do documento de forma fluída (bem parecida com JSON, não acha?!).</p>
<p>Obviamente, o tipo fornece uma interface altertiva. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:35d4a781-69f8-4a2f-bebb-cb9fb117e8eb" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static BsonDocument CreateDummyDocument2()
{
    var result = new BsonDocument();
    result.Add(&quot;name&quot;, &quot;Joca 123 da Silva 4&quot;);

    var address = new BsonDocument();
    address.Add(&quot;street&quot;, &quot;Rua dos Loucos&quot;);
    address.Add(&quot;city&quot;, &quot;MongoDBlandia&quot;);
    address.Add(&quot;state&quot;, &quot;TS&quot;);

    result.Add(&quot;address&quot;, address);
    return result;
}
</pre>
</pre>
</div>
<p>Para mim, significativamente mais pesada. Entretanto, mais convencional.</p>
<h2>Adicionando o documento no Mongo</h2>
<p>Já sabemos como definir um documento. Agora, vamos ver como realizar a persistência dele no Mongo. É tão simples quanto isso:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d58c30ae-92c8-4619-9e32-ba41642ff8d6" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void AddDocument(
    BsonDocument document,
    string databaseName = &quot;myDatabase&quot;,
    string collectionName = &quot;contacts&quot;
    )
{
    var server = MongoServer.Create(&quot;mongodb://localhost&quot;);
    server.Connect();

    var db = server.GetDatabase(databaseName);
    var collection = db.GetCollection(collectionName);

    collection.Insert(document);

    server.Disconnect();
}
</pre>
</pre>
</div>
<p>Bonito, não?!</p>
<h2>Próximos passos…</h2>
<p>Obviamente, o driver do MongoDB oferece alternativas para persistência direta de objetos(sem criação manual de objetos BsonDocument). Além disso, todas as operações que podemos executar no Shell, também podem ser executadas através do C#.</p>
<p>Para entender tudo isso, recomendo fortemente a leitura de:</p>
<ul>
<li><a href="http://www.mongodb.org/display/DOCS/CSharp+Driver+Serialization+Tutorial">CSharp Driver Serialization Tutorial</a> – mostra, detalhadamente, com muitos exemplos, boas formas de persistir seus objetos diretamente nas coleções do Mongo.</li>
<li><a href="http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial">CSharp Driver Tutorial</a> – mostra como executar todas as operações suportadas pelo driver (muito além do que mostrei aqui). Além disso, é uma excelente “porta de entrada” para o caso de você desejar colaborar com a evolução do driver.</li>
</ul>
<p>Por hoje, era isso. </p>
<br /> Tagged: <a href='http://elemarjr.net/tag/mongodb/'>MongoDB</a>, <a href='http://elemarjr.net/tag/nosql/'>NoSQL</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2294/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2294&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/23/brincando-com-o-mongodb-usando-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb17.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb18.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb19.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Entendendo a estrutura de uma aplica&#231;&#227;o WP7</title>
		<link>http://elemarjr.net/2012/02/21/entendendo-a-estrutura-de-uma-aplicao-wp7/</link>
		<comments>http://elemarjr.net/2012/02/21/entendendo-a-estrutura-de-uma-aplicao-wp7/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 01:23:08 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[WP7]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2284</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! No último post falei sobre como a Microsoft planejou a experiência do usuário para o Windows Phone 7. Nesse post, começo a falar sobre o desenvolvimento de aplicações para a plataforma. Antes de começar Uma das características mais interessantes do Windows Phone 7 é a facilidade relacionada ao desenvolvimento de aplicações [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2284&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>No <a href="http://elemarjr.net/2012/02/20/j-hora-de-voc-conhecer-as-personas-anna-e-miles/">último post</a> falei sobre como a Microsoft planejou a experiência do usuário para o Windows Phone 7. Nesse post, começo a falar sobre o desenvolvimento de aplicações para a plataforma.</p>
<h2>Antes de começar</h2>
<p>Uma das características mais interessantes do Windows Phone 7 é a facilidade relacionada ao desenvolvimento de aplicações para ele. </p>
<p>Para desenvolver para o Windows Phone 7, aproveitamos todo o conhecimento relacionado a Silverlight/WPF e XNA. Além disso, contamos com o Visual Studio como IDE (o que é um grande benefício comparado a outras plataformas).</p>
<p>Se você já tem o Visual Studio instalado, instale também o SDK (pode ser obitdo em <a href="http://create.msdn.com">http://create.msdn.com</a>).</p>
<h2>Começando uma aplicação para o Windows Phone 7</h2>
<p>Com o Visual Studio e o SDK devidamente instalados, podemos iniciar um projeto para o Windows Phone. Observe:</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image13.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb13.png?w=514&#038;h=348" width="514" height="348" /></a></p>
<p>Como você pode ver, há diversos templates disponíveis. Para o post de hoje utilizaremos o mais simples deles (Windows Phone Application). </p>
<p>Antes de iniciar o projeto, o Visual Studio ainda solicita qual é a plataforma target. Observe:</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image14.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb14.png?w=364&#038;h=175" width="364" height="175" /></a></p>
<p>Há duas opções:</p>
<ul>
<li>7.0 – Para a primeira geração do sistema operacional</li>
<li>7.1 – Para aplicações com suporte a Mango.</li>
</ul>
<p>Escolho uma opcão e estamos prontos para iniciar o desenvolvimento.</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image15.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb15.png?w=628&#038;h=352" width="628" height="352" /></a></p>
<p>Se você conhece Silverlight (não, ele não morreu!) se sentirá em casa.</p>
<p>Como já é habitual, podemos executar a aplicação a partir do código gerado até aqui com o template. O Visual Studio carregará um emulador para que você possa experimentar.</p>
<h2>Composição de um projeto básico para WP7</h2>
<p>Observando os arquivos que formam o projeto, encontramos algumas coisas bem interessantes:</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image16.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb16.png?w=226&#038;h=275" width="226" height="275" /></a></p>
<p>Temos:</p>
<ul>
<li>Application Manifest</li>
<li>Algumas imagens</li>
<li>XAML (MainPage.xaml e App.xaml)</li>
<li>Código C# (MainPage.xaml.cs, App.xaml.cs e AssemblyInfo.cs)</li>
</ul>
<h2>Arquivos .XAP</h2>
<p>Quando você compila uma aplicação para WP7, seja usando Silverlight ou XNA, ocorre a geração um arquivo com extensão .xap.</p>
<p>Arquivos XAP são, simplesmente, Zip. Se renomearmos o arquivo XAP dando a ele a extensão .zip, podemos inspecionar facilmente seu conteúdo.</p>
<p>O arquivo XAP possui diversos arquivos:</p>
<ul>
<li>DLLs geradas no processo de compilação</li>
<li>manifestos</li>
<li>imagens</li>
<li>outros “assets” utilizados no projeto (como vídeos e outros arquivos de dado) que não tenham sido “embedded” na DLL.</li>
</ul>
<h2>Application Manifest</h2>
<p>O arquivo chamado <em>WPAppManifest.xml</em> é o manifesto da aplicação (WM é uma abreviatura para “Windows Mobile”).</p>
<p>Ele descreve a aplicação para o sistema operacional. Ou seja:</p>
<ul>
<li>nome;</li>
<li>como aplicação se parece;</li>
<li>o que ela “pode fazer”</li>
</ul>
<p>Veja o conteúdo do manifesto gerado com o template padrão.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9a494397-44ce-4b43-9db7-317f2a17ee28" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: plain; pad-line-numbers: true;">
&lt;Deployment xmlns=&quot;http://schemas.microsoft.com/windowsphone/2009/deployment&quot; AppPlatformVersion=&quot;7.1&quot;&gt;
  &lt;App xmlns=&quot;&quot; ProductID=&quot;{b281e38e-e1cb-46e6-b955-7dd1f2849e52}&quot; 
       Title=&quot;PhoneApp1&quot; 
       RuntimeType=&quot;Silverlight&quot; Version=&quot;1.0.0.0&quot; 
       Genre=&quot;apps.normal&quot;  Author=&quot;PhoneApp1 author&quot; 
       Description=&quot;Sample description&quot; 
       Publisher=&quot;PhoneApp1&quot;&gt;
    &lt;IconPath IsRelative=&quot;true&quot; IsResource=&quot;false&quot;&gt;ApplicationIcon.png&lt;/IconPath&gt;
    &lt;Capabilities&gt;
      &lt;Capability Name=&quot;ID_CAP_GAMERSERVICES&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_IDENTITY_DEVICE&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_IDENTITY_USER&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_LOCATION&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_MEDIALIB&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_MICROPHONE&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_NETWORKING&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_PHONEDIALER&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_PUSH_NOTIFICATION&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_SENSORS&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_WEBBROWSERCOMPONENT&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_ISV_CAMERA&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_CONTACTS&quot;/&gt;
      &lt;Capability Name=&quot;ID_CAP_APPOINTMENTS&quot;/&gt;
    &lt;/Capabilities&gt;
    &lt;Tasks&gt;
      &lt;DefaultTask  Name =&quot;_default&quot; NavigationPage=&quot;MainPage.xaml&quot;/&gt;
    &lt;/Tasks&gt;
    &lt;Tokens&gt;
      &lt;PrimaryToken TokenID=&quot;PhoneApp1Token&quot; TaskName=&quot;_default&quot;&gt;
        &lt;TemplateType5&gt;
          &lt;BackgroundImageURI IsRelative=&quot;true&quot; IsResource=&quot;false&quot;&gt;Background.png&lt;/BackgroundImageURI&gt;
          &lt;Count&gt;0&lt;/Count&gt;
          &lt;Title&gt;PhoneApp1&lt;/Title&gt;
        &lt;/TemplateType5&gt;
      &lt;/PrimaryToken&gt;
    &lt;/Tokens&gt;
  &lt;/App&gt;
&lt;/Deployment&gt;
</pre>
</pre>
</div>
<p>Entenda que quase toda a informação mantida nesse arquivo será “considerada” e sobrescrita no processo de certificação para o MarketPlace.</p>
<p>Perceba que a aplicação possui um atributo <em>ProductID </em>(é um GUID) que identifica a aplicação. Além disso, há um <em>RuntimeType </em>indicando que a aplicação é “Silverlight” (atualmente, poderia ser XNA também).</p>
<p>O atributo <em>Genre </em>influencia onde a aplicação será instalada no telefone:</p>
<ul>
<li>app.normal – indica que a aplicação deverá ser instalada na lista convencional</li>
<li>app.games – indica que a aplicação deverá ser instalada no “Games Hub” (Também é válido para aplicações Silverlight)</li>
</ul>
<p>O elemento <em>IconPath</em> indica o nome do ícone.</p>
<h3>Application Capabilities</h3>
<p>A parte mais interessante do Application manifest é a lista de “capabilities”. São as permissões que a aplicação demanda para funcionar.</p>
<p>O template padrão do Visual Studio requisita todas as “capacidades” disponíveis.</p>
<p>Em um post futuro, falo mais sobre esse tópico.</p>
<h2>Imagens</h2>
<p>O projeto que geramos possui três imagens. São elas:</p>
<ol>
<li>applicationicon.png – O ícone da aplicação exibido onde quer que a aplicação tenha sido instalada.</li>
<ol>
<li>Para aplicações no App List, a imagem deverá ter 62&#215;62 pixels</li>
<li>Para aplicações no Game Hub, a imagem deverá ter 173&#215;173 pixels</li>
</ol>
<li>Background.png – O ícone a ser utilizado como Tile na tela inicial. Deve ter 173&#215;173 pixels. Para mim, foi pobremente nomeado.</li>
<li>SplashScreenImage.jpg – Imagem a ser exibida quando a aplicação estiver sendo carregada. Deve ter 480&#215;800 pixels.</li>
</ol>
<p>Podemos mudar o nome e a localização dessas imagens. Também podemos utilizar arquivos PNG ou JPEG. Entretanto, devemos lembrar de atualizar o manifesto.</p>
<p>Ícones com 62&#215;62 pixels devem respeitar uma margem de 12 pixel. Ou seja, deve ser um ícone de 38&#215;38 centralizado.</p>
<p>Ícones com 173&#215;173 pixels devem ter, na prática, 73&#215;73 pixels com margem superior de 47 pixels e 50 nas margens laterais.</p>
<p><strong>applicationicon.png e splashscreenimage.jpg devem ter build action Content!</strong></p>
<h2>MainPage.xaml e MainPage.xaml.cs</h2>
<p>Toda aplicação tem uma ou mais “pages”. Novos projetos começam com uma única página chamada “MainPage”.</p>
<p>O .xaml devide a interface, o .cs define a “lógica” (frequentemente chamada de <em>code-behind</em>).</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b8873e55-02c6-46a6-965f-4d219d57072a" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: plain;">
&lt;phone:PhoneApplicationPage 
    x:Class=&quot;PhoneApp1.MainPage&quot;
    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    xmlns:phone=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&quot;
    xmlns:shell=&quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&quot;
    xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
    xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
    mc:Ignorable=&quot;d&quot; d:DesignWidth=&quot;480&quot; d:DesignHeight=&quot;768&quot;
    FontFamily=&quot;{StaticResource PhoneFontFamilyNormal}&quot;
    FontSize=&quot;{StaticResource PhoneFontSizeNormal}&quot;
    Foreground=&quot;{StaticResource PhoneForegroundBrush}&quot;
    SupportedOrientations=&quot;Portrait&quot; Orientation=&quot;Portrait&quot;
    shell:SystemTray.IsVisible=&quot;True&quot;&gt;

    &lt;!--LayoutRoot is the root grid where all page content is placed--&gt;
    &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Transparent&quot;&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height=&quot;Auto&quot;/&gt;
            &lt;RowDefinition Height=&quot;*&quot;/&gt;
        &lt;/Grid.RowDefinitions&gt;

        &lt;!--TitlePanel contains the name of the application and page title--&gt;
        &lt;StackPanel x:Name=&quot;TitlePanel&quot; Grid.Row=&quot;0&quot; Margin=&quot;12,17,0,28&quot;&gt;
            &lt;TextBlock x:Name=&quot;ApplicationTitle&quot; Text=&quot;MY APPLICATION&quot; 
                       Style=&quot;{StaticResource PhoneTextNormalStyle}&quot;/&gt;
            &lt;TextBlock x:Name=&quot;PageTitle&quot; Text=&quot;page name&quot; 
                       Margin=&quot;9,-7,0,0&quot; 
                       Style=&quot;{StaticResource PhoneTextTitle1Style}&quot;/&gt;
        &lt;/StackPanel&gt;

        &lt;!--ContentPanel - place additional content here--&gt;
        &lt;Grid x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;&lt;/Grid&gt;
    &lt;/Grid&gt;

&lt;/phone:PhoneApplicationPage&gt;
</pre>
</pre>
</div>
<p>&#160;</p>
<p>O aspecto mais importante a observar, se você já entende de XAML, é que não são definidas cores e fontes explicitamente. Em lugar disso, são especificados recursos que são fornecidos pelo sistema operacional (padrões do sistema).</p>
<h2>App.xaml e App.xaml.cs</h2>
<p>App.xaml é um arquivo especial que não define elementos visuais. Em lugar disso, define elementos que serão usados na aplicação como um todo. A única razão para mexer nesse arquivo é definir recursos globais ou novos estilos para serem usados em toda a aplicação.</p>
<p>App.xaml.cs define eventos que serão executados durante todo o ciclo de vida da aplicação. Com destaque para:</p>
<ul>
<li>Lauching</li>
<li>Activated</li>
<li>Deactivated</li>
<li>Closing</li>
</ul>
<p>Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:36ead4a9-ce30-4afb-8f71-02b6e5e72640" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System.Diagnostics;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace PhoneApp1
{
    public partial class App : Application
    {
        /// &lt;summary&gt;
        /// Constructor for the Application object.
        /// &lt;/summary&gt;
        public App()
        {
            // Global handler for uncaught exceptions. 
            UnhandledException += Application_UnhandledException;

            // Standard Silverlight initialization
            InitializeComponent();

            // Phone-specific initialization
            InitializePhoneApplication();

            // Show graphics profiling information while debugging.
            if (Debugger.IsAttached)
            {
                // Display the current frame rate counters.
                Current.Host.Settings.EnableFrameRateCounter = true;

                // Show the areas of the app that are being redrawn in each frame.
                //Application.Current.Host.Settings.EnableRedrawRegions = true;

                // Enable non-production analysis visualization mode, 
                // which shows areas of a page that are handed off to GPU with a colored overlay.
                //Application.Current.Host.Settings.EnableCacheVisualization = true;

                // Disable the application idle detection by setting the UserIdleDetectionMode property of the
                // application's PhoneApplicationService object to Disabled.
                // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
                // and consume battery power when the user is not using the phone.
                PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
            }
        }

        /// &lt;summary&gt;
        /// Provides easy access to the root frame of the Phone Application.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;The root frame of the Phone Application.&lt;/returns&gt;
        public PhoneApplicationFrame RootFrame { get; private set; }

        // Code to execute when the application is launching (eg, from Start)
        // This code will not execute when the application is reactivated
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {
        }

        // Code to execute when the application is activated (brought to foreground)
        // This code will not execute when the application is first launched
        private void Application_Activated(object sender, ActivatedEventArgs e)
        {
        }

        // Code to execute when the application is deactivated (sent to background)
        // This code will not execute when the application is closing
        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
        }

        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
        }

        // Code to execute if a navigation fails
        private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // A navigation has failed; break into the debugger
                Debugger.Break();
            }
        }

        // Code to execute on Unhandled Exceptions
        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                Debugger.Break();
            }
        }

        #region Phone application initialization

        // Avoid double-initialization
        private bool phoneApplicationInitialized;

        // Do not add any additional code to this method
        private void InitializePhoneApplication()
        {
            if (phoneApplicationInitialized)
                return;

            // Create the frame but don't set it as RootVisual yet; this allows the splash
            // screen to remain active until the application is ready to render.
            RootFrame = new PhoneApplicationFrame();
            RootFrame.Navigated += CompleteInitializePhoneApplication;

            // Handle navigation failures
            RootFrame.NavigationFailed += RootFrame_NavigationFailed;

            // Ensure we don't initialize again
            phoneApplicationInitialized = true;
        }

        // Do not add any additional code to this method
        private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
        {
            // Set the root visual to allow the application to render
            if (RootVisual != RootFrame)
                RootVisual = RootFrame;

            // Remove this handler since it is no longer needed
            RootFrame.Navigated -= CompleteInitializePhoneApplication;
        }

        #endregion
    }
}
</pre>
</pre>
</div>
<p>Era isso.</p>
<p><img style="border-style:none;" class="wlEmoticon wlEmoticon-winkingsmile" alt="Smiley piscando" src="http://elemarjr.files.wordpress.com/2012/02/wlemoticon-winkingsmile.png?w=594" /></p>
<br /> Tagged: <a href='http://elemarjr.net/tag/wp7/'>WP7</a>, <a href='http://elemarjr.net/tag/xaml/'>XAML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2284/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2284&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/21/entendendo-a-estrutura-de-uma-aplicao-wp7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb13.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb14.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb15.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb16.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/wlemoticon-winkingsmile.png" medium="image">
			<media:title type="html">Smiley piscando</media:title>
		</media:content>
	</item>
		<item>
		<title>J&#225; &#233; hora de voc&#234; conhecer (as personas) Anna e Miles!</title>
		<link>http://elemarjr.net/2012/02/20/j-hora-de-voc-conhecer-as-personas-anna-e-miles/</link>
		<comments>http://elemarjr.net/2012/02/20/j-hora-de-voc-conhecer-as-personas-anna-e-miles/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 23:14:14 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2272</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! Este é meu primeiro post (de muitos) falando especificamente sobre o desenvolvimento de aplicações e aprimoramento da experiência do usuário no Windows Phone 7. Nesse primeiro post, pretendo “apresentar” as duas personas, idealizadas pela Microsoft, para orientar o desenvolvimento de toda a experiência do usuário no Windows Phone. Também falo sobre [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2272&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>Este é meu primeiro post (de muitos) falando especificamente sobre o desenvolvimento de aplicações e aprimoramento da experiência do usuário no Windows Phone 7.</p>
<p>Nesse primeiro post, pretendo “apresentar” as duas personas, idealizadas pela Microsoft, para orientar o desenvolvimento de toda a experiência do usuário no Windows Phone. Também falo sobre os princípios que orientaram o desenvolvimento do METRO (para atender Anna e Miles).</p>
<h2>Life Maximizers</h2>
<p>Windows Phone 7 foi projetado para um grupo particular de usuários identificados, pela Microsoft, como “Life Maximizers”.</p>
<p>Segundo a empresa, são pessoas, maduras, comprometidas, que precisam de devices para comunicação que suporte <em>“Life in Motion”.</em></p>
<p>Para facilitar a compreensão desse “conceito”, foram idealizadas duas personas: Anna e Miles. </p>
<h2>Settled, rather than seeking</h2>
<p>Com o Windows Phone 7, a Microsoft deseja atender pessoas mais maduras e sérias. Pessoas que usam mais que Office e Outlook, mas que não “lotam” computadores e dispositivos com aplicações usadas apenas uma vez.</p>
<h2>Anna</h2>
<p>Anna tem 37 anos e acumula as funções de relações púbicas e mãe presente. Morando nos Estados Unidos, possui familiares na Europa com quem deseja manter contato.</p>
<p>Em seu tempo livre, Anna costuma escutar música e verificar seus e-mails.</p>
<blockquote><p>My life is a balancing act between work, family, friends, and my own personal needs. – Anna</p>
</blockquote>
<div style="width:448px;display:block;float:none;margin-left:auto;margin-right:auto;padding:0;" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:8e188e4f-be51-4126-b080-b7231d526629" class="wlWriterEditableSmartContent">
<div><span style="text-align:center; display: block;"><a href="http://elemarjr.net/2012/02/20/j-hora-de-voc-conhecer-as-personas-anna-e-miles/"><img src="http://img.youtube.com/vi/JjO4NaHRrIk/2.jpg" alt="" /></a></span></div>
</div>
<h2>Miles</h2>
<p>Miles tem 38 anos, é arquiteto e, há pouco tempo, começou seu próprio negócio. Miles é casado com Anna.</p>
<p>Miles é uma pessoa “conectada” que usa diversas soluções da Microsoft (Exchange, Excel, OneNote, etc) e de outros fornecedores (Miles adora o GMail).</p>
<p>Miles trabalha em casa mas visita clientes com grande frequência. Por isso, dá grande importância para o seu calendário.</p>
<blockquote><p>I love running my life real-time so I can take advantage of whatever is inspiring me…whether it’s a new project, a pick up game or a stolen moment with Anna. – Miles</p>
</blockquote>
<h2>METRO &#8211; uma nova linguagem visual</h2>
<p>Para atender as necessidades de Anna e Miles, a Microsoft desenvolveu uma nova linguagem visual. Chamou-a de METRO. Agora, está usando essa mesma linguagem visual em todos os seus aplicativos.</p>
<p>Segundo a própria Microsoft:</p>
<blockquote><p>METRO is our design language. We call it METRO because it is MODERN and clean. It is fast and in motion. It is about content and typography. And it is entirely authentic.</p>
</blockquote>
<h2>Princípios de Design para atender Miles e Anna</h2>
<p>Com Miles e Anna (personas) em mente, a equipe de design do WP7 consolidou os seguintes princípios para a linguagem de interface – Metro:</p>
<ul>
<li>Clean, Light, Open, Fast</li>
<ul>
<li>Aplicação veloz e responsiva;</li>
<li>Foco nas atividades mais importantes;</li>
<li>Fazer muito, com muito pouco;</li>
<li>Redução de elementos desnecessários;</li>
<li>Uso “tranquílo” de espaço em branco;</li>
<li>Aplicação em “tela-cheia” todo o tempo (sem barra de status)</li>
</ul>
<li>Celebrate Typography</li>
<ul>
<li>Fontes bonitas, não apenas legíveis;</li>
<li>Informação clara</li>
<li>Uso equilibrado de peso e escala;</li>
</ul>
<li>Alive in motion</li>
<ul>
<li>Interface responsiva e adaptada as ações do usuário’;</li>
<li>Entrega um contexto beneficiando usabilidade;</li>
<li>Atenção especial para as transições de estado da interface;</li>
<li>Senso de dimensão e profundidade;</li>
</ul>
<li>Content, Not Chrome</li>
<ul>
<li>Janelas sem bordas e sem barras de título – ênfase no conteúdo;</li>
<li>Redução de qualquer elemento visual que não esteja relacionado com o conteúdo;</li>
<li><strong>Content is the UI</strong></li>
<li>Interação direta com o conteúdo;</li>
</ul>
<li>Authentically Digital</li>
<ul>
<li>Projeto de interface adequado ao tamanho dos dispositivos (sem reduzir a interface de um desktop para o device)</li>
<li>Minimização das “analogias” da interface para artifícios mais ricos.</li>
</ul>
</ul>
<h2>Red Threads – Personal. Relevant. Connected.</h2>
<p>Microsoft especializou o desenvolvimento de aplicações para Windows Phone em três “Red Threads”: </p>
<ol>
<li>Personal – Your day, your way</li>
<li>Relevant – Your people, your location</li>
<li>Connected – Your stuff, your peace of mind</li>
</ol>
<p>Vejamos o que eles querem dizer…</p>
<h3></h3>
<h3>Personal</h3>
<p>Toda a interface desenvolvida conforme Metro deverá focar os interesses do usuário e, preferencialmente, apenas isso. Embora isso pareça óbvio, não ocorre sempre assim.</p>
<p>A chave para fazer uma aplicação “Personal” é prover apenas informação diretamente relacionada ao usuário de alguma forma. </p>
<blockquote><p>Uma ótima consequência de fazer a interface “pessoal” é a redução do volume de dados que precisa ser transmitida.</p>
</blockquote>
<h3>Relevant</h3>
<p>Outro aspecto aparentemente óbvio. Sempre pensamos que nossas interfaces contém informações relevantes para o usuário. Entretanto a questão central é:</p>
<blockquote><p>Quanto <strong>relevante para o usuário</strong> você projeta suas interfaces atualmente versus quanto relevante essa interface poderia ser?!</p>
</blockquote>
<p>Algumas aplicações óbvias desse conceito:</p>
<ul>
<li>Se você está desenvolvendo uma aplicação que é geo-sensível, deveria considerar a localização do usuário fornecida pelo hardware;</li>
<li>Sua interface pode utilizar o acelerômetro para determinar se o usuário está em movimento;</li>
<li>Sua interface pode utilizar data e hora como filtro primário de informações.</li>
</ul>
<h3>Connected</h3>
<p>No lugar de desenvolver aplicações “stand-alone”, devemos considerar o desenvolvimento de cenários onde um usuário possa colaborar com outros usuários, compartilhando informação e conhecimento entre dispositivos. Para isso, precisamos “conectar” nossas aplicações a serviços on-line, armazenando informações na Cloud.</p>
<blockquote><p>A estratégia é não confiar em ambientes 100% conectados. No lugar disso, desenvolver funções que funcionem independente de uma conexão com rede, sincronizando e atualizando dados, em background, sempre que uma conexão estiver disponível.</p>
</blockquote>
<p>A combinação dos três Red Threads e dos princípios da linguagem METRO, entregam para Anna e Miles aquilo que eles buscam. </p>
<p>Você talvez não saiba. Pelo menos, não falei aqui no blog (embora você talvez tenha visto no vídeo). Mas, Anna e Miles têm um filho, Luca, 11 anos. A Microsoft também concebeu o seu perfil. Não sei até onde ele influenciou as decisões de interface, mas …</p>
<p>Era isso!</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/ux/'>UX</a>, <a href='http://elemarjr.net/tag/wp7/'>WP7</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2272/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2272&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/20/j-hora-de-voc-conhecer-as-personas-anna-e-miles/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>
	</item>
		<item>
		<title>Monads em C#</title>
		<link>http://elemarjr.net/2012/02/14/monads-em-c/</link>
		<comments>http://elemarjr.net/2012/02/14/monads-em-c/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 23:15:11 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Monad]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2266</guid>
		<description><![CDATA[Olá pessoal. Tudo certo? Monad é uma abstração poderosa que facilita a escrita de soluções elegantes para problemas complexos. É um conceito matemático amplamente utilizado em linguagens funcionais (com destaque para Haskell). Além disso, foi amplamente considerado no design do LINQ. Nesse post, mostro como utilizar essa poderosa abstração em C#. O que é Monad? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2266&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?</p>
<p>Monad é uma abstração poderosa que facilita a escrita de soluções elegantes para problemas complexos. É um conceito matemático amplamente utilizado em linguagens funcionais (com destaque para Haskell). Além disso, foi amplamente considerado no design do LINQ. </p>
<p>Nesse post, mostro como utilizar essa poderosa abstração em C#.</p>
<h2>O que é Monad?</h2>
<p>Esse termo acumula dois significados:</p>
<ol>
<li>É uma abstração, ou pattern de implementação, utilizada para combinar funções utilizando “valores ampliados”; </li>
<li>São classes implementadas seguindo o pattern que recebe este mesmo nome. </li>
</ol>
<h2>Benefícios de adoção</h2>
<p>Monads permitem a redução de “boilerplate code”. Ou seja, códigos repetidos, não relacionados com o objetivo principal do domínio, como, por exemplo:</p>
<ul>
<li>validação de estado (para verificar se uma variável está com conteúdo nulo, por exemplo), </li>
<li>logging </li>
<li>tratamento de exceptions </li>
</ul>
<p>Removendo boilerplate code, temos códigos mais simples de escrever, ler e, consequentemente, manutenir.</p>
<h2>Valores simples e valores “ampliados”</h2>
<p>Para poder entender corretamente o Pattern Monad, precisamos saber diferenciar valores simples e valores “ampliados” </p>
<p>Comecemos por valores simples. Considere:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f74ed8b6-358d-4072-bbbe-ad42df555337" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
private static void Main(string[] args)
{
    Func&lt;int, int&gt; fiveTimes = v =&gt; v*5;
    Func&lt;int, int&gt; halfOf = v =&gt; v/2;
    Console.WriteLine(halfOf(fiveTimes(6)));
}
</pre>
</pre>
</div>
<p>Nesse código, definimos duas funções simples que retornam apenas o “resultado principal” do processamento, sem nenhuma informação adicional.</p>
<p>Métodos assim são fáceis de combinar. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cafea25f-b12b-49f8-b5f3-534bc47cabc1" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void Main(string[] args)
{
    Func&lt;int, int&gt; fiveTimes = v =&gt; v*5;
    Func&lt;int, int&gt; halfOf = v =&gt; v/2;
    Func&lt;int, int&gt; halfOfFiveTimes = v =&gt; halfOf(fiveTimes(v));
    
    Console.WriteLine(halfOfFiveTimes(6));
}
</pre>
</pre>
</div>
<p>Entretanto, por só retornarem o valor principal, transferem uma série de responsabilidades para códigos clientes (verificação de retorno nulo, exceptions, etc).</p>
<p>Por outro lado, valores ampliados conseguem descrever mais do que o seu resultado principal.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:4a345873-fb2f-41f5-b370-ff7360092524" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
class Envelope&lt;T&gt;
{
    public T Value { get; private set; }

    public Envelope(T value)
    {
        Value = value;
    }
}
</pre>
</pre>
</div>
<p>Nossa implementação, ilustrativa, não faz uso do benefício que esse tipo poderia prover.</p>
<p>Vamos mudar nosso código para retornar esse valor ampliado.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b8d9d39a-7dba-4097-9427-a21492a0d6c8" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void Main(string[] args)
{
    Func&lt;int, Envelope&lt;int&gt;&gt; fiveTimes = v =&gt; new Envelope&lt;int&gt;(v*5);
    Func&lt;int, Envelope&lt;int&gt;&gt; halfOf = v =&gt; new Envelope&lt;int&gt;(v/2);
    
    Console.WriteLine(halfOf(fiveTimes(6).Value).Value);
}
</pre>
</pre>
</div>
<p>Naturalmente, como os valores de entrada (parâmetro) e saída (retorno) das funções não são do mesmo tipo, a combinação é um pouco mais trabalhosa. Para facilitar essa combinação, adicionamos um helper a classe <strong><em>Envelope</em></strong>.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ac26e262-dd3d-4dcf-af76-9b2b0ff69f93" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
class Envelope&lt;T&gt;
{
    public T Value { get; private set; }

    public Envelope(T value)
    {
        Value = value;
    }

    public Envelope&lt;TResult&gt; Bind&lt;TResult&gt;(Func&lt;T, Envelope&lt;TResult&gt;&gt; func)
    {
        return func(Value);
    }
}
</pre>
</pre>
</div>
<p>O que nos habilita a escrever o código de forma mais elegante.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c8ffbadd-e06f-4b0f-9bf6-ba660726e707" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void Main(string[] args)
{
    Func&lt;int, Envelope&lt;int&gt;&gt; fiveTimes = v =&gt; new Envelope&lt;int&gt;(v * 5);
    Func&lt;int, Envelope&lt;int&gt;&gt; halfOf = v =&gt; new Envelope&lt;int&gt;(v / 2);
    Func&lt;int, Envelope&lt;int&gt;&gt; halfOfFiveTimes = v =&gt; halfOf(v).Bind(fiveTimes);

    Console.WriteLine(halfOfFiveTimes(6).Value);
}
</pre>
</pre>
</div>
<h2>Implementação do Monad pattern</h2>
<p>Monad consiste de classes “envelope” com suporte para:</p>
<ol>
<li>criação de instâncias a partir do valor principal (no nosso exemplo, com o construtor); </li>
<li>combinação facilitada com outros objetos que implementem o pattern. </li>
</ol>
<p>O Envelope que escrevemos acima atende a essas duas condições. Logo, é um monad (Inútil, mas é um monad).</p>
<p>Uma prática comum, na implementação de Monads em C# é escrever Extensions Methods para criação do “primeiro monad”. Continuando no exemplo do envelope:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e8b97d6e-e1a9-4a92-8be0-b07a187475e9" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
static class EnvelopeExtensions
{
    public static Envelope&lt;T&gt; ToEnvelope&lt;T&gt;(T value)
    {
        return new Envelope&lt;T&gt;(value);
    }
}
</pre>
</pre>
</div>
<p>O que possibilita a simplificação no uso de monads. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ba8ac5c1-eb4c-4ce5-a45f-7ae12e54c204" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void Main(string[] args)
{
    Func&lt;int, Envelope&lt;int&gt;&gt; fiveTimes = v =&gt; (v * 5).ToEnvelope();
    Func&lt;int, Envelope&lt;int&gt;&gt; halfOf = v =&gt; (v / 2).ToEnvelope();
    Func&lt;int, Envelope&lt;int&gt;&gt; print = v =&gt;
                                         {
                                             Console.WriteLine(v);
                                             return v.ToEnvelope();
                                         };
    6.ToEnvelope()
        .Bind(fiveTimes)
        .Bind(halfOf)
        .Bind(print);
}
</pre>
</pre>
</div>
<h2>Maybe – Um Monad útil, em C#</h2>
<p>Considere o seguinte código:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1b41e63d-0e3e-464e-8a85-8a07554194a2" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static string GetThirdChildName(Dummy d)
{
    return d.Child.Child.Child.Name;
}
</pre>
</pre>
</div>
<p>Qual é o problema com esse código?! Qualquer um dos “três níveis” de propriedades poderá estar nulo (resultando em exception).</p>
<p>Para evitar problemas, devemos adicionar algum código de verificação. Entretanto, dependendo da complexidade da expressão, podemos incorrer em falhas. O ideal é fazer com que a validação esteja diretamente associada a execução. Assim, surge os Monads. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:731f6874-be61-4a0b-bea1-349bc8600cb5" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public class Maybe&lt;T&gt;
{
    public static readonly Maybe&lt;T&gt; Empty = new Maybe&lt;T&gt;();

    public Maybe(T value)
    {
        Value = value;
        IsEmpty = false;
    }

    private Maybe()
    {
        IsEmpty = true;
    }

    public T Value { get; private set; }
    public bool IsEmpty { get; private set; }

    public bool HasValue
    {
        get { return !IsEmpty; }
    }

    public Maybe&lt;TResult&gt; Bind&lt;TResult&gt;(Func&lt;T, Maybe&lt;TResult&gt;&gt; f)
    {
        return IsEmpty ? Maybe&lt;TResult&gt;.Empty : f(Value);
    }
}
</pre>
</pre>
</div>
<p>Esse monad pode ter ou não um valor atribuido. Caso não tenha, qualquer “bind” resultará em um Monad “vazio”.</p>
<p>Para completar a funcionalidade do Monad, definimos também alguns extension methods.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2923aa4b-7d1d-4cc9-bed0-c957a812ca6a" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static class MaybeExtensions
{
    public static Maybe&lt;T&gt; ToMaybe&lt;T&gt;(this T value)
    {
        return new Maybe&lt;T&gt;(value);
    }

    public static Maybe&lt;T&gt; ToNotNullMaybe&lt;T&gt;(this T value)
        where T : class
    {
        return value != null ? value.ToMaybe() : Maybe&lt;T&gt;.Empty;
    }
}
</pre>
</pre>
</div>
<p>Considere:</p>
<ul>
<li>Criei um “conversor” imediato de qualquer valor para o Monad; </li>
<li>Criei um “converso especialista” que define qualquer nulo como Monad vazio. </li>
</ul>
<p>Nosso código, agora, pode ser escrito assim:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ec4c408f-5d70-4626-9800-08352e7545e5" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static string GetThirdChildNameOrNull(Dummy d)
{
    return d.ToNotNullMaybe()
        .Bind(t =&gt; t.Child.ToNotNullMaybe())
        .Bind(t =&gt; t.Child.ToNotNullMaybe())
        .Bind(t =&gt; t.Child.ToNotNullMaybe())
        .Bind(t =&gt; t.Name.ToNotNullMaybe())
        .Value;
}
</pre>
</pre>
</div>
<p>A principal vantagem desse código é que tornamos a validação dispensável. O lado negativo é a quantidade de lambda expressions.</p>
<p>Apenas como provocação, <em>IEnumerable&lt;T&gt;</em> é um monad. Graças a ele, podemos criar implementações bem mais limpas, mas esse é tema para outro dia.</p>
<p>Era isso.</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/functional-programming/'>Functional Programming</a>, <a href='http://elemarjr.net/tag/monad/'>Monad</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2266/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2266&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/14/monads-em-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>
	</item>
		<item>
		<title>Map, Filter e Fold em C#</title>
		<link>http://elemarjr.net/2012/02/13/map-filter-e-folder-em-c/</link>
		<comments>http://elemarjr.net/2012/02/13/map-filter-e-folder-em-c/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 00:52:39 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[LINQ]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2261</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! No paradigma funcional, há três funções, muito comuns, aplicadas a listas e sequências. São elas: Map – uma mesma operação aplicada a todos os elementos de uma lista e/ou sequência; Filter – seleção de elementos de uma lista/sequência, conforme um critério especificado; Fold – “acumulo” de todos os valores de uma [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2261&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>No paradigma funcional, há três funções, muito comuns, aplicadas a listas e sequências. São elas:</p>
<ol>
<li>Map – uma mesma operação aplicada a todos os elementos de uma lista e/ou sequência;</li>
<li>Filter – seleção de elementos de uma lista/sequência, conforme um critério especificado;</li>
<li>Fold – “acumulo” de todos os valores de uma lista/sequência em um único resultado.</li>
</ol>
<p>Este post mostra alguns exemplos de aplicação destas funções em C#, considerando as implementações disponíveis no LINQ. No final, mostro como potencializar o uso dessas funções através de uma técnica chamada Currying (descrita em um <a href="http://elemarjr.net/2012/02/09/tornando-o-cdigo-mais-elegante-com-currying-e-partial-application-em-c/">post anterior</a>).</p>
<h2>Select, Where e Aggregate</h2>
<p>O LINQ possui uma implementação completa das funções descritas. Veja alguns exemplos de uso:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:178e638c-c014-4653-94e3-f8440bd766b9" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var squaresOf1To100 = Enumerable.Range(1, 100)
    .Select(x =&gt; x * x);

var evenOf1To100 = Enumerable.Range(1, 100)
    .Where(x =&gt; x % 2 == 0);

var sumOfEvenOf1To100 = Enumerable.Range(1, 100)
    .Where(x =&gt; x % 2 == 0)
    .Aggregate((l, r) =&gt; l + r);
</pre>
</pre>
</div>
<p>Na verdade, <strong><em>Select (Map)</em></strong>, <strong><em>Where (Filter) </em></strong>e <strong><em>Aggregate (Fold) </em></strong>são extension methods definidos na classe estática Enumerable. Logo, podem também ser utilizados em uma notação mais convencional. Considere:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e23fbd3b-79ae-4b49-8e4c-aa31e18635e1" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var squaresOf1To100 = Enumerable.Select(
    Enumerable.Range(1, 100),
    x =&gt; x * x
    );

var evenOf1To100 = Enumerable.Where(
    Enumerable.Range(1, 100),
    x =&gt; x % 2 == 0
    );

var sumOfEvenOf1To100 = Enumerable.Aggregate(
    Enumerable.Where(
        Enumerable.Range(1, 100),
        x =&gt; x % 2 == 0
        ),
    (l, r) =&gt; l + r
    );
</pre>
</pre>
</div>
<p>Perceba como a Microsoft deixou nossos códigos mais elegantes pela definição dos extension methods (há um post sobre <a href="http://elemarjr.net/2011/12/26/melhorando-o-codigo-com-extension-methods/">como melhorar códigos usando extension methods</a>).</p>
<p>Como você sabe, há métodos de agregação (operadores) pré-definidos que dimunem a necessidade da função <strong><em>Aggregate </em></strong>(No código de exemplo, poderíamos usar o agregador <strong><em>Sum </em></strong>no lugar do “genérico” <strong><em>Aggregate</em></strong>). Entretanto, o uso criativo desse operador permite que levantemos muito mais informações. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5406431c-4bd2-408a-bd85-fb324b63fdf2" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var ages = people
    .Select(p =&gt; DateTime.Now - p.Birthday)
    .Select(elapsedTime =&gt; elapsedTime.TotalDays)
    .Select(days =&gt; Convert.ToInt32(days / 365));

var summary = ages
    .Aggregate(Tuple.Create(0, 0), (l, r) =&gt; Tuple.Create(l.Item1 + r, l.Item2 + 1));
</pre>
</pre>
</div>
<p>No exemplo, percorro uma coleção de pessoas calculando a idade de cada uma delas. Depois, usando <strong><em>Aggregate</em></strong>, crio uma tupla com a soma dessas idades e com o número de elementos da lista. Também é possível definir um tipo anônimo para deixar a sintaxe mais clara. Perceba:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:52295b1b-e617-4ac6-947d-263b4b9b3fdd" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var summary2 = ages
    .Aggregate(
        new { SumOfAges = 0, Count = 0 },
        (l, r) =&gt; new { SumOfAges = l.SumOfAges + r, Count = l.Count + 1 }
    );
</pre>
</pre>
</div>
<p>Obviamente, podemos também escrever esse código usando a notação “livre” de extension methods, mas veja como o prejuízo de leitura fica mais evidente:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1bd91e96-5909-47e1-9eb3-1b8ae70e5e7e" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var ages = Enumerable.Select(
    Enumerable.Select(
        Enumerable.Select(
            people,
            p =&gt; DateTime.Now - p.Birthday
            ),
        elapsedTime =&gt; elapsedTime.TotalDays
        ),
    days =&gt; Convert.ToInt32(days / 365)
    );

var summary = Enumerable.Aggregate(
    ages,
    Tuple.Create(0, 0),
    (l, r) =&gt; Tuple.Create(l.Item1 + r, l.Item2 + 1)
    );

var summary2 = Enumerable.Aggregate(
    ages,
    new { SumOfAges = 0, Count = 0 },
    (l, r) =&gt; new { SumOfAges = l.SumOfAges + r, Count = l.Count + 1 }
    );
</pre>
</pre>
</div>
<h2>Currying Map, Filter e Fold</h2>
<p>Como expliquei em um post anterior, currying é uma técnica onde começamos com uma função com múltiplos parâmetros e a convertemos em uma sequência de funções, em cadeia, com apenas um parâmetro cada. Utilizando essa técnica, podemos, facilmente, criar novas funções especializadas, a partir de funções genéricas.</p>
<p>O problema com os métodos Select, Where e Aggregate é que eles têm, como primeiro parâmetro, a lista/sequência que será processada. Isso torna currying pouco usual para elas. Então, vamos mudar as coisas. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2600c8e4-021e-4e46-b7dd-21b46fedb4f8" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
static IEnumerable&lt;TResult&gt; Map&lt;TInput, TResult&gt;(Func&lt;TInput, TResult&gt; func, IEnumerable&lt;TInput&gt; input)
{
    return input.Select(func);
}

static IEnumerable&lt;TInput&gt; Filter&lt;TInput&gt;(Func&lt;TInput, bool&gt; func, IEnumerable&lt;TInput&gt; input)
{
    return input.Where(func);
}


static TAggregate Fold&lt;TAggregate, TInput&gt;(
    Func&lt;TAggregate, TInput, TAggregate&gt; func,
    TAggregate seed, 
    IEnumerable&lt;TInput&gt; input
    )
{
    return input.Aggregate(seed, func);
}

static TInput Fold&lt;TInput&gt;(
    Func&lt;TInput, TInput, TInput&gt; func,
    IEnumerable&lt;TInput&gt; input
    )
{
    return input.Aggregate(func);
}
</pre>
</pre>
</div>
<p>O que fizemos?! Simplesmente mudamos a sequência dos parâmetros. Para fins de simplificação, vou repetir aqui as funções que escrevi para Currying em um post anterior.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:22301bb4-1c08-4464-9ac2-d02671fd7991" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static class FunctionalExtensions
{
    public static Func&lt;T1, Func&lt;T2, TResult&gt;&gt;
        Curry&lt;T1, T2, TResult&gt;(this Func&lt;T1, T2, TResult&gt; func)
    {
        return a =&gt; b =&gt; func(a, b);
    }

    public static Func&lt;T1, Func&lt;T2, Func&lt;T3, TResult&gt;&gt;&gt;
        Curry&lt;T1, T2, T3, TResult&gt;(this Func&lt;T1, T2, T3, TResult&gt; func)
    {
        return a =&gt; b =&gt; c =&gt; func(a, b, c);
    }

    public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Func&lt;T4, TResult&gt;&gt;&gt;&gt;
        Curry&lt;T1, T2, T3, T4, TResult&gt;(this Func&lt;T1, T2, T3, T4, TResult&gt; func)
    {
        return a =&gt; b =&gt; c =&gt; d =&gt; func(a, b, c, d);
    }

    public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Func&lt;T4, Func&lt;T5, TResult&gt;&gt;&gt;&gt;&gt;
        Curry&lt;T1, T2, T3, T4, T5, TResult&gt;(this Func&lt;T1, T2, T3, T4, T5, TResult&gt; func)
    {
        return a =&gt; b =&gt; c =&gt; d =&gt; e =&gt; func(a, b, c, d, e);
    }
}
</pre>
</pre>
</div>
<p>Perfeito! Agora, vamos ver o que podemos fazer com isso.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:37cd956c-4eed-4ee4-95d7-c1a45bbf676e" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
var curriedMap =  FunctionalExtensions.Curry&lt;Func&lt;int, int&gt;, IEnumerable&lt;int&gt;, IEnumerable&lt;int&gt;&gt;(Map);
var curriedFilter = FunctionalExtensions.Curry&lt;Func&lt;int, bool&gt;, IEnumerable&lt;int&gt;, IEnumerable&lt;int&gt;&gt;(Filter);
var curriedFold = FunctionalExtensions.Curry&lt;Func&lt;int, int, int&gt;, IEnumerable&lt;int&gt;, int&gt;(Fold);

var squares = curriedMap(x =&gt; x*x);
var squaresOf1To100 = squares(Enumerable.Range(1, 100));

var evens = curriedFilter(x =&gt; x%2 == 0);

var evenOf1To100 = evens(
    Enumerable.Range(1, 100)
    );

var sum = curriedFold((l, r) =&gt; l + r);
var sumOfEvenOf1To100 = sum(evens(Enumerable.Range(1, 100)));
</pre>
</pre>
</div>
<p>Bacana, não?</p>
<p>Era isso.</p>
<p><font size="5">&#160;</font></p>
<br /> Tagged: <a href='http://elemarjr.net/tag/functional-programming/'>Functional Programming</a>, <a href='http://elemarjr.net/tag/linq/'>LINQ</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2261/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2261&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/13/map-filter-e-folder-em-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>
	</item>
		<item>
		<title>Como Closures funcionam em C#</title>
		<link>http://elemarjr.net/2012/02/10/como-closures-funcionam-em-c/</link>
		<comments>http://elemarjr.net/2012/02/10/como-closures-funcionam-em-c/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 01:11:16 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Intermediate Language]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2257</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! Uma discussão com o Juan Lopes (@juanplopes) me motivou a escrever este post. Pretendo explicar como Closures são entregues pelo compilador do C#. Uma questão intrigante… Para entender como closures funcionam é melhor examinar um código de exemplo. Observe: Seguindo o caminho de execução: &#160;Main chama a função GetFunc que retorna [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2257&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>Uma discussão com o Juan Lopes (<a href="http://twitter.com/juanplopes">@juanplopes</a>) me motivou a escrever este post. Pretendo explicar como Closures são entregues pelo compilador do C#.</p>
<h2>Uma questão intrigante…</h2>
<p>Para entender como closures funcionam é melhor examinar um código de exemplo. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:91b03989-067b-4315-8833-23fbb4cebaf5" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
using System;

namespace HowClosureWorks
{
    internal class Program
    {
        public static Func&lt;int, int&gt; GetFunc()
        {
            int seed = 10;
            Func&lt;int, int&gt; f = (v) =&gt; v + seed;
            Console.WriteLine(f(10));

            seed = 20;
            Console.WriteLine(f(15));
            return f;
        }

        static void Main()
        {
            Console.Title = &quot;How Closure Works&quot;;
            Console.WriteLine(GetFunc()(20));
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Seguindo o caminho de execução:</p>
<ol>
<li>&#160;<em>Main </em>chama a função <em>GetFunc </em>que retorna uma função;</li>
<li>Na <em>GetFunc</em>, há uma variável chamada <em>seed </em>(iniciada com 10) e outra chamada <em>f;</em></li>
<li><em>f </em>é uma expressão lambda que soma o valor de <em>seed </em>com o parâmetro <em>v</em>;</li>
<li><em>f </em>é evocada com parâmetro 10 – o retorno é 20 (valor do parâmetro + o valor de <em>seed</em>);</li>
<li><em>seed </em>é alterado para 20;</li>
<li><em>f </em>é acionado com parâmetro 15 – o retorno é 35;</li>
<li><em>f </em>é retornado de <em>GetFunc </em>e é chamado novamente com parâmetro 20 – o retorno agora é 40 (parâmetro + o último valor de <em>seed</em>).</li>
</ol>
<p>Vendo a execução:</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image11.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb11.png?w=301&#038;h=143" width="301" height="143" /></a></p>
<p>A questão é: A variável <em>seed</em> não deveria ter “saído” do escopo assim que a função GetFunc retorna?! </p>
<h2>Surgem os Closures…</h2>
<p>Closures garantem que valores não saiam do escopo quando o compilador “percebe” que isso cause algum prejuízo ao sistema.</p>
<p>Veja a definição da wikipedia:</p>
<blockquote>
<p>In <a href="http://en.wikipedia.org/wiki/Computer_science">computer science</a>, a <b>closure</b> (also <b>lexical closure</b>, <b>function closure</b>, <b>function value</b> or <b>functional value</b>) is a <a href="http://en.wikipedia.org/wiki/Function_(computer_science)">function</a> together with a <i>referencing environment</i> for the <a href="http://en.wikipedia.org/wiki/Non-local_variable">non-local variables</a> of that function.<sup><a href="http://en.wikipedia.org/wiki/Closure_(computer_science)#cite_note-0">[1]</a></sup> A closure allows a function to access variables outside its typical scope. Such a function is said to be &quot;closed over&quot; its <a href="http://en.wikipedia.org/wiki/Free_variables_and_bound_variables">free variables</a>. The referencing environment <a href="http://en.wikipedia.org/wiki/Name_binding">binds</a> the nonlocal names to the corresponding variables in <a href="http://en.wikipedia.org/wiki/Scope_(computer_science)">scope</a> at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself. When the closure is <i>entered</i> at a later time, possibly from a different scope, the function is executed with its non-local variables referring to the ones captured by the closure.</p>
</blockquote>
<p>De forma simplificada:</p>
<ul>
<li>O compilador identifica que uma função anônima (variável <em>f</em>) utiliza uma variável definida fora de seu escopo (variável <em>seed</em>);</li>
<li>Como essa função anônima será retornada e usada em outra posição do código (fora do escopo da variável <em>seed</em>), o compilador armazena os dados que são necessários em um lugar seguro (fora do <em>stack</em>);</li>
<li>Compilador gera uma classe anônima para armazenar com a implementação da função anônima (variável <em>f</em>) e com o dado que utiliza (variável <em>seed</em>)<em>;</em></li>
<li>Compilador modifica o código do método <em>GetFunc</em> para instanciar essa classe anônima usando os valores de <em>seed </em>e o <em>método</em> dessa classe. </li>
</ul>
<p>Ou seja, o IL gerado é totalmente compatível com aqueles das primeiras versões do Framework. </p>
<h2>Observando o IL</h2>
<p>Observe a estrutura do IL gerado (usando o IL Disassembler)</p>
<p>&#160;<a href="http://elemarjr.files.wordpress.com/2012/02/image12.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb12.png?w=490&#038;h=171" width="490" height="171" /></a></p>
<p>Perceba a classe aninhada e privada <em>c__DisplayClass1. </em>É a classe, privada e aninhada, gerada pelo compilador para armazenar o valor da variável <em>seed </em>(veja como o nome foi preservado) e do método anônimo <em>&lt;GetFunc&gt;b_0.</em></p>
<p>Inspecionando do método anônimo temos o seguinte IL:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:81051107-76cf-4b13-8430-43f3a8820894" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: plain;">
.method public hidebysig instance int32  '&lt;GetFunc&gt;b__0'(int32 v) cil managed
{
  // Code size       9 (0x9)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.0
  IL_0002:  ldfld      int32 HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1'::seed
  IL_0007:  add
  IL_0008:  ret
} // end of method '&lt;&gt;c__DisplayClass1'::'&lt;GetFunc&gt;b__0'
</pre>
</pre>
</div>
<p>Se você não entende muito de IL, veja a <a href="http://elemarjr.net/tag/il-101/">série que escrevi sobre o tema</a>.</p>
<p>Agora, vejamos como o compilador resolveu o método <em>GetFunc</em></p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:9542eb0f-70a5-44b9-82fb-5c14c0a275dc" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: plain;">
.method public hidebysig static class [mscorlib]System.Func`2&lt;int32,int32&gt; 
        GetFunc() cil managed
{
  // Code size       63 (0x3f)
  .maxstack  3
  .locals init ([0] class [mscorlib]System.Func`2&lt;int32,int32&gt; f,
           [1] class HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1' 'CS$&lt;&gt;8__locals2')
  IL_0000:  newobj     instance void HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1'::.ctor()
  IL_0005:  stloc.1
  IL_0006:  ldloc.1
  IL_0007:  ldc.i4.s   10
  IL_0009:  stfld      int32 HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1'::seed
  IL_000e:  ldloc.1
  IL_000f:  ldftn      instance int32 HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1'::'&lt;GetFunc&gt;b__0'(int32)
  IL_0015:  newobj     instance void class [mscorlib]System.Func`2&lt;int32,int32&gt;::.ctor(object, native int)
  IL_001a:  stloc.0
  IL_001b:  ldloc.0
  IL_001c:  ldc.i4.s   10
  IL_001e:  callvirt   instance !1 class [mscorlib]System.Func`2&lt;int32,int32&gt;::Invoke(!0)
  IL_0023:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_0028:  ldloc.1
  IL_0029:  ldc.i4.s   20
  IL_002b:  stfld      int32 HowClosureWorks.Program/'&lt;&gt;c__DisplayClass1'::seed
  IL_0030:  ldloc.0
  IL_0031:  ldc.i4.s   15
  IL_0033:  callvirt   instance !1 class [mscorlib]System.Func`2&lt;int32,int32&gt;::Invoke(!0)
  IL_0038:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_003d:  ldloc.0
  IL_003e:  ret
} // end of method Program::GetFunc
</pre>
</pre>
</div>
<p>Para facilitar, poderíamos dizer que GetFunc, em C#, como foi gerado pelo compilador parece com o que segue:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:868c09d3-709f-453e-b448-fe3ad0d3c064" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static Func&lt;int, int&gt; GetFunc()
{
    var d = new c__DisplayClass1();
    d.seed = 10;
    Func&lt;int, int&gt; f = d.b__0;
    Console.WriteLine(f(10));

    d.seed = 20;
    Console.WriteLine(f(15));
    return f;
}
</pre>
</pre>
</div>
<p>Era isso!</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/intermediate-language/'>Intermediate Language</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2257/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2257&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/10/como-closures-funcionam-em-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb11.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb12.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Tail Recursion (em C#)</title>
		<link>http://elemarjr.net/2012/02/10/tail-recursion-em-c/</link>
		<comments>http://elemarjr.net/2012/02/10/tail-recursion-em-c/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 17:34:58 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Intermediate Language]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2239</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! Nesse post, mostro como implementar “Tail Recursions” em C#. Embora o compilador do C# quase não forneça suporte para “Tail Recursion Optimizations”, o JIT em 64 bits fornece. Logo, utilizar técnicas de codificação para “Tail Recursion” pode representar um incremento significativo de performance. Nesse post, além de C#, usaremos um pouco [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2239&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>Nesse post, mostro como implementar “Tail Recursions” em C#. </p>
<p>Embora o compilador do C# quase não forneça suporte para “Tail Recursion Optimizations”, o JIT em 64 bits fornece. Logo, utilizar técnicas de codificação para “Tail Recursion” pode representar um incremento significativo de performance.</p>
<p>Nesse post, além de C#, usaremos um pouco de F# e um pouco de Intermediate Language. </p>
<p>Se você está com vontade de aprender F#, recomendo seguir <a href="twitter.com/rodrigovidal">@rodrigovidal</a> e ler tudo o que ele&#160; escreve (o cara é MVP em F# [linguagem pure-functional wanna-be], da Microsoft). </p>
<p>Se você quiser aprender Intermediate Language (acho que todo desenvolvedor .NET deveria saber pelo menos o básico), recomendo dar uma olhada na série <a href="http://elemarjr.net/tag/il-101/">IL 101</a> (aqui mesmo no blog).</p>
<h2>O que é Tail Recursion?!</h2>
<p>Pegando a definição da Wikipedia:</p>
<blockquote><p>In <a href="http://en.wikipedia.org/wiki/Computer_science">computer science</a>, a <b>tail call</b> is a <a href="http://en.wikipedia.org/wiki/Subroutine">subroutine</a> call that happens inside another procedure and that produces a return value, which is then immediately <a href="http://en.wikipedia.org/wiki/Return_statement">returned</a> by the calling procedure. The <a href="http://en.wikipedia.org/wiki/Call_site">call site</a> is then said to be in <b>tail position</b>, i.e. at the end of the calling procedure. If a subroutine performs a tail call to itself, it is called <b>tail-recursive</b>. This is a special case of <a href="http://en.wikipedia.org/wiki/Recursion_(computer_science)">recursion</a>.</p>
</blockquote>
<p>Tentado explicar: Se você escreve um método recursivo, onde a última operação do método é a chamada para a recursão. Então, a recursão implemetada tem um tipo especial chamado Tail Recursion. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e35c03da-76e4-43ea-ba17-6d6122a1db75" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
public static void CountDown(int seed)
{
    if (seed == 0) return;
    CountDown(seed - 1);
}
</pre>
</pre>
</div>
<p>Por outro lado,</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:18b9ee88-99ff-4511-bd42-803627693ea7" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static int ComputeFactorial(int value)
{
    if (value == 0) return 1;
    return value*ComputeFactorial(value - 1);
}
</pre>
</pre>
</div>
<p>Esse método não tem “Tail Recursion” já que executa operações <strong>depois</strong> da chamada para recursão.</p>
<h2>Por que Tail Recursion é importante!?</h2>
<p>Funções que implementam “Tail Recursion” suportam um tipo especial de otimização (Tail Recursion Optimization). </p>
<p>Como o “estado” (variáveis internas e call stack) da função evocadora não é relevante para a continuidade do programa, o compilador pode “descartar” essa informação e evitar o “terrível” <a href="http://msdn.microsoft.com/pt-br/library/system.stackoverflowexception.aspx">StackOverflowException</a>.</p>
<p>Além disso, como o sistema fica “aliviado” da responsabilidade de manter o call stack e estado das funções, há um evidente ganho de performance (tanto em memória quanto em tempo de processamento).</p>
<h2>Tail Recursion Optimization depende do compilador</h2>
<p>Quando implementamos uma “Tail Recursion” fazemos a nossa parte para que não ocorram “Stack Overflow Exceptions” e para que tenhamos uma performance superior. Entretanto, o compilador precisa fazer a parte dele. Infelizmente, esse <strong>nem sempre</strong> é o caso do C#.</p>
<p>Observe a seguinte implementação em F# (Olha só, <a href="http://twitter.com/rodrigovidal">@rodrigovidal</a>):</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:047796cf-4d7b-481f-8452-c8420c04c3a6" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: fsharp; pad-line-numbers: true;">
let n = 1000000

let rec countdown n =
    match n with
    | 0 -&gt; ()
    | _ -&gt; countdown (n-1)

countdown n
printfn &quot;Done&quot;
</pre>
</pre>
</div>
<p>A função <em>countdown</em>, em Intermediate Language, gerada pelo compilador do F# ficou assim (Não sabe IL? Que tal dar uma olhada <a href="http://elemarjr.net/tag/il-101/">nessa série</a>):</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f4dd12fe-ce7f-4125-86dd-d6204a4be0ed" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: plain;">
.method public static void  countdown(int32 n) cil managed
{
  // Code size       21 (0x15)
  .maxstack  4
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  switch     ( 
                        IL_000d)
  IL_000b:  br.s       IL_000e
  IL_000d:  ret
  IL_000e:  ldarg.0
  IL_000f:  ldc.i4.1
  IL_0010:  sub
  IL_0011:  starg.s    n
  IL_0013:  br.s       IL_0000
} // end of method Program::countdown
</pre>
</pre>
</div>
<p>O que, em C#, ficaria assim:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:01a3381b-349b-4055-b1ee-486ef4f11d5b" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static void countdown(int n)
{
    while (true)
    {
        switch (n)
        {
            case 0:
                goto label_1;
            default:
                --n;
                continue;
        }
    }
label_1: ;
}
</pre>
</pre>
</div>
<p>Ou seja, o compilador do F# reconheceu a “tail recursion” e a eliminou do IL integralmente. Esse código tem performance superior e nunca dispara “Stack Overflow Exception”.</p>
<p>Agora, a versão em C#:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:47dd945b-d247-4c85-a219-f6c85d821277" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion
{
    internal class Program
    {

        public static void CountDown(int seed)
        {
            if (seed == 0) return;
            CountDown(seed - 1);
        }

        private static void Main()
        {
            CountDown(1.Million());
            Console.WriteLine(&quot;done!&quot;);
        }
    }

    internal static class IntExtensions
    {
        public static int Million(this int value)
        {
            return value * 1000 * 1000;
        }
    }
}
</pre>
</pre>
</div>
<p>Perceba que também temos um “Tail Recursion” aqui. Entretanto, o IL gerado para a função <strong><em>CountDown</em></strong> fica assim (mais uma vez, considere <a href="http://elemarjr.net/tag/il-101/">aprender IL</a>):</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:85487885-2d2a-451d-bc2e-5887f7578b86" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
.method public hidebysig static void  CountDown(int32 seed) cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_0004
  IL_0003:  ret
  IL_0004:  ldarg.0
  IL_0005:  ldc.i4.1
  IL_0006:  sub
  IL_0007:  call       void TailRecursion.Program::CountDown(int32)
  IL_000c:  ret
} // end of method Program::CountDown
</pre>
</pre>
</div>
<p><font color="#ff0000">Como pode ver, o compilador não “removeu” a recursão. <strong>Isso quer dizer que esse código PODE resultar “Stack Overflow Exception” e ter performance inferior. </strong></font></p>
<p><font color="#ff0000">Não há certeza do resultado porque o JIT (que converte IL para código nativo) PODE implementar a otimização.</font></p>
<blockquote>
<p>Atualmente o JIT (Just-in-time compiler), em sua versão 64 bits, implementa a “Tail Recursion Optimization”. Entretanto, a versão 32 bits não implementa. Ou seja, Stack Overflow Exception ocorrerá apenas em programas que sejam processados pela versão 32 bits do JIT.</p>
</blockquote>
<p>Essa condição, espero eu, deverá mudar nas futuras implementações do C# e/ou JIT.</p>
<blockquote>
<p>Importante destacar que Intermediate Language possui um opcode especial para tratar tail recursion (curiosamente, Tail). Infelizmente, esse opcode só é “emitido” pelo compilador do F#. O compilador do C# não faz uso desse recurso.</p>
</blockquote>
<p>De qualquer forma, sempre que possível, devemos implementar “Tail Recursion”. Quando houver otimização, os resultados serão muito bons.</p>
<h2>Implementando “Accumulator Passing Style” Tail Recursion</h2>
<p>Considere a seguinte implementação para calcular o fatorial de um número (Lembrando 5! = 5 * 4 * 3 * 2 * 1 = 120).</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:68a0dd79-97dd-4b16-8841-3169a61f1a57" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static int ComputeFactorial(int value)
{
    if (value == 0) return 1;
    return value*ComputeFactorial(value - 1);
}
</pre>
</pre>
</div>
<p>Essa implementação não é “Tail Recursion”, pois a última operação não é a chamada para recursão. </p>
<p>Uma forma de modificar isso é implementando um acumulador. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:406dcd3f-7ee4-4fed-9057-c730eac05e74" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static int ComputeFactorial(int value, int accumulator = 1)
{
    if (value == 0) return accumulator;
    return ComputeFactorial(value - 1, value * accumulator);
}
</pre>
</pre>
</div>
<p>Essa implementação é “Tail Recursion” pois a chamada para a recursão é a última operação realizada.</p>
<p>Perceba:</p>
<ul>
<li>a assinatura da função foi modificada para incluir um parametro adicional (<em>accumulator</em>); </li>
<li>esse parâmetro, de certa forma, subsitui o valor de retorno. Em cada iteração, o acumulador contém o fatorial calculado até aquele ponto; </li>
<li>enquanto o contador não chega a zero, o acumulador é atualizado e uma nova chamada a recursão é executada; </li>
<li>em determinado momento, o contador chega a zero, e o valor do acumulador é retornado como resultado. </li>
</ul>
<p>Podemos remover o inconveniente da mudança da assinatura usando lambda expressions. Perceba:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2a5e0d66-84e0-47e5-89b7-0edabcf6c451" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static int ComputeFactorial(int value)
{
    Func&lt;int, int, int&gt; @worker = null;
    @worker = (v, a) =&gt; v == 0 ? a : @worker(v - 1, v * a);
    return @worker(value, 1);
}
</pre>
</pre>
</div>
<p>Basicamente, mudamos a recursão de lugar. A lambda <em>@worker</em> é “tail recursive”.</p>
<blockquote>
<p>O segredo para criar expressões lambdas recursivas está na atribuição inicial para <strong><em>null</em></strong></p>
</blockquote>
<h2>Implementando “Continuation Passing Style” Tail Recursion</h2>
<p>Continuation Passing Style é mais uma estratégia para implantação de algoritmos com “Tail Recursion”. </p>
<p>Como não é tão “fácil de pegar”, vamos tentar construir alguma fundamentação. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cbc81d2c-b374-4245-8630-fe9b2d18c97a" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion.CPS
{
    internal class Program
    {
        public static int Add(int a, int b)
        {
            return a + b;
        }

        public static int Mult(int a, int b)
        {
            return a*b;
        }

        static void Main()
        {
            Console.WriteLine(Mult(3, Add(5,2)));
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Nessa sequência ingênua de código temos algo plenamente intuitivo sob a perspectiva matemática. Mas, pouco intuitiva para linguagens imperativas sequênciais. Os trechos mais internos (innermost) da linha que imprime o resultado são calculados antes dos trechos mais externos (outermost). Ou seja:</p>
<ol>
<li><strong>Add</strong> é chamado com parâmetros 5 e 2; </li>
<li><strong>Mult</strong> é chamado com 3 e o resultado da adição; </li>
<li><strong>WriteLine</strong> é chamado com resultado da multiplicação. </li>
</ol>
<p>Continuation Passing Style habilita que façamos um código “sequencialmente” mais intuitivo. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:89beb4e7-3c1d-4942-bb0f-eb07d270f76c" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion.CPS
{
    internal class Program
    {
        public static void Add(int a, int b, Action&lt;int&gt; continuation)
        {
            continuation( a + b );
        }

        public static void Mult(int a, int b, Action&lt;int&gt; continuation)
        {
            continuation( a * b );
        }

        static void Main()
        {
            Add(5, 2, (x)
                      =&gt; Mult(x, 3, Console.WriteLine)
                );
 
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Repare como “invertemos” o código. </p>
<p>Agora, voltando ao exemplo do cálculo do fatorial, usando CPS.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:197a909d-025a-4541-af9d-48c5860626e8" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion.CPS
{
    internal class Program
    {
        public static void ComputeFactorial(int value, Action&lt;int&gt; continuation)
        {
            if (value == 0)
                continuation(1);
            else
                ComputeFactorial(value - 1, x =&gt; continuation(value * x));
        }

        static void Main()
        {
            ComputeFactorial(5, Console.WriteLine);
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>O que fizemos?</p>
<ul>
<li>Alteramos a assinatura do nosso método para que ele aceitasse um continuation; </li>
<li>Inicialmente, passamos um “WriteLine”; </li>
<li>Nossa função verifica se o contador chegou a zero.
<ul>
<li>Em caso positivo, executa o continuation; </li>
<li>Em caso negativo, ativa uma “Tail call” com o contador decrementado e uma versão diferente do continuation. </li>
</ul>
</li>
</ul>
<p>E temos mais uma versão com Tail Recursion.</p>
<p>Agora, vamos implementar uma versão modificada, mais conveniente, onde nossa função retorna um valor no lugar de simplesmente processar um continuation. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7cdcaf0b-6114-4e0b-837f-0a92970a641f" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion.CPS
{
    internal class Program
    {
        public static int ComputeFactorial(int value, Func&lt;int, int&gt; continuation)
        {
            return (value == 0) ? continuation(1) : 
                ComputeFactorial(value - 1, x =&gt; continuation(value * x));
        }

        static void Main()
        {
            Console.WriteLine(ComputeFactorial(5, x =&gt; x));
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>O inconveniente dessa implementação é a obrigatoriedade da passagem de uma função de continuation burra. Vamos eliminar isso?!</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0ad668f7-c332-4896-b7da-e5cbcf9eeb92" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace TailRecursion.CPS
{
    internal class Program
    {
        public static int ComputeFactorial(int value)
        {
            Func&lt;int, Func&lt;int, int&gt;, int&gt; @worker = null;
            
            @worker = (v, c) =&gt; (v == 0) ? c(1) : 
                @worker(v - 1, x =&gt; c(v * x));

            return @worker(value, x =&gt; x);
        }

        static void Main()
        {
            Console.WriteLine(ComputeFactorial(5));
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Lindo, não?!</p>
<p>Era isso!</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/functional-programming/'>Functional Programming</a>, <a href='http://elemarjr.net/tag/intermediate-language/'>Intermediate Language</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2239/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2239/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2239/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2239&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/10/tail-recursion-em-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>
	</item>
		<item>
		<title>Tornando o c&#243;digo mais elegante com &#8220;Currying&#8221; e &#8220;Partial Application&#8221; (em C#)</title>
		<link>http://elemarjr.net/2012/02/09/tornando-o-cdigo-mais-elegante-com-currying-e-partial-application-em-c/</link>
		<comments>http://elemarjr.net/2012/02/09/tornando-o-cdigo-mais-elegante-com-currying-e-partial-application-em-c/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 21:02:49 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Functional Programming]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2236</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! Fundamentalmente, programação funcional trata da aplicação de funções e suas combinações para algoritmos mais complexos. Outro dia, mostrei como “combinar” funções usando uma técnica chamada “Combinators” (veja o post). Hoje, mostro como decompor funções complexas usando uma ténica chamada “Currying” para, depois disso, criar composições mais inteligentes através de uma técnica [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2236&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>Fundamentalmente, programação funcional trata da aplicação de funções e suas combinações para algoritmos mais complexos.</p>
<p>Outro dia, mostrei como “combinar” funções usando uma técnica chamada “Combinators” (<a href="http://elemarjr.net/2012/01/05/produzindo-codigo-mais-elegante-com-combinators-em-c/">veja o post</a>). Hoje, mostro como decompor funções complexas usando uma ténica chamada “Currying” para, depois disso, criar composições mais inteligentes através de uma técnica chamada “Partial Application”.</p>
<p>Este é um post com bastante código (ao gosto do meu amigo <a href="http://twitter.com/juanplopes">@juanplopes</a>)</p>
<p>Você sabe, C# não é (nem pretende ser) uma linguagem puramente funcional (Aliás, F# também não é [desculpa aí, <a href="twitter.com/rodrigovidal">@rodrigovidal</a>]!). Mesmo assim, algumas técnicas desse paradigma conseguem deixar nosso código bem mais elegante.</p>
<h2>Currying 101</h2>
<p>Currying é uma técnica onde começamos com uma função com múltiplos parâmetros e a convertemos em uma sequência de funções, em cadeia, com apenas um parâmetro cada.</p>
<p>Observe esse exemplo convencional:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b82b348d-5697-422e-bf65-2adfa5d6b9f3" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Func&lt;int, int, int&gt; add = (a, b) =&gt; a + b;
            Console.WriteLine(add(2, 5));
        }
    }
}
</pre>
</pre>
</div>
<p>Como você pode ver, definimos uma função de soma simples que aceita dois parâmetros. Aplicar currying&#160; nesse cenário implica em definir uma função que aceite apenas um parâmetro, retorne outra função que espere o segundo parâmetro, para, enfim, retornar o resultado da adição. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cb311edb-2581-4a39-b8a7-d46a459fb64b" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Func&lt;int, Func&lt;int, int&gt;&gt; add = a =&gt; b =&gt; a + b;
            Console.WriteLine(add(2)(5));
        }
    }
}
</pre>
</pre>
</div>
<p>Perceba como o tipo da função mudou de <strong><em>Func&lt;int, int, int&gt; </em></strong>para <strong><em>Func&lt;int, Func&lt;int, int&gt;&gt;</em></strong>. Como a função interna (inner) utiliza o parâmetro <strong><em>a</em></strong> que é uma variável da função externa (outer), c compilador cria uma closure para essa variável.</p>
<p>Perceba que essa técnica pode ser aplicada independente da quantidade de parâmetros.</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0aba2539-3bd5-42cc-8d0e-2df0631fc26f" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Func&lt;int, Func&lt;int, Func&lt;int, int&gt;&gt;&gt; add = a =&gt; b =&gt; c =&gt; a + b + c;
            Console.WriteLine(add(2)(5)(7));
        }
    }
}
</pre>
</pre>
</div>
<h2>Facilitando as coisas…</h2>
<p>Embora o conceito seja bastante simples, pode ser tedioso (e fácil de errar) escrever funções com currying. Além disso, podemos querer aplicar a técnica em funções já implementadas. Por isso, é bom pensar em escrever algum código de ajuda. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b0595b61-c18e-4a86-a0a6-f60d64b587bc" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Func&lt;int, int, int&gt; add = (a, b) =&gt; a + b;
            var curriedAdd = add.Curry();

            Console.WriteLine(&quot;Add result for 2, 2 is: {0}&quot;, add(2,2));
            Console.WriteLine(&quot;Curried Add result for 2, 2 is: {0}&quot;, curriedAdd(2)(2));

        }
    }

    public static class FunctionalExtensions
    {
        public static Func&lt;T1, Func&lt;T2, TResult&gt;&gt; 
            Curry&lt;T1, T2, TResult&gt;(this Func&lt;T1, T2, TResult&gt; func)
        {
            return a =&gt; b =&gt; func(a, b);
        }

        public static Func&lt;T1, Func&lt;T2, Func&lt;T3, TResult&gt;&gt;&gt;
            Curry&lt;T1, T2, T3, TResult&gt;(this Func&lt;T1, T2, T3, TResult&gt; func)
        {
            return a =&gt; b =&gt; c =&gt; func(a, b, c);
        }

        public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Func&lt;T4, TResult&gt;&gt;&gt;&gt;
            Curry&lt;T1, T2, T3, T4, TResult&gt;(this Func&lt;T1, T2, T3, T4, TResult&gt; func)
        {
            return a =&gt; b =&gt; c =&gt; d =&gt; func(a, b, c, d);
        }

        public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Func&lt;T4, Func&lt;T5, TResult&gt;&gt;&gt;&gt;&gt;
            Curry&lt;T1, T2, T3, T4, T5, TResult&gt;(this Func&lt;T1, T2, T3, T4, T5, TResult&gt; func)
        {
            return a =&gt; b =&gt; c =&gt; d =&gt; e =&gt; func(a, b, c, d, e);
        }
    }
}
</pre>
</pre>
</div>
<h2>Usando Currying em classes</h2>
<p>Até aqui, utilizamos Currying apenas em algumas expressões lambdas dentro de um escopo de função. Entretanto, nada nos impede de que façamos uso destas em classes. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6bbc7fea-62dc-463e-ab97-7e811f1f905c" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Console.WriteLine(&quot;Add result for 2, 2 is: {0}&quot;, 
                Calculator.Add(2,2));
            Console.WriteLine(&quot;Curried Add result for 2, 2 is: {0}&quot;, 
                Calculator.AddC(2)(2));
        }
    }

    public static class Calculator
    {
        public static readonly Func&lt;int, int, int&gt;
            Add = (a, b) =&gt; a + b;

        public static readonly Func&lt;int, Func&lt;int, int&gt;&gt;
            AddC = Add.Curry();

        public static readonly Func&lt;int, int, int&gt;
            Mult = (a, b) =&gt; a * b;

        public static readonly Func&lt;int, Func&lt;int, int&gt;&gt;
            MultC = Mult.Curry();
    }

    public static class FunctionalExtensions
    {
        /* .. */
    }
}
</pre>
</pre>
</div>
<h2>Mas, afinal, por que usar Currying?</h2>
<p>A principal razão para utilização de currying é tornar possível chamar uma função com apenas alguns (e não todos) parâmetros que esta precisa para funcionar. Em outras palavras, Currying autoriza a utilização de uma ténica chamada “Partial Application”</p>
<p>Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6059b37c-6ffa-4d11-9fbf-29fdc67263ed" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
private static void Main()
{
    Func&lt;int, int, int&gt; add = (a, b) =&gt; a + b;
    var addC = add.Curry();
    var add5 = addC(5);
    Console.WriteLine(&quot;The result of 5 + 17 is {0}&quot;, add5(17));
}
</pre>
</pre>
</div>
<p>Perceba:</p>
<ol>
<li>construímos uma função de soma simples (variável add); </li>
<li>usando os helpers que já definimos, criamos uma “curried version” dessa função (variável addC); </li>
<li>chamamos a “curried version” de nossa versão passando apenas o valor (5) de um parâmetro (variável add5); </li>
<li>o “retorno” armazenado da “curried version” é uma função que poderá ser chamada quantas vezes desejarmos; </li>
</ol>
<h2>Entendendo Partial Application</h2>
<p>Utilizar “Partial Application” permite que criemos uma nova função com base em uma existente. Geralmente, partimos de uma função mais genérica para criar uma função com aplicação mais expecífica.</p>
<p>No exemplo que mostrei acima, tinhamos uma função “genérica” de soma que aceitava dois inteiros. Toda vez que ela fosse chamada aceitaria um novo par de parâmetros e devolveria o resultado. Criamos uma função mais específica para restringir a aplicação a um domínio bem mais restrito de entradas.</p>
<h2>Currying Actions</h2>
<p>Da mesma forma que “generalizamos” currying para Func, podemos generalizar Actions. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:80b23601-e6a9-4d67-a034-e02729263480" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
public static class FunctionalExtensions
{
    /* .. */

    public static Func&lt;T1, Action&lt;T2&gt;&gt;
        Curry&lt;T1, T2&gt;(this Action&lt;T1, T2&gt; action)
    {
        return a =&gt; b =&gt; action(a, b);
    }

    public static Func&lt;T1, Func&lt;T2, Action&lt;T3&gt;&gt;&gt;
        Curry&lt;T1, T2, T3&gt;(this Action&lt;T1, T2, T3&gt; action)
    {
        return a =&gt; b =&gt; c =&gt; action(a, b, c);
    }

    public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Action&lt;T4&gt;&gt;&gt;&gt;
        Curry&lt;T1, T2, T3, T4&gt;(this Action&lt;T1, T2, T3, T4&gt; action)
    {
        return a =&gt; b =&gt; c =&gt; d =&gt; action(a, b, c, d);
    }

    public static Func&lt;T1, Func&lt;T2, Func&lt;T3, Func&lt;T4, Action&lt;T5&gt;&gt;&gt;&gt;&gt;
        Curry&lt;T1, T2, T3, T4, T5&gt;(this Action&lt;T1, T2, T3, T4, T5&gt; action)
    {
        return a =&gt; b =&gt; c =&gt; d =&gt; e =&gt; action(a, b, c, d, e);
    }
}
</pre>
</pre>
</div>
<p>Assim, podemos escrever código assim:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fe5aa726-4985-43dd-8b2d-05aa90321f31" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;

namespace FunctionalProgramming
{
    internal class Program
    {
        private static void Main()
        {
            Console.Title = &quot;Having fun with Currying&quot;;

            Action&lt;string, string&gt; print = Console.WriteLine;
            var printC = print.Curry();
            var printAlert = printC(&quot;ALERT: {0}&quot;);

            printAlert(&quot;Hello World&quot;);
            printAlert(&quot;This is the second alert&quot;);
            printAlert(&quot;This is the third alert&quot;);
            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Executando …</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image10.png"><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb10.png?w=533&#038;h=271" width="533" height="271" /></a></p>
<p>Era isso.</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/functional-programming/'>Functional Programming</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2236/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2236/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2236/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2236&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/09/tornando-o-cdigo-mais-elegante-com-currying-e-partial-application-em-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb10.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>Conhecendo o Microsoft &#8220;Roslyn&#8221; CTP &#8211; Parte 2 &#8211;  Verificando o c&#243;digo (Linq To Code)</title>
		<link>http://elemarjr.net/2012/02/08/conhecendo-o-microsoft-roslyn-ctp-parte-2-verificando-o-cdigo-linq-to-code/</link>
		<comments>http://elemarjr.net/2012/02/08/conhecendo-o-microsoft-roslyn-ctp-parte-2-verificando-o-cdigo-linq-to-code/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 20:53:55 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[Roslyn]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2231</guid>
		<description><![CDATA[Olá pessoal. Tudo certo?! Nessa série, mostro os fundamentos do projeto Roslyn. Se está chegando agora, considere visitar o primeiro post (acho que vale a pena). Aqui, mostro como gerar e inspecionar uma árvore sintática de códigos em C#. O código que desejamos analisar Para demonstrar as funcionalidades do Roslyn, escrevi um arquivo com um [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2231&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo?!</p>
<p>Nessa série, mostro os fundamentos do projeto Roslyn. Se está chegando agora, considere visitar o <a href="http://elemarjr.net/2012/01/19/conhecendo-o-microsoft-roslyn-ctp-parte-1-criando-um-repl-para-c/">primeiro post</a> (acho que vale a pena).</p>
<p>Aqui, mostro como gerar e inspecionar uma árvore sintática de códigos em C#.</p>
<h2>O código que desejamos analisar</h2>
<p>Para demonstrar as funcionalidades do Roslyn, escrevi um arquivo com um código de exemplo. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f2c8622a-982d-4589-87d9-50562ca579bb" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
using System;
using System.Linq;

namespace Demo
{
	class demo
	{
		static void Main(string[] args)
		{
			Console.WriteLine(GetMessage());
		}
		
		static string GetMessage()
		{
			return "Hello World!";
		}		
	}
}
</pre>
</pre>
</div>
<h2>Percorrendo a árvore sintática</h2>
<p>Roslyn permite que “interpretemos” um código facilmente. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7889f33c-54dd-472a-823a-48f6f39ba41f" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;
using System.IO;

using Roslyn.Compilers.CSharp;

namespace RoslynSyntaxTree
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Roslyn SyntaxTree Demo";

            var source = File.ReadAllText("demo.txt");
            var tree = SyntaxTree.ParseCompilationUnit(source);

            var root = (CompilationUnitSyntax) tree.Root;

            foreach (var @using in root.Usings)
            {
                  Console.WriteLine("Using: {0}", @using.Name.GetText());
            }

            Console.WriteLine("\n");

            var @namespace = (NamespaceDeclarationSyntax) root.Members[0];
            Console.WriteLine("Namespace is {0}", @namespace.Name.GetText());

            var @type = (TypeDeclarationSyntax) @namespace.Members[0];
            Console.WriteLine("Type keyword is {0}; identifier {1}", 
                @type.Keyword.ToString().Trim(),
                @type.Identifier.GetText()
                );

            var @method = (MethodDeclarationSyntax) @type.Members[0];
            Console.WriteLine("First Method identifier is {0}", @method.Identifier);

            var @argument = @method.ParameterList.Parameters[0];
            Console.WriteLine("Argument identifier is {0}",
                @argument.TypeOpt.GetText());

            Console.WriteLine("Argument name is {0}",
                @argument.Identifier.GetText());
            
            Console.ReadLine();
        }
    }
}

</pre>
</pre>
</div>
<p>Como pode ver, submetemos um código-fonte para o Roslyn. Como resultado, recebemos a árvore sintática correspondente. O código que seguiu, apresenta alguns dados do código conforme essa árvore sintática.</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image8.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb8.png?w=582&#038;h=295" width="582" height="295" /></a></p>
<p>Perceba como os diversos elementos (nodos) da árvore sintática possuem tipos apropriados. Com o cast, conseguimos “especializar” a consulta.</p>
<h2>Linq To Code <img style="border-style:none;" class="wlEmoticon wlEmoticon-smile" alt="Alegre" src="http://elemarjr.files.wordpress.com/2012/02/wlemoticon-smile.png?w=594" /></h2>
<p>A árvore sintática gerada pelo Roslyn permite consultas feitas com Linq. Veja:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:698be1f4-e415-4448-9ee4-f724af328c63" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;
using System.IO;
using System.Linq;
using Roslyn.Compilers.CSharp;

namespace RoslynSyntaxTree
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.Title = "Roslyn SyntaxTree Demo";

            var source = File.ReadAllText("demo.txt");
            var tree = SyntaxTree.ParseCompilationUnit(source);
            var root = (CompilationUnitSyntax) tree.Root;

            Action print = Console.WriteLine;
            Action nl = () =&gt; print("\n");

            var methods = root.DescendentNodes()
                .OfType();
                          

            foreach (var method in methods)
                print(method.Identifier.GetText());

            nl();

            var methodsStartingWithM = from m in methods
                                       where m.Identifier.GetText().StartsWith("M")
                                       select m;

            foreach (var method in methodsStartingWithM)
                print(method.Identifier.GetText());

            Console.ReadLine();
        }
    }
}
</pre>
</pre>
</div>
<p>Executando,</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image9.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb9.png?w=582&#038;h=298" width="582" height="298" /></a></p>
<p>&#160;</p>
<p>Gostou?! </p>
<p>Era isso.</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/roslyn/'>Roslyn</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2231/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2231/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2231/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2231&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/08/conhecendo-o-microsoft-roslyn-ctp-parte-2-verificando-o-cdigo-linq-to-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb8.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/wlemoticon-smile.png" medium="image">
			<media:title type="html">Alegre</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb9.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>HTTP Caching e Conditional Get (Last-Modified e ETag) em ASP.net MVC 3</title>
		<link>http://elemarjr.net/2012/02/05/http-caching-e-conditional-get-last-modified-e-etag-em-asp-net-mvc-3/</link>
		<comments>http://elemarjr.net/2012/02/05/http-caching-e-conditional-get-last-modified-e-etag-em-asp-net-mvc-3/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 20:06:24 +0000</pubDate>
		<dc:creator>elemarjr</dc:creator>
				<category><![CDATA[Post]]></category>
		<category><![CDATA[AspNetMvc]]></category>
		<category><![CDATA[Caching]]></category>
		<category><![CDATA[HTTP]]></category>

		<guid isPermaLink="false">https://elemarjr.wordpress.com/?p=2224</guid>
		<description><![CDATA[Olá pessoal. Tudo certo!? Em um post anterior, mostrei como podemos usar o suporte de caching dos browsers para melhorar o desempenho de nossas aplicações. Naquele momento, mostrei como fazer a implementação “na unha”. Nesse post, mostro como implementar esse benefício utilizando ASP.net MVC 3. As coisas ficam um pouco mais fáceis. Caching simples Considere [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2224&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal. Tudo certo!?</p>
<p>Em um <a href="http://elemarjr.net/2012/02/03/melhorando-o-desempenho-de-aplicaes-web-com-http-caching-e-suporte-para-conditional-get-usando-c/">post anterior</a>, mostrei como podemos usar o suporte de caching dos browsers para melhorar o desempenho de nossas aplicações. Naquele momento, mostrei como fazer a implementação “na unha”.</p>
<p>Nesse post, mostro como implementar esse benefício utilizando ASP.net MVC 3. As coisas ficam um pouco mais fáceis.</p>
<h2>Caching simples</h2>
<p>Considere o seguinte controller:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:755c1959-972b-4a5f-9c5a-0de93b892951" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp; pad-line-numbers: true;">
using System;
using System.Globalization;
using System.Web.Mvc;

namespace ConditionalMVC.Controllers
{
    public class HomeController : Controller
    {
        public string Index()
        {
            return string.Format("Hello from ASP.net MVC {0}", 
                DateTime.Now.ToString(CultureInfo.InvariantCulture));
        }
    }
}
</pre>
</pre>
</div>
<p>Basicamente, estamos gerando um retorno dinâmico. Executando a aplicação e atualizando o Browser, percebemos que um request é feito a cada atualização.</p>
<p>Vejamos como é o retorno HTTP provido pela infraestrutura do ASP.net.</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image6.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb6.png?w=434&#038;h=174" width="434" height="174" /></a></p>
<p>Nada de especial. Agora, vamos solicitar algum caching. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:089f56f4-477e-4ab7-8139-f1034e94488a" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;
using System.Globalization;
using System.Web.Mvc;

namespace ConditionalMVC.Controllers
{
    [OutputCache(Duration = 10)]
    public class HomeController : Controller
    {
        public string Index()
        {
            return string.Format("Hello from ASP.net MVC {0}", 
                DateTime.Now.ToString(CultureInfo.InvariantCulture));
        }
    }
}
</pre>
</pre>
</div>
<p>O atributo <strong><em>OutputCache </em></strong>indica que clientes não devem nos “importunar” em intervalos inferiores ao especificado na duração (em segundos). Vejamos o que isso muda na resposta para o browser.</p>
<p><a href="http://elemarjr.files.wordpress.com/2012/02/image7.png"><img style="background-image:none;border-bottom:0;border-left:0;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;border-top:0;margin-right:auto;border-right:0;padding-top:0;" title="image" border="0" alt="image" src="http://elemarjr.files.wordpress.com/2012/02/image_thumb7.png?w=434&#038;h=174" width="434" height="174" /></a></p>
<p>Veja a adição dos atributos <strong><em>Expires </em></strong>e <strong><em>Last-Modified</em></strong> ! São os heróis que vimos no post anterior.</p>
<p>Bacana!</p>
<h2>Evitando processamento desnecessário com Last-Modified field</h2>
<p>Digamos que você saiba, exatamente, quando seu conteúdo dinâmico resultará algo diferente do que já foi “enviado” ao browser! Pois bem, nesses cenários, você pode evitar o “reprocessamento” devolvendo o status 304 para o cliente (assim, ele entenderá que o conteúdo em Cache continua válido). Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7ce2d879-a9c8-4df3-b550-768706567f5c" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;
using System.Globalization;
using System.Web.Mvc;

namespace ConditionalMVC.Controllers
{
    public class HomeController : Controller
    {
        private static int _dummyCounter = 0;
        private static DateTime _lastModified;

        static void Update()
        {
            _dummyCounter++;
            if ((_dummyCounter % 5) == 0)
            {
                _lastModified = DateTime.Now;
                _lastModified = new DateTime(
                    _lastModified.Year, _lastModified.Month, _lastModified.Day,
                    _lastModified.Hour, _lastModified.Minute, _lastModified.Second
                    );
            }
        }

        static HomeController()
        {
            _lastModified = DateTime.Now;
        }

        public string Index()
        {
            Update();
            var response = HttpContext.Response;
            var request = HttpContext.Request;

            var incomingDate = request.Headers["If-Modified-Since"];

            response.Cache.SetLastModified(_lastModified);

            DateTime testDate;
            if (
                DateTime.TryParse(incomingDate, out testDate) &amp;&amp; 
                testDate == _lastModified
                )
            {
                response.ClearContent();
                response.StatusCode = 304;
                response.SuppressContent = true;
                return null;
            }

            return string.Format("Hello from ASP.net MVC {0}", 
                DateTime.Now.ToString(CultureInfo.InvariantCulture));
        }
    }
}
</pre>
</pre>
</div>
<p>Pegou a idéia?! Apenas para fins de ilustração, assumo que “meu conteúdo” deve mudar a cada 5 requests. Obviamente, a lógica que você aplicaria em seu sistema poderia ser outro (envolvendo consulta a última data de modificação de uma tabela em um banco de dados, por exemplo).</p>
<h2>Evitando processamento desnecessário com ETag field</h2>
<p>Algumas vezes, fica mais fácil determinar modificações através de um hash do conteúdo, em lugar de uma “data de validade”. Observe:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ff28e09c-5cf6-4338-8214-29d196693989" class="wlWriterEditableSmartContent">
<pre style="white-space:normal;">
<pre class="brush: csharp;">
using System;
using System.Globalization;
using System.Web.Mvc;

namespace ConditionalMVC.Controllers
{
    public class HomeController : Controller
    {
        static int _dummyCounter = 0;
        static string _lastHash;
        static string _content;

        static void Update()
        {
            if ((_dummyCounter++ % 5) == 0)
            {
                _content = string.Format("Hello from ASP.net MVC {0}", 
                    DateTime.Now.ToString(CultureInfo.InvariantCulture));
                _lastHash = Guid.NewGuid().ToString();
            }
        }

        public string Index()
        {
            Update();
            var response = HttpContext.Response;
            var request = HttpContext.Request;

            response.Cache.SetETag(_lastHash);

            var incomingHash = request.Headers["If-None-Match"];

            if (
                incomingHash == _lastHash
                )
            {
                response.ClearContent();
                response.StatusCode = 304;
                response.SuppressContent = true;
                return null;
            }

            return _content;
        }
    }
}
</pre>
</pre>
</div>
<p>Neste exemplo, “gero” um conteúdo novo a cada 5 requests. Atribuo um hash ao ETag e, depois, em cada request, verifico se o hash permanece adequado ao&#160; “conteúdo atual”.</p>
<p>Bela alternativa.</p>
<p>Era isso!</p>
<br /> Tagged: <a href='http://elemarjr.net/tag/aspnetmvc/'>AspNetMvc</a>, <a href='http://elemarjr.net/tag/caching/'>Caching</a>, <a href='http://elemarjr.net/tag/http/'>HTTP</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/elemarjr.wordpress.com/2224/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/elemarjr.wordpress.com/2224/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/elemarjr.wordpress.com/2224/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=elemarjr.net&amp;blog=14656382&amp;post=2224&amp;subd=elemarjr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://elemarjr.net/2012/02/05/http-caching-e-conditional-get-last-modified-e-etag-em-asp-net-mvc-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/784c5d06fca162d5fc3fbe59e25e5180?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">elemarjr</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb6.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://elemarjr.files.wordpress.com/2012/02/image_thumb7.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
	</channel>
</rss>
