<?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>Hespanha</title>
	<atom:link href="http://www.hespanha.com.br/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hespanha.com.br/blog</link>
	<description>Apenas um programador que ama o que faz e servo do Senhor Jesus</description>
	<lastBuildDate>Wed, 16 May 2012 23:37:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>&#8220;Scala Tips&#8221; =&gt; try &#8211; finally</title>
		<link>http://www.hespanha.com.br/blog/2012/05/scala-tips-try-finally/</link>
		<comments>http://www.hespanha.com.br/blog/2012/05/scala-tips-try-finally/#comments</comments>
		<pubDate>Wed, 16 May 2012 23:37:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=152</guid>
		<description><![CDATA[Scala tem um comportamento curioso com try-finally. Dado o código: def f(): Int = try { return 1 } finally { return 2} se chamarmos f() o retorno será 2. Agora dado o código: def g(): Int = try { 1 } finally { 2 } se chamarmos g() o retorno será 1. Estranho não? [...]]]></description>
			<content:encoded><![CDATA[<p>Scala tem um comportamento curioso com try-finally.</p>
<p>Dado o código:</p>
<p><code>def f(): Int = try { return 1 } finally { return 2}</code></p>
<p>se chamarmos f() o retorno será 2.</p>
<p>Agora dado o código:</p>
<p><code>def g(): Int = try { 1 } finally { 2 }</code></p>
<p>se chamarmos g() o retorno será 1.</p>
<p>Estranho não? Se houvesse certificação em Scala certamente essa seria uma das questões!</p>
<p>No Scala, se o bloco try for executado com sucesso, o retorno será o resultado do bloco try, e ele ignorará o valor de retorno do finally.</p>
<p>Já no Java, o comportamento é retornar o resultado que houver no bloco finally, se houver, é claro, senão ele retorna o resultado do bloco try, obviamente.</p>
<p>Logo, ao que tudo indica, para manter compatibilidade com Java, se usarmos a palavra chave <strong>return</strong> o código Scala acaba se comportando igual ao código Java, o que é bem confuso, dado que se fazemos <code>try { 1 } finally { 2 }</code> o return está implicito. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2012/05/scala-tips-try-finally/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala Tips &#8211; Construtores</title>
		<link>http://www.hespanha.com.br/blog/2012/05/scala-tips-construtores/</link>
		<comments>http://www.hespanha.com.br/blog/2012/05/scala-tips-construtores/#comments</comments>
		<pubDate>Tue, 15 May 2012 23:01:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=137</guid>
		<description><![CDATA[Todos que programam em Scala sabem que é possível definir o construtor de uma classe da seguinte forma: class Rational(n: Int, d: Int) Com isso, ao se criar uma nova instância da classe usando o construtor: new Rational(1, 2) automaticamente os valores 1 e 2 são associados aos atributos n e d da classe, respectivamente. [...]]]></description>
			<content:encoded><![CDATA[<p>Todos que programam em Scala sabem que é possível definir o construtor de uma classe da seguinte forma:</p>
<p><code>class Rational(n: Int, d: Int) </code></p>
<p>Com isso, ao se criar uma nova instância da classe usando o construtor:</p>
<p><code>new Rational(1, 2)</code></p>
<p>automaticamente os valores 1 e 2 são associados aos atributos n e d da classe, respectivamente.</p>
<p>Mas uma outra peculiaridade de Scala que nem todos sabem é que, tudo que for dedinido no corpo da classe que não seja atributo ou método será considerado código a ser chamado pelo construtor da classe. Exemplo:</p>
<p><code>class Rational(n: Int, d: Int) {<br />
println("Criando a classe")</p>
<p>def imprime() = println(n + "/" + d)</p>
<p>println("Vai ser chamado novamente pelo construtor")</p>
<p>}</code></p>
<p>Agora, ao chamar o construtor:</p>
<p><code>new Rational(1,2)</code></p>
<p>será exibido na tela:</p>
<p><code>Criando a classe<br />
Vai ser chamado novamente pelo construtor</code></p>
<p>Para saber mais sobre esses detalhes da linguagem, recomendo a leitura do livro &#8220;Programming in Scala&#8221;.</p>
<p>PS: Como definimos um construtor para a classe, o construtor default não é criado, assim como no Java.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2012/05/scala-tips-construtores/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A falta de qualidade nos sistemas atuais</title>
		<link>http://www.hespanha.com.br/blog/2012/04/falta-de-qualidad/</link>
		<comments>http://www.hespanha.com.br/blog/2012/04/falta-de-qualidad/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 05:41:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=131</guid>
		<description><![CDATA[Confesso que estou um pouco chateado com a falta de qualidade que venho encontrando nos sistemas, especialmente sites, ultimamente. Para dar alguns exemplos rápidos: Fui declarar meu imposto de renda usando o software pro Mac, e na hora de enviar a minha declaração pra receita estourava um NullPointerException na minha cara. Mudei pro Windows e [...]]]></description>
			<content:encoded><![CDATA[<p>Confesso que estou um pouco chateado com a falta de qualidade que venho encontrando nos sistemas, especialmente sites, ultimamente. Para dar alguns exemplos rápidos:</p>
<li>Fui declarar meu imposto de renda usando o software pro Mac, e na hora de enviar a minha declaração pra receita estourava um NullPointerException na minha cara. Mudei pro Windows e foi. Ou seja, não testaram direito o sistema no Mac.</li>
<li>Entrei no site de um grande time de futebol esses dias, e quando cliquei em um link apareceu um alert com o texto ERROR. Isso porque era um dos links principais do site. Será que foi testado? Duvido muito.</li>
<li>Fui fazer uma compra em um grande site de produtos esportivos do Brasil, líder do segmento, errei minha senha e o site apagou o meu usuário e deixou a senha errada lá. Depois mudou a senha para um outro campo nada a ver. Que beleza! Será que foi testado? Provavelmente só testaram considerando que o usuário sempre acerta a senha de primeira.</li>
<li>Fui fazer o pagamento com cartão de crédito em um grande portal, e sem querer esqueci de selecionar a bandeira, mas preenchi o número do cartão e tudo o mais. Quando percebi que precisava selecionar a bandeira, cliquei e ele apagou o que eu tinha preenchido. Por que?</li>
<p>Esses são só alguns exemplos que lembrei agora, mas certamente tem muitos outros. Confesso que isso me deixa muito triste, pois mostra que está abaixando o nível dos profissionais da computação e que a qualidade dos produtos tem caído muito.</p>
<p>Erros básicos e grosseiros como esse pra mim só mostram uma coisa: Relaxo.  Em nenhum dos casos eu entrei em um fluxo complexo, com várias exceções, que seja difícil de ser simulado. Foram casos bem simples que demonstram que os sistemas foram pouco testados.</p>
<p>Triste! Precisamos começar a mudar isso urgentemente! Infelizmente fala-se pouco de testes aqui no Brasil, é tempo da comunidade começar a mudar essa situação.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2012/04/falta-de-qualidad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Os três principais problemas da Concorrência</title>
		<link>http://www.hespanha.com.br/blog/2011/09/os-tres-principais-problemas-da-concorrencia/</link>
		<comments>http://www.hespanha.com.br/blog/2011/09/os-tres-principais-problemas-da-concorrencia/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 22:46:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[programação]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=123</guid>
		<description><![CDATA[Ultimamente se tornou inevitável desenvolver programas que funcionam de maneira concorrente, já que os processadores com multiplos cores já estão em todo lugar, até mesmo nos celulares. E ao mesmo tempo que é extremamente prazeroso ver o seu software muito mais rápido graças a concorrência, também se pode perder muitas noites de sono com os [...]]]></description>
			<content:encoded><![CDATA[<p>Ultimamente se tornou inevitável desenvolver programas que funcionam de maneira concorrente, já que os processadores com multiplos cores já estão em todo lugar, até mesmo nos celulares. E ao mesmo tempo que é extremamente prazeroso ver o seu software muito mais rápido graças a concorrência, também se pode perder muitas noites de sono com os problemas causados por erros no desenvolvimento de software concorrente. Neste post eu pretendo falar de maneira breve dos três principais problemas que podem surgir quando se desenvolve software concorrente. São eles: Starvation, Deadlocks e Race Conditions.</p>
<p><strong>Starvation</strong></p>
<p><strong>Starvation</strong> ocorre quando uma thread fica esperando uma resposta pra prosseguir e essa resposta nunca chega, logo, a thread permanece viva, ocupando recursos, mas não produzindo nada de útil para o software. Uma boa forma de tratar esse problema é sempre trabalhar com timeout e fluxo de exceção, para que caso a resposta não chegue em um determinado tempo seja seguido o fluxo de exceção e a thread possa finalizar o seu trabalho.</p>
<p><strong>Deadlocks</strong></p>
<p><strong>Deadlock</strong> ocorre se duas ou mais threads ficam aguardando uma a outra para realizar alguma ação ou liberar algum recurso, por exemplo, a thread A ficar aguardando a thread B liberar algum recurso e B ficar aguardando A terminar alguma ação pra liberar esse recurso, logo, ambas vão permanecer eternamente esperando. Não existe uma solução simples pra resolver esse problema como o timeout para o problema de Starvation, mas se a aplicação não possuir locks explicitos e estados mutáveis então ela estará a salvo de deadlocks, então esse pode ser um bom caminho a se seguir.</p>
<p><strong>Race Conditions</strong></p>
<p><strong>Race Condition</strong> ocorre se duas threads concorrem para usar o mesmo recurso ou dado. É um problema bem difícil de tratar pois o comportamento da aplicação se torna imprevisível e uma Race Condition pode ocorrer depois de meses do software em produção. Pra piorar, este problema não ocorre apenas quando duas threads tentam modificar o mesmo dado, ele pode correr quando uma thread tenta gravar um dado e a outra está tentando apenas ler este mesmo dado. Pra piorar ainda mais, existem casos aonde se o código não é otimizado com O JIT(Just In Time) Compiler a Race Condition não aparece, mas se o código é elegível ao JIT e é compilado então a Race Condition surge, basicamente porque a JVM passa a usar cache para acessar algumas variáveis e se outra thread muda o valor da variável, esse valor não é replicado para o cache. Neste caso citado a solução seria usar volatile e/ou synchronized.</p>
<p>Novamente não usar objetos mutáveis evitaria o problema de Race Conditions, por isso que imutabilidade tem sido um tema tão comentado ultimamente, e linguagens que pregam essa técnica tem ganhado cada vez mais força.</p>
<p>Para se aprofundar mais no assunto, inclusive com um código de exemplo que mostra uma Race Condition causada pelo JIT, recomendo a leitura do livro <strong>&#8220;Programming Concurrency on the JVM&#8221;</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2011/09/os-tres-principais-problemas-da-concorrencia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Manifesto conta o uso abusivo de Checked Exceptions</title>
		<link>http://www.hespanha.com.br/blog/2010/11/manifesto-conta-o-uso-abusivo-de-checked-exceptions/</link>
		<comments>http://www.hespanha.com.br/blog/2010/11/manifesto-conta-o-uso-abusivo-de-checked-exceptions/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 20:48:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=118</guid>
		<description><![CDATA[Resolvi escrever este post porque vejo que existe muita confusão, e talvez até mesmo desinformação da comunidade Java quando o assunto são exceções. Pra esclarecer as dúvidas resolvi ir até uma das maiores fontes de informação sobre boas práticas do Java que existe, o livro Effective Java. Pra começar, no item 40 do livro é [...]]]></description>
			<content:encoded><![CDATA[<p>Resolvi escrever este post porque vejo que existe muita confusão, e talvez até mesmo desinformação da comunidade Java quando o assunto são exceções.</p>
<p>Pra esclarecer as dúvidas resolvi ir até uma das maiores fontes de informação sobre boas práticas do Java que existe, o livro Effective Java.</p>
<p>Pra começar, no item 40 do livro é dito “Use Checked Exceptions for recoverable conditions”. Infelizmente eu vejo que em muitos projetos por aí Checked Exceptions viraram padrão e  todas as exceções do projeto são deste tipo. Isso é um ERRO que deixa o projeto chatissimo pra manter, porque com isso toda vez que você precisa chamar um método ou você tem que colocar ele dentro de um try/catch, ou senão tem que dar um throws na exceção. Da próxima vez que você precisar lançar uma exceção, por favor, pense por alguns momentos no seguinte: “O cara que pegar essa minha exceção vai poder fazer alguma coisa pra trata-lá?”. Se a sua reposta por NÃO, então você não deve usar uma Checked Exception.</p>
<p>Lidar com exceções em Java não é um assunto fácil, e no próprio livro o Joshua Bloch fala que não existe uma receita de bolo que resolva todos os casos. Mas de toda maneira, parece que um comodismo se instalou nos programadores Java, e ao invez de pensar no cenário, o que se tem feito é lançar uma Checked Exception e pronto, possivelmente incentivado por um pensamento do tipo “Se o cara quiser fazer alguma coisa ele faz, senão ele ignora, pelo menos eu fiz a minha parte”. No item 41 é dito “Avoid unnecessay use of checked exceptions”. É um desprazer trabalhar com uma API ou sistema cheio de checked exceptions.</p>
<p>Checked Exceptions são excelentes quando usadas na hora certa, pois dá poder pra você  corrigir algo que deu errado, mas são péssimas se usadas na hora errada!</p>
<p>Eu poderia tentar explicar mais sobre exceções, mas definitivamente é melhor ler o Effective Java, e a Bani traduziu esse capítulo de exceçõe, e disponibilizou no blog dela no seguinte link: <a href="http://vanessas.sites.uol.com.br/java/ej6.html">http://vanessas.sites.uol.com.br/java/ej6.html</a> . Minha recomendação é: LEIAM! É de graça, é pouca coisa, e com certeza você se tornará um programador melhor depois de ler, e vai pensar melhor antes de sair lançando checked exceptions por aí.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2010/11/manifesto-conta-o-uso-abusivo-de-checked-exceptions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A linguagem certa para cada problema! (Problema do Sudoku)</title>
		<link>http://www.hespanha.com.br/blog/2010/09/a-linguagem-certa-para-cada-problema-problema-do-sudoku/</link>
		<comments>http://www.hespanha.com.br/blog/2010/09/a-linguagem-certa-para-cada-problema-problema-do-sudoku/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 02:11:37 +0000</pubDate>
		<dc:creator>Luiz Hespanha</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[prolog]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=85</guid>
		<description><![CDATA[Cada vez mais na área de programação aquela história de se especializar em uma linguagem, e resolver todos os problemas com ela está sendo questionada. E realmente, como vocês verão neste post, esse questionamento faz todo sentido. Existe uma linguagem mais adequada para resolver cada problema, e por isso, é obrigação do programador conhecer diversas [...]]]></description>
			<content:encoded><![CDATA[<p>Cada vez mais na área de programação aquela história de se especializar em uma linguagem, e resolver todos os problemas com ela está sendo questionada. E realmente, como vocês verão neste post, esse questionamento faz todo sentido. Existe uma linguagem mais adequada para resolver cada problema, e por isso, é obrigação do programador conhecer diversas linguagens, no mínimo uma de cada paradigma, para poder escolher qual linguagem se encaixa melhor para determinado problema.</p>
<p>Considere o problema de implementar um resolvedor de Sudoku, ou seja, você deve implementar um programa que dado um tabuleiro do jogo parcialmente preenchido, seu programa deve devolver o tabuleiro totalmente preenchido.</p>
<p>Não sei se é a melhor que existe, mas a melhor linguagem que eu conheço pra resolver este problema é Prolog. Sim, aquela linguagem de programação que a gente vê na faculdade no curso de Inteligência Artificial. Prolog é uma linguagem de programação declarativa, baseada em lógica de primeira ordem. Em Prolog temos:</p>
<ol>
-<strong>Fatos:</strong> Uma afirmação básica. (Ex: Azalão é um cavalo; cavalo gosta de grama.)</ol>
<p></p>
<ol>
-<strong>Regras</strong>: É uma inferência sobre um fato. (Ex: Um animal gosta de grama se ela é um cavalo.)</ol>
<p></p>
<ol>
-<strong>Query</strong>: Uma questão (Ex: Azalão gosta de grama?)</ol>
<p>E é isso, ou seja, bem diferente de uma linguagem de programação imperativa, como Java por exemplo.</p>
<p>Agora vamos definir as regras para verificar se um jogo de Sudoku é valido, e embaixo de cada regra vamos definir o código em Prolog para implementar tal regra. São elas:</p>
<p>Supondo que nosso problema é definido como:</p>
<pre name="code" class="prolog">
sudoku(Entrada, Solucao)
</pre>
<p><strong>Regra 1)</strong> Para um jogo resolvido, os números na entrada e na saída devem ser os mesmos.</p>
<pre name="code" class="prolog">
sudoku(Entrada, Solucao) :- Solucao = Entrada.
</pre>
<p><strong>Regra 2)</strong> Um tabuleiro de Sudoku é uma grade de 81 elementos, com valores de 1-9.</p>
<pre name="code" class="prolog">
Entrada = [S11, S12, S13, S14, S15, S16, S17, S18, S19,
		  S21, S22, S23, S24, S25, S26, S27, S28, S29,
		  S31, S32, S33, S34, S35, S36, S37, S38, S39,
		  S41, S42, S43, S44, S45, S46, S47, S48, S49,
		  S51, S52, S53, S54, S55, S56, S57, S58, S59,
		  S61, S62, S63, S64, S65, S66, S67, S68, S69,
		  S71, S72, S73, S74, S75, S76, S77, S78, S79,
		  S81, S82, S83, S84, S85, S86, S87, S88, S89,
		  S91, S92, S93, S94, S95, S96, S97, S98, S99],
	fd_domain(Solucao, 1, 9).
</pre>
<p><strong>Regra 3)</strong> Um tabuleiro tem 9 linhas, 9 colunas e 9 quadrados.</p>
<pre name="code" class="prolog">
Row1 = [S11, S12, S13, S14, S15, S16, S17, S18, S19],
Row2 = [S21, S22, S23, S24, S25, S26, S27, S28, S29],
Row3 = [S31, S32, S33, S34, S35, S36, S37, S38, S39],
Row4 = [S41, S42, S43, S44, S45, S46, S47, S48, S49],
Row5 = [S51, S52, S53, S54, S55, S56, S57, S58, S59],
Row6 = [S61, S62, S63, S64, S65, S66, S67, S68, S69],
Row7 = [S71, S72, S73, S74, S75, S76, S77, S78, S79],
Row8 = [S81, S82, S83, S84, S85, S86, S87, S88, S89],
Row9 = [S91, S92, S93, S94, S95, S96, S97, S98, S99],

Col1 = [S11, S21, S31, S41, S51, S61, S71, S81, S91],
Col2 = [S12, S22, S32, S42, S52, S62, S72, S82, S92],
Col3 = [S13, S23, S33, S43, S53, S63, S73, S83, S93],
Col4 = [S14, S24, S34, S44, S54, S64, S74, S84, S94],
Col5 = [S15, S25, S35, S45, S55, S65, S75, S85, S95],
Col6 = [S16, S26, S36, S46, S56, S66, S76, S86, S96],
Col7 = [S17, S27, S37, S47, S57, S67, S77, S87, S97],
Col8 = [S18, S28, S38, S48, S58, S68, S78, S88, S98],
Col9 = [S19, S29, S39, S49, S59, S69, S79, S89, S99],

Square1 = [S11, S12, S13, S21, S22, S23, S31, S32, S33],
Square2 = [S14, S15, S16, S24, S25, S26, S34, S35, S36],
Square3 = [S17, S18, S19, S27, S28, S29, S37, S38, S39],
Square4 = [S41, S42, S43, S51, S52, S53, S61, S62, S63],
Square5 = [S44, S45, S46, S54, S55, S56, S64, S65, S66],
Square6 = [S47, S48, S49, S57, S58, S59, S67, S68, S69],
Square7 = [S71, S72, S73, S81, S82, S83, S91, S92, S93],
Square8 = [S74, S75, S76, S84, S85, S86, S94, S95, S96],
Square9 = [S77, S78, S79, S87, S88, S89, S97, S98, S99].
</pre>
<p><strong>Regra 4)</strong> Não pode haver números repetidos nas linhas, colunas e quadrados.</p>
<pre name="code" class="prolog">
valid([]).
valid([Head | Tail]) :-
	fd_all_different(Head), valid(Tail).

valid([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9,
     Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9,
     Square1, Square2, Square3, Square4, Square5, Square6, Square7, Square8, Square9]).
</pre>
<p>E pronto, acredite ou não, o problema está resolvido. Como vocês viram, a única coisa que fizemos foi definir as regras do problema e pronto, o Prolog resolve o problema pra você. Agora pense como você resolveria esse problema em Java por exemplo. Com certeza definir as regras acima seria apenas o começo.</p>
<p>Mas muitos devem estar se perguntando: &#8220;Tá, mas meu programa é feito em Java, o que eu vou fazer com esse código em Prolog?&#8221;. Mas é aí que entra o principal ponto, é possível integrar código em Prolog com diversas outras linguagems, por isso que hoje em dia não é mais preciso resolver todos os problemas de um sistema com a mesma linguagem.</p>
<p>E aí, animou a conhecer mais Prolog? </p>
<p>Segue abaixo o código completo do problema. Para rodar essa implementação é necessário o <a href="http://www.gprolog.org/">gprolog</a>, já que usamos algumas funções pré-definidas existentes apenas nesta ferramenta.</p>
<pre name="code" class="prolog">
valid([]).
valid([Head | Tail]) :-
	fd_all_different(Head), valid(Tail).

sodoku(Puzzle, Solution) :-
	Solution = Puzzle,
	Puzzle = [S11, S12, S13, S14, S15, S16, S17, S18, S19,
		  S21, S22, S23, S24, S25, S26, S27, S28, S29,
		  S31, S32, S33, S34, S35, S36, S37, S38, S39,
		  S41, S42, S43, S44, S45, S46, S47, S48, S49,
		  S51, S52, S53, S54, S55, S56, S57, S58, S59,
		  S61, S62, S63, S64, S65, S66, S67, S68, S69,
		  S71, S72, S73, S74, S75, S76, S77, S78, S79,
		  S81, S82, S83, S84, S85, S86, S87, S88, S89,
		  S91, S92, S93, S94, S95, S96, S97, S98, S99],
	fd_domain(Solution, 1, 9),

	Row1 = [S11, S12, S13, S14, S15, S16, S17, S18, S19],
	Row2 = [S21, S22, S23, S24, S25, S26, S27, S28, S29],
	Row3 = [S31, S32, S33, S34, S35, S36, S37, S38, S39],
	Row4 = [S41, S42, S43, S44, S45, S46, S47, S48, S49],
	Row5 = [S51, S52, S53, S54, S55, S56, S57, S58, S59],
	Row6 = [S61, S62, S63, S64, S65, S66, S67, S68, S69],
	Row7 = [S71, S72, S73, S74, S75, S76, S77, S78, S79],
	Row8 = [S81, S82, S83, S84, S85, S86, S87, S88, S89],
	Row9 = [S91, S92, S93, S94, S95, S96, S97, S98, S99],

	Col1 = [S11, S21, S31, S41, S51, S61, S71, S81, S91],
	Col2 = [S12, S22, S32, S42, S52, S62, S72, S82, S92],
	Col3 = [S13, S23, S33, S43, S53, S63, S73, S83, S93],
	Col4 = [S14, S24, S34, S44, S54, S64, S74, S84, S94],
	Col5 = [S15, S25, S35, S45, S55, S65, S75, S85, S95],
	Col6 = [S16, S26, S36, S46, S56, S66, S76, S86, S96],
	Col7 = [S17, S27, S37, S47, S57, S67, S77, S87, S97],
	Col8 = [S18, S28, S38, S48, S58, S68, S78, S88, S98],
	Col9 = [S19, S29, S39, S49, S59, S69, S79, S89, S99],

	Square1 = [S11, S12, S13, S21, S22, S23, S31, S32, S33],
	Square2 = [S14, S15, S16, S24, S25, S26, S34, S35, S36],
	Square3 = [S17, S18, S19, S27, S28, S29, S37, S38, S39],
	Square4 = [S41, S42, S43, S51, S52, S53, S61, S62, S63],
	Square5 = [S44, S45, S46, S54, S55, S56, S64, S65, S66],
	Square6 = [S47, S48, S49, S57, S58, S59, S67, S68, S69],
	Square7 = [S71, S72, S73, S81, S82, S83, S91, S92, S93],
	Square8 = [S74, S75, S76, S84, S85, S86, S94, S95, S96],
	Square9 = [S77, S78, S79, S87, S88, S89, S97, S98, S99],

	valid([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9,
	       Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9,
	       Square1, Square2, Square3, Square4, Square5, Square6, Square7, Square8, Square9]).
</pre>
<p>Segue um exemplo de entrada:</p>
<pre name="code" class="prolog">
sodoku([9,4,_,1,_,2,_,5,8,
 6,_,_,_,5,_,_,_,4,
 _,_,2,4,_,3,1,_,_,
 _,2,_,_,_,_,_,6,_,
 5,_,8,_,2,_,4,_,1,
 _,6,_,_,_,_,_,8,_,
 _,_,1,6,_,8,7,_,_,
 7,_,_,_,4,_,_,_,3,
 4,3,_,5,_,9,_,1,2], Solution).
</pre>
<p>Abraços e até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2010/09/a-linguagem-certa-para-cada-problema-problema-do-sudoku/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>O que esperar das linguagens de programação para o futuro?</title>
		<link>http://www.hespanha.com.br/blog/2010/07/linguagens-de-programacao-modernas/</link>
		<comments>http://www.hespanha.com.br/blog/2010/07/linguagens-de-programacao-modernas/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 18:53:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=71</guid>
		<description><![CDATA[Dizem que os melhores perfumes são aqueles que estão nos menores frascos. Ao menos pelo show que o Rod Pike do Google deu quando falou no OSCON 2010, parece que isso vale para palestras também. Foram doze minutos e meio de um conteúdo riquissímo pra fazer qualquer programador refletir. Nesta palestra, o Rod tentou mostrar [...]]]></description>
			<content:encoded><![CDATA[<p>Dizem que os melhores perfumes são aqueles que estão nos menores frascos. Ao menos pelo show que o Rod Pike do Google deu quando falou no OSCON 2010, parece que isso vale para palestras também. Foram doze minutos e meio de um conteúdo riquissímo pra fazer qualquer programador refletir.</p>
<p>Nesta palestra, o Rod tentou mostrar como as principais linguagens que dominam o mercado hoje são burocráticas e chatas de trabalhar. Ele deixa claro que são linguagens robustas e de qualidade, isso é um fato inquestionável, mas elas podiam ser mais amigáveis.</p>
<p>O Rod usou a conhecida do frase do Norvig que diz “patterns are a a demonstration of weakness in a language” para embassar seus argumentos, e também não deixou de mostrar muitos códigos para comprovar o quão verboso é fazer algumas coisas em linguagens como o Java por exemplo. Além disso, também foi falado que o hardware evoluiu muito esses últimos anos, hoje em dia qualquer um tem um computador com dois cores no mínimo, mas nas linguagens de programação tradicionais por assim dizer, não é nada trivial fazer uso deste poder.</p>
<p>Após mostrar todos esses pontos, o Rod expõe quais são os objetivos das linguagens de programação para o futuro. Ou seja, o que precisa ser feito para que elas se tornem melhores, e no final, puxa um pouquinho a sardinha pro lado dele, falando um pouco da Go, a linguagem de programação do Google.</p>
<p>Um fato importante é que para conseguir ver tudo isso que o Rod viu e falou, é preciso pensar fora da caixa como dizem por aí, e aprender novas linguagens de programação. Eu atualmente tenho dado uma olhada mais profunda em duas: Python e Haskell, e não estou me arrependendo. O pessoal pode falar: “Mas aonde você vai usar Haskell profissionalmente?”. Bom, talvez eu nunca use Haskell profissionalmente, mas com certeza seja qual for a linguagem que eu trabalhar, aprender Haskell e programação funcional me tornará um programador melhor.</p>
<p>Enfim, para quem ainda não viu, não deixe de ver essa palestra. E viva a internet, aonde você consegue ter acesso a uma palestra de um evento de fora do país quase que no mesmo dia em que a palestra foi dada.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/5kj5ApnhPAE&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/5kj5ApnhPAE&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="385"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2010/07/linguagens-de-programacao-modernas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Participação no Y! Hack Day 2010</title>
		<link>http://www.hespanha.com.br/blog/2010/03/participacao-no-y-hack-day-2010/</link>
		<comments>http://www.hespanha.com.br/blog/2010/03/participacao-no-y-hack-day-2010/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 03:44:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=67</guid>
		<description><![CDATA[Esse fim de semana eu participei do Yahoo Hack Day Brasil. Foi definitivamente o melhor evento de computação que eu já fui, perfeito, e o melhor de tudo, foi de graça. O objetivo do evento foi construir uma aplicação qualquer usando as APIs que o Yahoo disponibiliza, excelentes APIs, diga-se de passagem. Eu formei um [...]]]></description>
			<content:encoded><![CDATA[<p>Esse fim de semana eu participei do Yahoo Hack Day Brasil. Foi definitivamente o melhor evento de computação que eu já fui, perfeito, e o melhor de tudo, foi de graça. O objetivo do evento foi construir uma aplicação qualquer usando as APIs que o Yahoo disponibiliza, excelentes APIs, diga-se de passagem.</p>
<p>Eu formei um time com dois amigos do UOL(<a href="http://www.twitter.com/rafael_manoel">Rafael</a> e <a href="http://www.twitter.com/wandi">Wandi</a>) e um amigo feito no Rails Summit(<a href="http://www.twiter.com/marcos_sousa">Marcos Sousa</a>).</p>
<p>Falando um pouco do nosso projeto, ele consistiu de um site no qual o usuário informava um endereço da cidade de São Paulo, e a partir disso o site retornava dados sobre a criminalidade na região daquele endereço. Pra chegar nisso, a gente fez o seguinte:</p>
<p>1) Recuperamos todos os endereços de delegacias da cidade de São Paulo e pra cada um obtivemos a latitude e a longitude usando a API do Yahoo Maps. Depois salvamos na nossa aplicação essas informações.</p>
<p>2) Dado o endereço do usuário nós usamos a API do Yahoo Maps para obter a latitude e longitude do endereço.</p>
<p>3) Calculamos qual a delegacia mais próxima do endereço informado usando os dados da latitude e longitude que tinhamos na mão.</p>
<p>4) Depois de encontrada a delegacia mais próxima nós vamos em um site de dados da secretaria de segurança da cidade de São Paulo, e usamos a fantástica API YQL para obter os dados daquela delegacia. Os dados no site da secretaria de segurança ficam expostos em uma tabela HTML, então o YQL ajuda muito para filtrar estes dados.</p>
<p>5) Com os dados na mão é só exibir para o usuário o indice de criminalidade naquela região.</p>
<p>Bom, quem quiser conferir o endereço do nosso projeto é:</p>
<p><a href="http://violenciasp.appspot.com">http://violenciasp.appspot.com</a></p>
<p>O layout tem algumas falhas, principalmente em browsers no Windows, mas não se esqueçam que é um projeto feito em 24hs. hehehe Quem sabe no futuro a gente de um tapa e melhore o site.</p>
<p>Infelizmente o nosso hack não nos rendeu nenhum prêmio, mas com certeza o aprendizado que o evento proporcionou valeu muito! E pra quem não conhece, eu recomendo muito dar uma olhada nas APIs do Yahoo, especialmente nesse tal de YQL que é show de bola!</p>
<p>Até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2010/03/participacao-no-y-hack-day-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simulador de algoritmos de geometria computacional escrito em Python</title>
		<link>http://www.hespanha.com.br/blog/2010/01/simulador-de-algoritmos-de-geometria-computacional-escrito-em-python/</link>
		<comments>http://www.hespanha.com.br/blog/2010/01/simulador-de-algoritmos-de-geometria-computacional-escrito-em-python/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 02:18:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=60</guid>
		<description><![CDATA[No semestre passado eu tive a oportunidade de fazer um projeto muito bacana no mestrado. Eu cursei uma matéria chamada Geometria computacional, que como o próprio nome diz, estuda algoritmos clássicos para resolver problemas geométricos. Como projeto final, tivemos que criar um “simulador visual” de um dos problemas geométricos que estudamos. A idéia era implementar [...]]]></description>
			<content:encoded><![CDATA[<p>No semestre passado eu tive a oportunidade de fazer um projeto muito bacana no mestrado. Eu cursei uma matéria chamada Geometria computacional, que como o próprio nome diz, estuda algoritmos clássicos para resolver problemas geométricos. Como projeto final, tivemos que criar um “simulador visual” de um dos problemas geométricos que estudamos. A idéia era implementar o algoritmo força-bruta que resolve o problema e um algoritmo assintoticamente mais rápido, tudo isso de uma forma que o usuário pudesse ver o que o algoritmo está fazendo a cada instante.</p>
<p>Eu e mais um colega de classe resolvemos implementar os algoritmos que resolvem o problema de localizar intersecção de segmentos no plano, ou seja, dado um conjunto de n retas no plano localizar quais delas se intersectam. O <a href="http://www.ime.usp.br/~alexis">Alexis</a>, um ex-aluno do ime-usp, desenvolveu no ano que ele fez essa matéria toda uma interface gráfica bem modular para esse tipo de projeto feita em Python. Como Python é uma linguagem muito massa e seria bem mais simples usar essa interface que ele desenvolveu do que criar uma nossa do zero, resolvemos usar ela para o nosso projeto.</p>
<p>Implementamos um algoritmo conhecido como <a href="http://softsurfer.com/Archive/algorithm_0108/algorithm_0108.htm">Shamos &#038; Hoey(SH)</a> que encontra a primeira interseção em um conjunto de n segmentos de reta. Esse algoritmo possui complexidade O(nlgn), e para atingir essa complexidade ele requer uma estrutura de dados que busca um elemento em um conjunto de n elementos em tempo O(lgn). Sendo assim, resolvemos implementar o algoritmo com três sabores: Com Árvore de Busca Binária Balanceada, Árvore de Busca Binária Sem Balanceamento e Skip List. A idéia resumida do algoritmo é analisar todas as retas, mas ao invés de testar a intersecção de cada uma com todas as outras, ele testa apenas a reta logo acima e a logo abaixo da que está sendo analisada, pois obviamente, se estas duas não intersectam a reta, nenhuma outra intersecta, dada uma linha de varredura sobre o eixo x.  Além disso, implementamos a versão Força-Bruta que consome tempo O(nˆ2), já que pra cada reta analisada, ele verifica a intersecção com todas as outras.</p>
<p>Segue abaixo alguns screenshots com o resultado final:</p>
<p><img src="http://www.hespanha.com.br/images/proj1.png" alt="Tela inicial" /></p>
<p><img src="http://www.hespanha.com.br/images/proj2.png" alt="Após execução do algoritmo" /></p>
<p> No exemplo mostrado, como a árvore de busca não crescia muito, o tempo entre a execução com árvore balanceada e não balanceada foram equivalentes, mas em casos onde a árvore cresce(existem exemplos deste no código) é bem bacana ver a diferença que dá usar uma árvore balanceada. A diferença entre o algoritmo de SH e o Força-Bruta então é gritante. Um programa como esse é legal para abrir os olhos daqueles que não dão valor para Analise de Algoritmos. Se você não acredita o quanto um algoritmo O(nlgn) é melhor que um O(nˆ2), agora você pode ver e comprovar. =)</p>
<p>Coloquei o código no GitHub para caso alguém se interesse por olhar e/ou rodar o programa. Está em <a href="http://github.com/luizhespanha/geometry-algorithms-simulation">http://github.com/luizhespanha/geometry-algorithms-simulation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2010/01/simulador-de-algoritmos-de-geometria-computacional-escrito-em-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Repositório de códigos de campeonatos de programação</title>
		<link>http://www.hespanha.com.br/blog/2009/12/repositorio-de-codigos-de-campeonatos-de-programacao/</link>
		<comments>http://www.hespanha.com.br/blog/2009/12/repositorio-de-codigos-de-campeonatos-de-programacao/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 19:54:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.hespanha.com.br/blog/?p=56</guid>
		<description><![CDATA[Como muitos que me conhecem sabem, eu sou um grande fã de campeonatos de programação. Na época da graduação eu participei por 2 anos consecutivos da Maratona de Programação, e hoje em dia, mesmo não podendo mais participar, ainda me divirto resolvendo problemas em sites como: TopCoder, br.spoj.pl e uva. No próximo ano eu pretendo [...]]]></description>
			<content:encoded><![CDATA[<p>Como muitos que me conhecem sabem, eu sou um grande fã de campeonatos de programação. Na época da graduação eu participei por 2 anos consecutivos da <a href="http://maratona.ime.usp.br">Maratona de Programação</a>, e hoje em dia, mesmo não podendo mais participar, ainda me divirto resolvendo problemas em sites como: <a href="http://www.topcoder.com">TopCoder</a>, <a href="http://br.spoj.pl">br.spoj.pl</a> e <a href="http://uva.onlinejudge.org/">uva</a>.</p>
<p>No próximo ano eu pretendo participar do <a href="http://code.google.com/codejam/">Google Code Jam</a> pra valer, pra conseguir um resultado honroso. E pra isso, eu estipulei uma meta de resolver um problema por dia útil da semana, ou seja, aproximadamente 20 problemas por mês.</p>
<p>A partir dessa idéia surgiu uma outra de disponibilizar o códigos desses problemas que eu resolver em um repositório. Dessa idéia surgiu o: <a href="http://github.com/luizhespanha/maratona-programacao">http://github.com/luizhespanha/maratona-programacao</a>.</p>
<p>A idéia de disponibilizar os códigos não é muito bem vista pela comunidade que gosta destes campeonatos, pois isso acaba tirando a graça do desafio de outras pessoas, porém, o Google Code JAM disponibiliza o código de todos os concorrentes, e eu achei muito bacana, porque mesmo tendo resolvido um problema, eu tive a oportunidade de ver os códigos do ACRush, e ver como ele programa, algo que com certeza vale a pena. Logo, cabe a quem se interessar avaliar se é interessante ou não olhar um código do repositório sem tentar resolver primeiro.</p>
<p>Espero que consiga manter minha meta. Para problemas mais elaborados também pretendo criar um post com algumas explicações.</p>
<p>Até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hespanha.com.br/blog/2009/12/repositorio-de-codigos-de-campeonatos-de-programacao/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

