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

<channel>
	<title>DestaqueBlog &#187; clojure</title>
	<atom:link href="http://weblog.destaquenet.com/tag/clojure/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Emacs e Slime: Seu Laboratório Lisp</title>
		<link>http://weblog.destaquenet.com/2010/11/18/emacs-e-slime-seu-laboratorio-lisp/</link>
		<comments>http://weblog.destaquenet.com/2010/11/18/emacs-e-slime-seu-laboratorio-lisp/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 12:50:40 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[slime]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1175</guid>
		<description><![CDATA[Esse post vai para quem está estudando Clojure (ou outro Lisp qualquer) e está tendo dificuldades para configurar o Emacs. Não é, Ronaldo?! Esteja preparado para uma enorme quantidade de gambiarras. ELPA A primeira coisa que faço numa nova instalação &#8230; <a href="http://weblog.destaquenet.com/2010/11/18/emacs-e-slime-seu-laboratorio-lisp/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Esse post vai para quem está estudando <a href="http://clojure.org">Clojure</a> (ou outro <a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a> qualquer) e está tendo dificuldades para configurar o <a href="http://www.gnu.org/software/emacs/">Emacs</a>. Não é, <a href="http://twitter.com/rferraz">Ronaldo</a>?! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Esteja preparado para uma enorme quantidade de gambiarras.</p>
<h3>ELPA</h3>
<p>A primeira coisa que faço numa nova instalação do Emacs é configurar o <a href="http://tromey.com/elpa">ELPA</a>, ou <em>Emacs Lisp Package Archive</em>. Para quem não conhece, pense no ELPA como se fosse um <code>apt-get</code> da vida, guardadas as devidas proporções (como veremos a seguir).</p>
<p>As instruções para instalação podem ser vistas <a href="http://tromey.com/elpa/install.html">nesta página</a>. Se tudo der certo, agora deve ser possível rodar o comando <code>M-x package-list-packages &lt;ENTER&gt;</code>. Leia <a href="http://sean.wenzel.net/docs/emacs/quick_reference/">este documento</a> caso tenha dificuldades para usar atalhos e comandos do Emacs.</p>
<p>Após alguns instantes, a lista de pacotes disponíveis para instalação via ELPA deve ser exibida num buffer secundário.</p>
<p><span id="more-1175"></span></p>
<h3>Clojure-Mode</h3>
<p>Coloque o cursor sobre a linha do pacote <code>swank-clojure</code> e pressione a tecla <code>I</code> para marcá-lo para instalação. Faça o mesmo com o pacote <a href="http://www.emacswiki.org/ParEdit"><code>paredit</code></a>. Se outros pacotes foram marcados acidentalmente, mova o cursor para as linhas correspondentes e pressione <code>U</code> para desfazer a marcação. Pressione <code>X</code> para prosseguir com a instalação.</p>
<p>Feito isso, ao rodar o comando <code>M-x slime &lt;ENTER&gt;</code>, o Emacs irá perguntar se você deseja que ele faça o download dos JARs de Clojure. Não adianta dizer que sim, pois não irá funcionar. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>Para resolver isso, baixe manualmente os <a href="http://clojure.org/downloads">JARs de Clojure</a> e os coloque no diretório <code>~/.clojure/</code>. Em seguida, baixe o <a href="http://clojars.org/repo/swank-clojure/swank-clojure/">JAR mais recente</a> projeto <a href="https://github.com/technomancy/swank-clojure">swank-clojure</a> e o coloque no diretório <code>~/.swank-clojure/</code>.</p>
<p>Pronto. Reinicie o Emacs e rode o comando <code>M-x slime &lt;ENTER&gt;</code> para iniciar um REPL Clojure dentro do Emacs!</p>
<div id="attachment_1363" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2010/11/clj-repl.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2010/11/clj-repl-300x168.png" alt="REPL Clojure" title="clj-repl" width="300" height="168" class="size-medium wp-image-1363" /></a><p class="wp-caption-text">Clojure no Emacs Slime</p></div>
<p>Vale lembrar que o Slime fornece vários recursos para edição de código, como auto-completion, exibição de docstrings, entre outras coisas. Consulte o <a href="http://common-lisp.net/project/slime/">site do projeto</a> para mais informações.</p>
<h3>Outros Lisps</h3>
<p>Rode o comando abaixo para instalar duas das principais implementações open source do ANSI Common Lisp, <a href="http://www.gnu.org/software/clisp">CLISP</a> e <a href="http://www.sbcl.org/">SBCL</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> clisp sbcl</pre></div></div>

<p>Finalmente, abra o arquivo <code>~/.emacs</code> e cole o código a seguir na última linha:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; paredit + lisp modes</span>
<span style="color: #66cc66;">&#40;</span>defvar *lisp-modes* '<span style="color: #66cc66;">&#40;</span>clojure-mode-hook lisp-mode-hook emacs-lisp-mode-hook
                       lisp-interaction-mode-hook slime-repl-mode-hook<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; config used in all lisp modes</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> lisp-config <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>paredit-mode t<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>show-paren-mode t<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>mode<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>add-hook mode 'lisp-config<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *lisp-modes*<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; other lisp implementations</span>
<span style="color: #66cc66;">&#40;</span>eval-after-load <span style="color: #ff0000;">&quot;slime&quot;</span>
  '<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> slime-lisp-implementations
                '<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sbcl <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/usr/bin/sbcl&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                  <span style="color: #66cc66;">&#40;</span>clisp <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/usr/bin/clisp&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Swank</h3>
<p>As últimas versões do Slime já trazem servidores Swank para diversas implementações Lisp, mas curiosamente essa parte do código não é baixada quando se instala o Slime via ELPA.</p>
<p>Certifique-se de que um cliente CVS esteja instalado e rode o comando abaixo para fazer o download da última versão do Slime:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cvs</span> <span style="color: #660033;">-d</span> :pserver:anonymous:anonymous<span style="color: #000000; font-weight: bold;">@</span>common-lisp.net:<span style="color: #000000; font-weight: bold;">/</span>project<span style="color: #000000; font-weight: bold;">/</span>slime<span style="color: #000000; font-weight: bold;">/</span>cvsroot <span style="color: #c20cb9; font-weight: bold;">co</span> slime</pre></div></div>

<p>Em seguida, vá até o diretório <code>slime</code> recém-criado e copie todos os arquivos deste diretório por cima dos arquivos instalados via ELPA em <code>~/.emacs.d/elpa/slime-&lt;VERSION&gt;</code>. Aproveite e remova o arquivo <code>slime.elc</code> deste último diretório, já que tal arquivo é uma versão compilada de um arquivo que acabamos de sobrescrever.</p>
<p>Reinicie o Emacs. O comando <code>M-x slime &lt;ENTER&gt;</code> continua servindo para iniciar um REPL Clojure. Para iniciar um REPL SBCL, por exemplo, rode o comando <code>M-- M-x slime &lt;ENTER&gt;</code>, digite <code>sbcl</code> e pressione <code>&lt;ENTER&gt;</code>.</p>
<div id="attachment_1364" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2010/11/sbcl-repl.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2010/11/sbcl-repl-300x168.png" alt="REPL SBCL" title="sbcl-repl" width="300" height="168" class="size-medium wp-image-1364" /></a><p class="wp-caption-text">SBCL no Emacs Slime</p></div>
<h4><em>&#8220;Nunca vi tanta gambiarra num lugar só&#8230;&#8221;</em></h4>
<p>Tudo seria mais fácil se o ELPA disponibilizasse versões minimamente atualizadas &#8212; e não-&#8221;capadas&#8221; &#8212; de certos pacotes, por isso creio que essa complicação deva ser temporária. Atualizarei este texto quando a coisa mudar. Para melhor, espero.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/11/18/emacs-e-slime-seu-laboratorio-lisp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Emacs and Slime: Your Lisp Lab</title>
		<link>http://weblog.destaquenet.com/2010/11/18/emacs-and-slime-your-lisp-lab/</link>
		<comments>http://weblog.destaquenet.com/2010/11/18/emacs-and-slime-your-lisp-lab/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 12:42:56 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[clisp]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[sbcl]]></category>
		<category><![CDATA[slime]]></category>
		<category><![CDATA[swank]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1377</guid>
		<description><![CDATA[This post goes to who&#8217;s studying Clojure (or other Lisp implementations) and is having trouble configuring Emacs. Be prepared for a huge amount of ugly workarounds. ELPA The first thing I do on a fresh Emacs installation is configure the &#8230; <a href="http://weblog.destaquenet.com/2010/11/18/emacs-and-slime-your-lisp-lab/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This post goes to who&#8217;s studying <a href="http://clojure.org">Clojure</a> (or other <a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp</a> implementations) and is having trouble configuring <a href="http://www.gnu.org/software/emacs">Emacs</a>. Be prepared for a huge amount of ugly workarounds.</p>
<h3>ELPA</h3>
<p>The first thing I do on a fresh Emacs installation is configure the <a href="http://tromey.com/elpa">ELPA</a>, or <em>Emacs Lisp Package Archive</em>. If you don&#8217;t know what ELPA is, think of it as an <code>apt-get</code> for Emacs (with some quirks though, as discussed below).</p>
<p>You can find the installation instructions <a href="http://tromey.com/elpa/install.htm">here</a>. If everything works, now you should be able to run the command <code>M-x package-list-packages &lt;ENTER&gt;</code>. Read <a href="http://sean.wenzel.net/docs/emacs/quick_reference/">this</a> if you don&#8217;t understand how commands and shortcuts work on Emacs.</p>
<p>The list of packages available for installation via ELPA should be displayed in a secondary buffer after a few seconds.</p>
<p><span id="more-1377"></span></p>
<h3>Clojure-Mode</h3>
<p>Place the cursor over the line that describes the <code>swank-clojure</code> package, and press <code>I</code> to check it for installation. Do the same thing with <a href="http://www.emacswiki.org/ParEdit"><code>paredit</code></a>. If other packages were checked by accident, move the cursor to the correspondent lines and press <code>U</code> to undo the selection. When you&#8217;re done, press <code>X</code> to proceed with the installation.</p>
<p>Then, run the command <code>M-x slime &lt;ENTER&gt;</code>, and Emacs will ask if you want it to download the Clojure JAR files for you. Unfortunately, answering yes won&#8217;t do anything. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>To fix this, download the <a href="http://clojure.org/downloads">Clojure JAR files</a> manually and put them on <code>~/.clojure/</code>. Then, download the most recent <a href="http://clojars.org/repo/swank-clojure/swank-clojure/">swank-clojure JAR</a> file and put it on <code>~/.swank-clojure/</code>.</p>
<p>There you go. Restart Emacs and run the command <code>M-x slime &lt;ENTER&gt;</code> to start a Clojure REPL inside Emacs!</p>
<div id="attachment_1363" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2010/11/clj-repl.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2010/11/clj-repl-300x168.png" alt="REPL Clojure" title="clj-repl" width="300" height="168" class="size-medium wp-image-1363" /></a><p class="wp-caption-text">Clojure REPL in Emacs</p></div>
<p>Remember that Slime provides many useful features like auto-completion, docstring lookup, etc. Check the <a href="http://common-lisp.net/project/slime/">Slime website</a> for more information.</p>
<h3>Other Lisps</h3>
<p>Run the following command line to install two of the most popular open source implementations of the ANSI Common Lisp standard, <a href="http://www.gnu.org/software/clisp">CLISP</a> and <a href="http://www.sbcl.org/">SBCL</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> clisp sbcl</pre></div></div>

<p>Finally, open the file <code>~/.emacs</code> and paste the following code at the end:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; paredit + lisp modes</span>
<span style="color: #66cc66;">&#40;</span>defvar *lisp-modes* '<span style="color: #66cc66;">&#40;</span>clojure-mode-hook lisp-mode-hook emacs-lisp-mode-hook
                       lisp-interaction-mode-hook slime-repl-mode-hook<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; config used in all lisp modes</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> lisp-config <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>paredit-mode t<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>show-paren-mode t<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapc</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>mode<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>add-hook mode 'lisp-config<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *lisp-modes*<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; other lisp implementations</span>
<span style="color: #66cc66;">&#40;</span>eval-after-load <span style="color: #ff0000;">&quot;slime&quot;</span>
  '<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> slime-lisp-implementations
                '<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sbcl <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/usr/bin/sbcl&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                  <span style="color: #66cc66;">&#40;</span>clisp <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/usr/bin/clisp&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Swank</h3>
<p>The latest versions of Slime come with Swank servers for many popular Lisp implementations, although the package available via ELPA looks like a outdated stripped-down version of Slime. Don&#8217;t ask me why.</p>
<p>Let&#8217;s fix this. Make sure you have a CVS client installed and then run the following command line to get the latest Slime:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">cvs</span> <span style="color: #660033;">-d</span> :pserver:anonymous:anonymous<span style="color: #000000; font-weight: bold;">@</span>common-lisp.net:<span style="color: #000000; font-weight: bold;">/</span>project<span style="color: #000000; font-weight: bold;">/</span>slime<span style="color: #000000; font-weight: bold;">/</span>cvsroot <span style="color: #c20cb9; font-weight: bold;">co</span> slime</pre></div></div>

<p>Now, go to the newly created directory <code>slime</code> and copy all files from this directory over the files installed via ELPA in <code>~/.emacs.d/elpa/slime-&lt;VERSION&gt;</code>. Also remove the file <code>slime.elc</code> from the latter directory as this is a compiled version of an old file.</p>
<p>Restart Emacs. The command <code>M-x slime &lt;ENTER&gt;</code> still starts a Clojure REPL. To start a SBCL REPL, for example, run the command <code>M-- M-x slime &lt;ENTER&gt;</code>, type <code>sbcl</code> and press <code>&lt;ENTER&gt;</code>.</p>
<div id="attachment_1364" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2010/11/sbcl-repl.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2010/11/sbcl-repl-300x168.png" alt="REPL SBCL" title="sbcl-repl" width="300" height="168" class="size-medium wp-image-1364" /></a><p class="wp-caption-text">SBCL REPL in Emacs</p></div>
<h4><em>&#8220;Jeez, I never saw that many workarounds in a single blog post&#8230;&#8221;</em></h4>
<p>Everything would be a lot easier if the packages distributed via ELPA were updated more often, so I expect things to get better eventually. I&#8217;ll update this post when that happens. (Fingers crossed)</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/11/18/emacs-and-slime-your-lisp-lab/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Understanding Open Source Licenses with Clojure</title>
		<link>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/</link>
		<comments>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 12:52:51 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[compojure]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[licensator]]></category>
		<category><![CDATA[licenses]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[project]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1236</guid>
		<description><![CDATA[You only know how cool it is to develop or contribute to an open source project until you do so. The worst part is to define which license to use, and this task is frequently neglected by software developers. Recently &#8230; <a href="http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You only know how cool it is to develop or contribute to an open source project until you do so. The worst part is to define which license to use, and this task is frequently neglected by software developers.</p>
<p>Recently we released <a href="http://licensator.appspot.com">Licensator</a>, a simple web application that gathers information on the most popular open source licenses and helps you choose the right license for your own projects.</p>
<p>The language behind Licensator is <a href="http://clojure.org">Clojure</a>, which proved to be great to solve this sort of problem. We&#8217;ll see today how the application&#8217;s main algorithm works.</p>
<p><span id="more-1236"></span></p>
<h3>REPL: where it all begins</h3>
<p>One of the strengths of dynamic languages is how easily we can transform ideas into working code, and Clojure is no exception. In fact, I decided to write Licensator in one of these coding sessions in the <a href="http://clojure.org/repl_and_main">REPL</a>, Clojure&#8217;s interactive shell. After a few minutes playing with it I saw the problem was indeed easy to solve.</p>
<p>Despite the huge number of licenses, we can easily extract information common to all of them, i.e., if it&#8217;s copyleft, or if a licensed work can be used by closed source software, etc.</p>
<p>Let&#8217;s take the <a href="http://www.opensource.org/licenses/apache2.0.php">Apache v2.0</a> license:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def *licenses*
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">long-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache License v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">short-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">url</span> <span style="color: #ff0000;">&quot;http://www.opensource.org/licenses/apache2.0.php&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">derivative-work</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">affero</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-distribution</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-use</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span>
                         <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span> <span style="color: #66cc66;">:</span><span style="color: #555;">public-domain</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>You can see the remaining licenses <a href="http://github.com/danielfm/licensator/blob/master/src/licensator/licenses.clj">here</a>.</p>
<p>Considering all licenses have the same set of information, how can we find the licenses that are not reciprocal and have explicit copyright terms?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">bsd</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>If you know a little bit about functional programming, this code should be easy to follow. In any case, what this code does is return the <code>:id</code> of all licenses where <code>:copyright</code> is <code>true</code> and <code>:copyleft</code> is <code>false</code>.</p>
<p>Another example: which licenses are compatible with Apache v2.0 and <a href="http://www.opensource.org/licenses/cddl1.php">CDDL v1.0</a>?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>use 'clojure<span style="color: #66cc66;">.</span><span style="color: #b1b100;">set</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Here we used the <a href="http://clojure.github.com/clojure/clojure.set-api.html">clojure.set</a> namespace, which provides a few useful functions to deal with relational algebra. The code is very similar to the previous one; the only difference is that now we used the <code>subset?</code> function to get the licenses compatible with <code>[:apl-v20 :cddl-v10]</code>.</p>
<p>One last example: which reciprocal licenses are compatible with Apache v2.0?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">agpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">gpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>At this point we can see that there is no magic behind the algorithm; what it does is to filter the list of licenses based on a function.</p>
<h3>The solution</h3>
<p>The code we saw up until now works fine, but it&#8217;s not appropriate to solve the problem since the matching logic is spread all over the place.</p>
<p>It would be better to express the search criteria as a map object&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def cmap
     <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&#8230;so we need a function to filter the licenses based on that input, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn find-matches <span style="color: #66cc66;">&#91;</span>cmap data<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>filter <span style="color: #66cc66;">&#40;</span>where cmap<span style="color: #66cc66;">&#41;</span> data<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Here we have <code>where</code>, yet to be coded, that returns a function that filters the elements (licenses) in <code>data</code> according to the criteria map <code>cmap</code>.</p>
<p>First things first. Which conditions of <code>cmap</code> match the Apache v2.0 license?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn criteria-matches? <span style="color: #66cc66;">&#91;</span>license <span style="color: #66cc66;">&#91;</span>kval cval<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #ff0000;">&quot;Checks whether the criteria condition centry is true for license.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>lval <span style="color: #66cc66;">&#40;</span>kval license<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
      true
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>true true true<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A license can only be considered compatible with the given criteria if the list only yields <code>true</code>. Therefore, in this case, the Apache v2.0 license is considered to be compatible:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>every? true? <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> true</pre></div></div>

<p>Given all this, a possible implementation of the <code>where</code> function might be:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn where
  <span style="color: #ff0000;">&quot;Returns a function that checks whether all conditions in cmap match for license lentry.&quot;</span>
  <span style="color: #66cc66;">&#91;</span>cmap<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>lentry<span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>res <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>centry<span style="color: #66cc66;">&#93;</span>
		     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>cval <span style="color: #66cc66;">&#40;</span>val centry<span style="color: #66cc66;">&#41;</span>
			   lval <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>key centry<span style="color: #66cc66;">&#41;</span> lentry<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
		       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
			 true
			 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
      <span style="color: #66cc66;">&#40;</span>every? true? res<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This code is a combination of the previous two snippets; <code>where</code> gets the criteria map <code>cmap</code> and returns a second function, which in turn gets a license entry <code>lentry</code> and checks whether all criteria conditions match.</p>
<p>Since <code>where</code> is used along with <code>filter</code> in <code>find-matches</code>, all licenses compatible with the criteria map <code>cmap</code> are returned:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">&#40;</span>find-matches cmap *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>What I like about Clojure &#8212; and functional programming languages in general &#8212; is the ridiculous amount of code it takes to solve certain problems. This algorithm, for example, has only 15 (really short) lines of code. Where is your God now?! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>You can see <a href="http://github.com/danielfm/licensator">the whole thing</a> in Github.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/10/05/understanding-open-source-licenses-with-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Entendendo Licenças Open Source com Clojure</title>
		<link>http://weblog.destaquenet.com/2010/10/05/entendendo-licencas-open-source-com-clojure/</link>
		<comments>http://weblog.destaquenet.com/2010/10/05/entendendo-licencas-open-source-com-clojure/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 12:52:42 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[compojure]]></category>
		<category><![CDATA[licenças]]></category>
		<category><![CDATA[licensator]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[programação funcional]]></category>
		<category><![CDATA[projeto]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1141</guid>
		<description><![CDATA[Só quem desenvolve ou contribui com projetos open source sabe como é legal. A pior parte é definir sob qual licença soltar o código, e essa tarefa é muitas vezes negligenciada por desenvolvedores de software. Para quem não viu, recentemente &#8230; <a href="http://weblog.destaquenet.com/2010/10/05/entendendo-licencas-open-source-com-clojure/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Só quem desenvolve ou contribui com projetos open source sabe como é legal. A pior parte é definir sob qual licença soltar o código, e essa tarefa é muitas vezes negligenciada por desenvolvedores de software.</p>
<p>Para quem não viu, recentemente colocamos no ar o <a href="http://www.destaquenet.com/portifolio/licensator/">Licensator</a>, uma aplicação web que, além de reunir informações sobre as licenças open source mais populares, é capaz de indicar as licenças apropriadas para cada caso.</p>
<p>A linguagem escolhida para implementar o projeto foi <a href="http://clojure.org">Clojure</a>, que se mostrou excelente para resolver esse tipo de problema. Veremos hoje como o principal algoritmo da aplicação funciona.</p>
<p><span id="more-1141"></span></p>
<h3>REPL: onde tudo começa</h3>
<p>Um dos pontos fortes das linguagens dinâmicas é a facilidade em transformar idéias em código funcional, e com Clojure não é diferente. A idéia por trás do Licensator surgiu justamente em uma dessas sessões de codificação no <a href="http://clojure.org/repl_and_main">REPL</a>, o ambiente interativo da linguagem. Após alguns minutos brincando, vi que o problema era simples de resolver.</p>
<p>Apesar do elevado número de licenças, podemos facilmente extrair informações comuns a todas elas, como: se a licença é copyleft, se pode ser usada por código fechado (proprietário), entre outras coisas.</p>
<p>Por exemplo, vamos pegar a licença <a href="http://www.opensource.org/licenses/apache2.0.php">Apache v2.0</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def *licenses*
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">long-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache License v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">short-</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Apache v2.0&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">url</span> <span style="color: #ff0000;">&quot;http://www.opensource.org/licenses/apache2.0.php&quot;</span>
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">derivative-work</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">affero</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> false
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-distribution</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">charge-for-use</span> true
       <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span>
                         <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span> <span style="color: #66cc66;">:</span><span style="color: #555;">public-domain</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A lista completa de licenças pode ser vista <a href="http://github.com/danielfm/licensator/blob/master/src/licensator/licenses.clj">aqui</a>.</p>
<p>Considerando que todas as licenças têm esse mesmo conjunto de informações, como podemos saber quais licenças não são recíprocas e possuem cláusulas explícitas de copyright?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyright</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">freebsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span> <span style="color: #66cc66;">:</span><span style="color: #555;">bsd</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Se você conhece um pouco sobre programação funcional, este código deve ser fácil de acompanhar. De qualquer forma, o que ele faz é retornar o <code>:id</code> de todas as licenças onde <code>:copyright</code> é verdadeiro e <code>:copyleft</code> é falso.</p>
<p>Outro exemplo: quais licenças são compatíveis com Apache v2.0 e <a href="http://www.opensource.org/licenses/cddl1.php">CDDL v1.0</a>?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>use 'clojure<span style="color: #66cc66;">.</span><span style="color: #b1b100;">set</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Aqui usamos a namespace <a href="http://clojure.github.com/clojure/clojure.set-api.html">clojure.set</a>, que conta com algumas funções úteis para álgebra relacional. O código é muito parecido com o anterior; a mudança é que agora usamos a função <code>subset?</code> para buscar as licenças compatíveis com <code>[:apl-v20 :cddl-v10]</code>.</p>
<p>Último exemplo: quais licenças recíprocas são compatíveis com Apache v2.0?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span>
  <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">copyleft</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">agpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">gpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Neste ponto já se pode perceber que não existe mágica nenhuma por trás do algoritmo; o que ele faz é filtrar as licenças com base numa função.</p>
<h3>A solução</h3>
<p>O código que acabamos de ver funciona, mas não é apropriado para resolver o problema uma vez que a lógica de consulta se encontra fixa no código.</p>
<p>O ideal seria se os critérios de busca fossem expressados como um map&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def cmap
     <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #555;">patent</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">closed-source-linking</span> true<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">compatible-with</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">:</span><span style="color: #555;">mit</span> <span style="color: #66cc66;">:</span><span style="color: #555;">new-bsd</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&#8230;portanto precisamos de uma função que faça a filtragem das licenças com base nesse mapa, algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn find-matches <span style="color: #66cc66;">&#91;</span>cmap data<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>filter <span style="color: #66cc66;">&#40;</span>where cmap<span style="color: #66cc66;">&#41;</span> data<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>No caso, essa função <code>where</code>, que ainda não definimos, deve retornar uma função que filtre os elementos (licenças) em <code>data</code> de acordo com o mapa de critérios <code>cmap</code>.</p>
<p>Vamos por partes. Quais condições em <code>cmap</code> são verdadeiras para a licença Apache v2.0?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn criteria-matches? <span style="color: #66cc66;">&#91;</span>license <span style="color: #66cc66;">&#91;</span>kval cval<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
  <span style="color: #ff0000;">&quot;Verifica se o critério 'centry' é verdadeiro para a licença 'license'.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>lval <span style="color: #66cc66;">&#40;</span>kval license<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
      true
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>true true true<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Uma licença só pode ser considerada compatível com os critérios se a lista retornada contém apenas valores verdadeiros. Portanto, neste caso, a licença Apache v2.0 é considerada compatível com os critérios informados:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>every? true? <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>partial criteria-matches? apl-v20<span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> true</pre></div></div>

<p>Logo, uma possível implementação para a função <code>where</code> seria:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn where
  <span style="color: #ff0000;">&quot;Retorna função que diz se todos os critérios em 'cmap' são verdadeiros para a licença 'lentry'.&quot;</span>
  <span style="color: #66cc66;">&#91;</span>cmap<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>lentry<span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>res <span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">&#40;</span>fn <span style="color: #66cc66;">&#91;</span>centry<span style="color: #66cc66;">&#93;</span>
		     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>cval <span style="color: #66cc66;">&#40;</span>val centry<span style="color: #66cc66;">&#41;</span>
			   lval <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>key centry<span style="color: #66cc66;">&#41;</span> lentry<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
		       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">nil</span>? cval<span style="color: #66cc66;">&#41;</span>
			 true
			 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>coll? lval<span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span>subset? <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> cval<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
			   <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> cval lval<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> cmap<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
      <span style="color: #66cc66;">&#40;</span>every? true? res<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Este código é uma junção dos dois anteriores. A função <code>where</code> recebe o mapa <code>cmap</code> com os critérios de pesquisa, e retorna uma segunda função. Esta função recebe uma licença <code>lentry</code> e verifica se todos os critérios informados são verdadeiros para esta licença.</p>
<p>Como <code>where</code> é usada em conjunto com <code>filter</code> na função <code>find-matches</code>, isso fará com que todas as licenças compatíveis sejam retornadas:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">id</span> <span style="color: #66cc66;">&#40;</span>find-matches cmap *licenses*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">afl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">apl-v20</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cddl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">epl-v10</span> <span style="color: #66cc66;">:</span><span style="color: #555;">lgpl-v30</span> <span style="color: #66cc66;">:</span><span style="color: #555;">mpl-v11</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Uma das coisas legais de Clojure &#8212; e outras linguagens funcionais &#8212; é a quantidade ridícula de código necessário para resolver certos problemas. Este algoritmo, por exemplo, tem apenas 15 linhas (muito curtas) de código. Onde está seu Deus agora?! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>O <a href="http://github.com/danielfm/licensator">código da aplicação</a> está no Github para quem tiver interesse em ver o restante do código.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/10/05/entendendo-licencas-open-source-com-clojure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Clojure Invade o Dev In Sampa</title>
		<link>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/</link>
		<comments>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 11:30:34 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Português]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[devinsampa]]></category>
		<category><![CDATA[encontro]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[palestra]]></category>
		<category><![CDATA[sao paulo]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1062</guid>
		<description><![CDATA[No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º Dev In Sampa, um encontro de desenvolvedores de software que não faz propaganda do governo nem apresenta palestras com foco em um único fornecedor. Já era hora! Infelizmente, por &#8230; <a href="http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º <a href="http://devinsampa.com.br/">Dev In Sampa</a>, um encontro de desenvolvedores de software que não <a href="http://fisl.softwarelivre.org/">faz propaganda do governo</a> nem apresenta palestras com <a href="http://www.oracle.com/us/javaonedevelop/index.html">foco em um único fornecedor</a>. Já era hora!</p>
<p>Infelizmente, por <a href="http://weblog.destaquenet.com/2009/10/05/use-web-scraping-para-acompanhar-seus-pedidos-na-ticketmaster/">razões de força maior</a> eu não pude comparecer na primeira edição do evento, mas este ano eu estarei presente, e ainda por cima <a href="http://devinsampa.com.br/palestras#presentation-3">como palestrante</a>.</p>
<p>Por isso, antes de mais nada, eu gostaria de agradecer àqueles que votaram na minha palestra. Isso mostra que <a href="http://clojure.org/">Clojure</a> anda despertando o interesse da rapazeada também no Brasil, o que é muito bom.</p>
<p><strong>Update:</strong> Apresentação e códigos-fonte <a href="http://github.com/danielfm/clojure-devinsampa">disponíveis para download</a>.</p>
<p><span id="more-1062"></span></p>
<h3>Sobre a palestra</h3>
<p>Apresentar uma linguagem de programação numa palestra de 50 minutos é sempre uma tarefa complicada, especialmente se essa linguagem de programação traz consigo uma <a href="http://clojure.org/rationale">bagagem</a> que vai muito além da sintaxe.</p>
<p>Quando eu assisto uma palestra sobre linguagens de programação, existem duas coisas que me irritam. A primeira é quando o palestrante soca um monte de código e se limita à sintaxe, explicando tudo vírgula por vírgula, sem nenhum contexto. A outra é quando o palestrante fala sobre uma linguagem mas não mostra nenhum exemplo.</p>
<p>Para não repetir esses erros, eu optei por um estilo diferente, onde a linguagem é abordada e explorada aos poucos, mas sempre seguindo uma linha para que haja um começo, um meio e um fim.</p>
<p>Meu objetivo não será ensinar ninguém a programar em Clojure, e sim mostrar alguns dos recursos que eu considero importantes. Assim, quem se interessar pode pesquisar mais por conta própria. Afinal, não somos todos auto-didatas?</p>
<p>Quem tiver dúvidas ao final da palestra, ou quiser apenas jogar conversa fora, é só me chamar pelo <a href="http://twitter.com/danielfmt">Twitter</a>. Também não irei reclamar se alguém quiser pagar meu almoço. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>O &#8220;pós-evento&#8221;</h3>
<p>Ao final, a apresentação será disponibilizada para download no <a href="http://github.com/danielfm">GitHub</a>, juntamente com os <em>muitos</em> exemplos de código. Os slides virão acompanhados de notas que poderão ser lidas como uma espécie de artigo.</p>
<p>Deixarei os comentários deste post habilitados para quem quiser deixar dúvidas ou mensagens sobre a palestra.</p>
<p>É isso aí. Nos encontramos lá!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>At World Cup Season&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/</link>
		<comments>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 16:42:02 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bet]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[football]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[pool]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[soccer]]></category>
		<category><![CDATA[sweepstakes]]></category>
		<category><![CDATA[world cup]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=909</guid>
		<description><![CDATA[Some people think &#8212; and I agree &#8212; that the UEFA Champions League is a more relevant tournament than the World Cup itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye &#8230; <a href="http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some people think &#8212; and I agree &#8212; that the <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> is a more relevant tournament than the <a href="http://www.fifa.com/worldcup/index.html">World Cup</a> itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye on. Even those who doesn&#8217;t love the sport tend to follow the teams, the matches, the celebration.</p>
<p>And with the World Cup comes the sweepstakes. Lots of.</p>
<p>Although the rules might change from one place to another, these are the ones we use the most here in Brazil:</p>
<ol>
<li>Everyone try to predict the score of a particular match, paying a fixed amount for each guess (eg $1.00).</li>
<li>At the end, the ammount collected is divided equally among the winners. If there are no winners: (a) the sweepstake &#8220;accumulates&#8221;<sup class='footnote'><a href='#fn-909-1' id='fnref-909-1'>1</a></sup>, or (b) everyone get their money back, or (c) you-crazy-rule-here.</li>
</ol>
<p>I like this kind of sweepstake, but it could be better in some respects.</p>
<p>First, not everybody has the habit of carrying small bills around, so the sweepstakes manager (a.k.a. YOU) loses a lot of time chasing change. Besides, I think the fixed-valued bet is kind of boring since the amount collected is divided equally among the winners. I think things get more exciting when people can choose how much to pay for each guess, so the amount collected is divided <strong>proportionally</strong> among the winners. In this case, when several people win, earns more who bets more.</p>
<p>Since I don&#8217;t like to do the math myself, here&#8217;s the challenge: create a program that receives a list with all guesses and returns the list of winners along with the proportional amount to be paid to each one of them.</p>
<p>So, shall we?</p>
<p><span id="more-909"></span></p>
<h3>Solving the problem&#8230; with Clojure</h3>
<p>Write more code than necessary is going out of style these days, so I decided to code a solution in <a href="http://clojure.org">Clojure</a>, a functional programming language that makes this sort of &#8220;problem&#8221; really easy to solve. Just launch <a href="http://clojure.org/repl_and_main">the REPL</a> and profit!</p>
<p>The first thing to do is define how to represent each guess:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>All guesses has the same information. That&#8217;s why we defined a <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> with the keys <code>:name</code>, <code>:amount</code>, <code>:guess</code>, and <code>:rate</code>.</p>
<p>A list of possible guesses might be:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">2.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Daniel bets $2.00 on score 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">4.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; John bets $4.00 on score 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Maria bets $1.00 on score 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Okay, we already know how each guess is represented. Now, how to find the sweepstake&#8217;s total amount? Simple, all we have to do is to sum the amount of all guesses:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">7.0</span></pre></div></div>

<p>Great, but how much each guess represent in relation to the whole, that is, what&#8217;s the proportion of each guess? All we have to do is to divide the amount of each guess by the sweepstake&#8217;s total amount:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.285</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.571</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.142</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">1.0</span></pre></div></div>

<p>Note that, if everyone wins, the amount earned by John would be the double of the amount earned by Daniel, which would be the double of the amount earned by Maria. Justice, finally!</p>
<p>To finish the code, we just need a function that filters the winners and calculates how much to pay to each winner:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; no winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; just one winner</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.0</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; several winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Daniel&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">4.66</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.66</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">2.33</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.33</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A major advantage of this solution is that it allows you to bet on anything. Want to bet on the sex of a baby shortly after the good news (or bad news, whatever)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">3.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">male</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">5.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">1.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>There you go, a simple solution for a simple problem.</p>
<h3>The code</h3>
<p>Although it&#8217;s possible to solve this problem in Lisp/Clojure with a one-liner (<a href="http://clojure.org/reader">the Reader</a> works with <strong>data structures</strong> after all), I decided to write a code that is as readable as possible for those who are starting with Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Your turn</h3>
<p>Do you program in Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? How would you solve such problem in your favorite programming language?</p>
<p><strong>Update (Nov 3, 2010).</strong> Common Lisp solution, using <code>copy-*</code> to avoid changes in state:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #b1b100;">name</span> amount guess rate<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-amount <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>reduce #'+ <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'bet-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-rates <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>bet<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-winners <span style="color: #66cc66;">&#40;</span>pool result<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>winners <span style="color: #66cc66;">&#40;</span>loop for bet in pool <span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> <span style="color: #66cc66;">&#40;</span>bet-guess bet<span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> collect bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>winner<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet winner<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-909-1'>The amount collected remains available for the next match&#8217;s sweepstakes, but everyone must pay again for a new guess. <span class='footnotereverse'><a href='#fnref-909-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Em Tempos de Copa do Mundo&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/</link>
		<comments>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 11:00:16 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[aposta]]></category>
		<category><![CDATA[bolão]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[copa do mundo]]></category>
		<category><![CDATA[futebol]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[programa]]></category>
		<category><![CDATA[solução]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=898</guid>
		<description><![CDATA[Há quem ache &#8212; e eu concordo &#8212; que a UEFA Champions League é um torneio mais relevante do que a Copa do Mundo, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é &#8230; <a href="http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há quem ache &#8212; e eu concordo &#8212; que a <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> é um torneio mais relevante do que a <a href="http://www.fifa.com/worldcup/index.html">Copa do Mundo</a>, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é apaixonado pelo esporte passa a prestar atenção nas seleções, nas partidas, na festa.</p>
<p>E com a Copa do Mundo vem os bolões. Muitos bolões.</p>
<p>Todo mundo já sabe como funciona um bolão, embora a mecânica possa mudar de um lugar para outro:</p>
<ol>
<li>Cada palpite tem um valor fixo (ex: R$2,00).</li>
<li>Cada um pode dar quantos palpites quiser.</li>
<li>No final, o montante arrecadado é dividido igualmente entre os vencedores. Se não houverem vencedores: (a) o bolão &#8220;acumula&#8221;<sup class='footnote'><a href='#fn-898-1' id='fnref-898-1'>1</a></sup>, ou (b) todo mundo recebe seu dinheiro de volta, ou (c) sua-regra-maluca-aqui.</li>
</ol>
<p>Esse tipo de bolão é interessante, mas ele podia ser melhor em alguns aspectos.</p>
<p>Primeiro, o organizador acaba perdendo muito tempo correndo atrás de troco, afinal não é todo mundo que anda com dinheiro trocado na carteira. Além disso, valor fixo de palpite é muito chato, pois o valor arrecadado é dividido por igual entre os ganhadores. O bolão fica muito mais interessante quando o valor do palpite é variável e o valor arrecadado é dividido proporcionalmente entre os ganhadores. Assim, no caso de vários ganhadores, ganha mais quem apostar mais.</p>
<p>O problema de se fazer bolões com palpite variável é ter que ficar calculando o valor proporcional a ser dado a cada ganhador. Portanto eis o desafio: criar um programa que receba uma lista com todos os palpites e retorne uma lista com os palpites vencedores juntamente com o valor proporcional a ser pago a cada ganhador.</p>
<p>E aí, topa?</p>
<p><span id="more-898"></span></p>
<h3>Resolvendo o problema&#8230; em Clojure</h3>
<p>Como escrever mais código do que necessário está saindo de moda, optei por codificar uma possível solução em <a href="http://clojure.org">Clojure</a>. Por ser uma <a href="http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/">linguagem funcional</a>, Clojure é excelente para esse tipo de tarefa. Basta iniciar o <a href="http://clojure.org/repl_and_main">REPL</a> e mãos à obra!</p>
<p>Primeiramente, devemos definir como um palpite deve ser representado:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Todos os palpites possuem o mesmo conjunto de informações, por isso definimos um <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> com as chaves <code>:name</code>, <code>:amount</code>, <code>:guess</code> e <code>:rate</code>.</p>
<p>Abaixo, uma possível lista de palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span>  <span style="color: #cc66cc;">2.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Daniel aposta R$2,00 no placar 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Antônio&quot;</span> <span style="color: #cc66cc;">4.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Antônio aposta R$4,00 no placar 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Marcela&quot;</span> <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Marcela aposta R$1,00 no placar 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Certo, já sabemos como os palpites são representados. Agora, como saber o montante total de uma lista de palpites (a.k.a. bolão)? Simples, basta calcular o somatório dos valores de todos os palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">7.0</span></pre></div></div>

<p>Beleza, mas quanto cada palpite representa em relação ao total arrecadado? Afinal, precisamos calcular o valor proporcional a ser pago a cada ganhador.</p>
<p>Sem problemas, basta dividir o valor de cada palpite pelo montante total:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.285</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.571</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.142</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">1.0</span></pre></div></div>

<p>Repare que, se todos os participantes ganhassem um bolão, o valor recebido pelo Antônio seria o dobro do valor recebido pelo Daniel, que seria o dobro do valor recebido pela Marcela. Justiça, finalmente!</p>
<p>Pronto, agora só falta uma função para filtrar os ganhadores da lista de participantes e calcular o valor proporcional a ser pago a cada um deles:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; sem ganhadores</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; apenas um ganhador</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Antônio&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.0</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; vários ganhadores</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Daniel&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">4.66</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.66</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Marcela&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">2.33</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.33</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Uma grande vantagem dessa solução é que ela permite que você aposte em qualquer coisa. Quer apostar no sexo de um bebê logo após a boa notícia (ou má notícia, sei lá)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; :male = masculino, :female = feminino</span>
<span style="color: #66cc66;">&#40;</span>def pool <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span>  <span style="color: #cc66cc;">3.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">male</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Antônio&quot;</span> <span style="color: #cc66cc;">5.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Fran&quot;</span>    <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Antônio&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Fran&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">1.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Aí está, uma solução simples para um problema simples. Como deveria ser sempre.</p>
<h3>Minha solução, na íntegra</h3>
<p>Embora seja possível resolver isso com um one-liner em Lisp/Clojure (afinal o <a href="http://clojure.org/reader">Reader</a> não trabalha com linhas, mas com <strong>estruturas de dados</strong>), eu optei por escrever um código que fosse o mais legível possível para quem não conhece ou está aprendendo Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Levando adiante</h3>
<p>Você programa em Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? Qual seria a sua solução para este problema de extrema importância para o desenvolvimento da raça humana? <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p><strong>Atualização (03/11/2010).</strong> Solução em Common Lisp, usando <code>copy-*</code> para evitar mutabilidade:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #b1b100;">name</span> amount guess rate<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-amount <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>reduce #'+ <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'bet-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-rates <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>bet<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-winners <span style="color: #66cc66;">&#40;</span>pool result<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>winners <span style="color: #66cc66;">&#40;</span>loop for bet in pool <span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> <span style="color: #66cc66;">&#40;</span>bet-guess bet<span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> collect bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>winner<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet winner<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-898-1'>Todo o montante recebido continua disponível no próximo bolão, mas os participantes devem pagar um novo palpite. <span class='footnotereverse'><a href='#fnref-898-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programação Funcional: vale a pena aprender?</title>
		<link>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/</link>
		<comments>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 19:32:54 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[programação funcional]]></category>
		<category><![CDATA[project euler]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=511</guid>
		<description><![CDATA[Antes de começar com Python, eu não conhecia praticamente nada sobre Programação Funcional. Para falar a verdade, eu até achava que os paradigmas Funcional e Procedural eram a mesma coisa pelo fato do segundo se basear em funções métodos (e &#8230; <a href="http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Antes de começar com <a href="http://python.org">Python</a>, eu não conhecia praticamente nada sobre <a href="http://en.wikipedia.org/wiki/Functional_programming">Programação Funcional</a>. Para falar a verdade, eu até achava que os paradigmas Funcional e <a href="http://en.wikipedia.org/wiki/Procedural_programming">Procedural</a> eram a mesma coisa pelo fato do segundo se basear em <span style="text-decoration: line-through;">funções</span> métodos (e várias pessoas com as quais eu convivo e trabalho também têm esse equívoco). Felizmente, tudo começou a fazer sentido quando aprendi, graças ao Python, coisas  como <a href="http://docs.python.org/library/functions.html#map"><code>map()</code></a>, <a href="http://docs.python.org/library/functions.html#reduce"><code>reduce()</code></a>, <a href="http://docs.python.org/library/functions.html#filter"><code>filter()</code></a>, <a href="http://docs.python.org/tutorial/classes.html#generators">generators</a> e <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list comprehensions</a>.</p>
<p>Como o mercado é dominado por linguagens imperativas, é bem difícil encontrar pessoas que realmente conheçam e utilizem linguagens funcionais com certa regularidade. Mas isso não significa, de forma alguma, que não há espaço para tais linguagens. Na verdade, a tendência é que elas ganhem cada vez mais espaço.</p>
<p><span id="more-511"></span></p>
<h3>Por que aprender uma linguagem funcional?</h3>
<p>Em linguagens imperativas, a programação de um <em>software</em> consiste basicamente na definição e manipulação de seu estado interno, conduzida de modo a resolver um determinado problema. Portanto, pode-se dizer que <em>softwares</em> escritos em tais linguagens são movidos a <em>efeitos colaterais</em>, pois a forma e a ordem com que seu estado interno é modificado é o que define o funcionamento do <em>software</em>.</p>
<p>Em <em>softwares</em> triviais isso não chega a ser um problema, mas quando falamos de <em>softwares</em> grandes e complexos, essa volatilidade complica, e muito, a vida de quem os desenvolve e os mantém.</p>
<p>Linguagens funcionais, por outro lado, são conhecidas por evitar efeitos colaterais ao máximo, e isso nos trás uma infinidade de vantagens. Assim como na matemática, executar uma função <em>f(x)</em> com o mesmo argumento <em>N</em> vezes produz <em>sempre</em> o mesmo resultado, e por isso:</p>
<ol>
<li>o código fica muito mais fácil de entender, debugar e testar. Tudo o que você precisa saber sobre uma função está nos seus argumentos;</li>
<li>o código, por também contar com estruturas de dados imutáveis, pode ser executado de forma concorrente, com poucas ou quaisquer modificações, e você nunca terá de se preocupar com locks, <a href="http://en.wikipedia.org/wiki/Race_condition">condições de corrida</a>, <a href="http://en.wikipedia.org/wiki/Deadlock">deadlocks</a> e coisas do tipo;</li>
<li>o compilador pode fazer otimizações impossíveis de serem feitas em linguagens imperativas, como automaticamente paralelizar ou reordenar chamadas a funções;</li>
</ol>
<p>Enfim, esse é só um resumo das vantagens que linguagens funcionais têm sobre linguagens imperativas. Confira os links no final deste post para saber mais.</p>
<h3>Escolhendo a linguagem</h3>
<p>Clojure, Erlang, Haskell, J, (Common) Lisp, Scheme. E essas são somente algumas das linguagens com forte base funcional disponíveis por aí.</p>
<p>Mas qual delas escolher? Cada pessoa segue um ritual diferente ao escolher uma nova ferramenta e por isso não sou eu quem irá te dizer qual delas escolher. O que eu posso fazer é dar algumas sugestões:</p>
<ul>
<li>Quer saber como tudo começou? Aprenda <a href="http://en.wikipedia.org/wiki/Common_Lisp">Common Lisp</a>.</li>
<li>Quer uma linguagem parecida com Lisp, mas que rode na JVM? <a href="http://clojure.org/">Clojure</a> pode ser uma boa.</li>
<li>Quer uma linguagem com uma sintaxe sucinta e poderosa? Dê uma olhada em <a href="http://www.jsoftware.com/">J</a>.</li>
<li>Quer uma linguagem que facilite a construção de <em>softwares</em> distribuídos e de alta disponibilidade? Vá de <a href="http://www.erlang.org/">Erlang</a>.</li>
<li><strong>Quer uma linguagem que mude a forma com que você pensa sobre programação? Aprenda qualquer uma delas!</strong></li>
</ul>
<p>Erlang e Haskell estão na minha mira mas, no momento, eu optei por aprender Clojure.</p>
<h3>Praticar é essencial</h3>
<p>Ok, escolhida a linguagem de programação, o próximo passo é ler muito e praticar mais ainda.</p>
<p>Para quem está interessado em aprender Clojure, material não falta. Apesar de bem nova (apenas 2 anos de existência), a linguagem vem ganhando popularidade e muito vêm sendo escrito sobre ela. Aliás, <a href="http://www.pragprog.com/titles/shcloj/programming-clojure">o primeiro livro sobre Clojure</a> foi publicado recentemente pela <a href="http://pragprog.com/">Pragmatic Bookshelf</a>. (Pode comprar sem medo, o livro é excelente)</p>
<p>Agora, independente da linguagem escolhida, uma forma interessante de aplicar os conhecimentos recém-adquiridos é tentar resolver os problemas propostos pelo <a href="http://projecteuler.net/">Project Euler</a>, um website com centenas de problemas do tipo <a href="http://projecteuler.net/index.php?section=problems&amp;id=12">&#8220;What is the value of the first triangle number to have over five hundred divisors?&#8221;</a>. No começo eu sofri um pouco para pegar as manhas da linguagem, mas depois de ter resolvido uns 10-15 problemas desse tipo, eu sinto que as coisas estão começando a fazer sentido.</p>
<p>Aos interessados, eu acabei de disponibilizar no Github <a href="http://github.com/danielfm/euler-clojure/tree/master">um projeto</a> contendo as soluções, todas em Clojure, para alguns dos problemas propostos.</p>
<h3>E vocês, o que recomendam?</h3>
<p>Depois de algumas semanas pesquisando sobre Programação Funcional, eu me sinto como se tivesse deixado de lado um vício: meio assustador no início, mas melhor a cada dia que passa!</p>
<p>Aos que já conhecem ou trabalham regularmente com linguagens funcionais, que dica vocês dão para quem acabou de tomar a <a href="http://en.wikipedia.org/wiki/Redpill">pílula vermelha</a>?</p>
<h3>Referências</h3>
<ul>
<li><a href="http://www.paulgraham.com/onlisp.html">On Lisp Book</a> (Obrigatório!);</li>
<li><a href="http://www.defmacro.org/ramblings/fp.html">Functional Programming For The Rest Of Us</a> (Obrigatório!);</li>
<li><a href="http://www2.computer.org/portal/web/computingnow/0609/whatsnew/cise">The Promises Of Functional Programming</a> (Atualização);</li>
<li><a href="http://www.pragprog.com/titles/shcloj/programming-clojure">Programming Clojure</a>;</li>
<li><a href="http://java.ociweb.com/mark/clojure/article.html">Clojure &#8211; Functional Programming for the JVM</a>;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

