├── .editorconfig ├── .gitignore ├── .gitmodules ├── README.md ├── angularjs ├── 001-guia-definitivo-para-aprender-angularjs.md ├── 002-aprenda-angularjs-com-5-exemplos.md ├── 003-use-angularjs-para-potencializar-sua-webapp.md ├── 004-mais-magicas-angularjs-para-turbinar-sua-webapp.md └── 005-entendendo-diretivas.md ├── bdd └── 001-bdd-with-js.md ├── elixir └── construindo-simples-armazenador-usando-logs-parte-1.md ├── handlebars └── 001-aprenda-tudo-sobre-handlebars.md ├── img ├── angularJS-5-exemplos.png ├── callback-js.png ├── guia-definitivo-angular.png ├── js-prototype.png ├── node-absolute-begginer.png └── traduz-ai.png ├── javascript ├── 001-como-aprender-js-corretamente.md ├── 002-objetos-js-em-detalhe.md ├── 003-escopo-de-variavel-js-e-hoisting-explicado.md ├── 004-entenda-closures-no-javaScript-com-facilidade.md ├── 005-prototipos-javascript-em-uma-linguagem-simples.md ├── 006-entenda-callbacks-js.md ├── 007-um-mergulho-no-javascript-puro.md ├── 008-programacao-funcional-prioridade-2015.md ├── 009-uma-suave-introducao-ao-javascript-parte-1.md ├── 010-uma-suave-introducao-ao-javascript-parte-2.md ├── 011-uma-suave-introducao-ao-javascript-parte-3.md └── 012-uma-suave-introducao-ao-javascript-parte-4.md ├── mongodb └── 001-uma-introducao-ao-mongodb.md ├── nodejs ├── 001-guia-para-iniciantes-absolutos-em-nodejs.md └── 002-simples-guia-nodejs-jade-express-mongodb.md ├── programacao-funcional └── beleza-da-programacao-funcional.md ├── react ├── 01-sua-linha-do-tempo-para-aprender-react.md └── 02-introducao-ao-react-para-pessoas-que-sabem-apenas-jquery.md ├── roteiros └── design-de-sistemas │ ├── 00-o-que-e-isso.md │ └── README.md └── series ├── entao-voce-quer-ser-um-programador-funcional ├── README.md ├── parte-1.md ├── parte-2.md ├── parte-3.md └── parte-4.md ├── perguntas-desconfortaveis ├── README.md ├── pd-001.md └── pd-002.md └── voce-nao-precisa-de-jquery ├── 00-intro.md ├── 01-seletores.md ├── 02-manipulacao-dom.md └── README.md /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | [*] 3 | charset = utf-8 4 | end_of_line = lf 5 | insert_final_newline = false 6 | trim_trailing_whitespace = true 7 | indent_style = tab 8 | indent_size = 4 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.sw* 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "javascript/mdo-code-guide"] 2 | path = javascript/mdo-code-guide 3 | url = git@github.com:diegoeis/code-guide.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![traduz ai](img/traduz-ai.png) 2 | 3 | > Coleção de artigos sobre desenvolvimento e engenharia de software traduzidos para pt-br 4 | 5 | ## Como Ajudar 6 | 7 | Além dos materiais separados para tradução, você pode contribuir através da indicação de novos artigos para as traduções e/ou com as traduções/revisões. Deixe sua contribuição **[aqui](https://github.com/ericdouglas/traduz-ai/issues)**. 8 | 9 | ## Tópicos 10 | 11 | - [Como Ajudar](#como-ajudar) 12 | - [Tópicos](#tópicos) 13 | - [Roteiros](#roteiros) 14 | - [Séries](#séries) 15 | - [AngularJS](#angularjs) 16 | - [Behaviour Driven Development](#behaviour-driven-development) 17 | - [Elixir](#elixir) 18 | - [Handlebars.js](#handlebarsjs) 19 | - [JavaScript](#javascript) 20 | - [MongoDB](#mongodb) 21 | - [Node.js](#nodejs) 22 | - [Programação Funcional](#programação-funcional) 23 | - [React](#react) 24 | 25 | ## Roteiros 26 | 27 | 1. [Design de Sistemas](roteiros/design-de-sistemas/README.md) `engenharia de software` 28 | 29 | ## Séries 30 | 31 | - [Você não precisa de jQuery](series/voce-nao-precisa-de-jquery) `javascript` 32 | - [Então você quer ser um Programador Funcional?](series/entao-voce-quer-ser-um-programador-funcional) `javascript` `programação funcional` 33 | - [Perguntas desconfortáveis](series/perguntas-desconfortaveis) 34 | 35 | ## AngularJS 36 | 37 | 1. Guia Definitivo para Aprender AngularJS em Um Dia - [`Tradução`](angularjs/001-guia-definitivo-para-aprender-angularjs.md) [`Original`](http://toddmotto.com/ultimate-guide-to-learning-angular-js-in-one-day/) 38 | 1. Aprenda AngularJS com estes 5 exemplos práticos - [`Tradução`](angularjs/002-aprenda-angularjs-com-5-exemplos.md) [`Original`](http://tutorialzine.com/2013/08/learn-angularjs-5-examples/) 39 | 1. Use AngularJS para Potencializar sua Aplicação Web - [`Tradução`](angularjs/003-use-angularjs-para-potencializar-sua-webapp.md#use-angularjs-para-potencializar-suas-aplica%C3%A7%C3%B5es-web) [`Original`](http://www.yearofmoo.com/2012/08/use-angularjs-to-power-your-web-application.html) 40 | 1. Mais mágicas do AngularJS para turbinar sua Webapp - [`Tradução`](angularjs/004-mais-magicas-angularjs-para-turbinar-sua-webapp.md#mais-m%C3%A1gicas-do-angularjs-para-turbinar-sua-webapp) [`Original`](http://www.yearofmoo.com/2012/10/more-angularjs-magic-to-supercharge-your-webapp.html) 41 | 1. Entendendo Diretivas - [`Tradução`](angularjs/005-entendendo-diretivas.md) [`Original`](https://github.com/angular/angular.js/wiki/Understanding-Directives) 42 | 43 | ## Behaviour Driven Development 44 | 45 | 1. Behaviour Driven Development com JavaScript - [`Tradução`](bdd/001-bdd-with-js.md) [`Original`](http://gajus.com/blog/1/behaviour-driven-development-with-javascript) 46 | 47 | ## Elixir 48 | 49 | 1. Construindo um Simples Armazenador de Chave-Valor em Elixir, usando Logs - Parte 1 - [`Tradução`](elixir/construindo-simples-armazenador-usando-logs-parte-1.md) [`Original`](https://www.poeticoding.com/build-a-simple-persistent-key-value-store-in-elixir-using-logs-part-1/) 50 | 51 | ## Handlebars.js 52 | 53 | 1. Aprenda Tudo sobre Handlebars.js Templating JavaScript - [`Tradução`](handlebars/001-aprenda-tudo-sobre-handlebars.md#aprenda-tudo-sobre-handlebarsjs-templating-javascript) [`Original`](http://javascriptissexy.com/handlebars-js-tutorial-learn-everything-about-handlebars-js-javascript-templating/) 54 | 55 | ## JavaScript 56 | 57 | 1. Como Aprender JavaScript Corretamente - [`Tradução`](javascript/001-como-aprender-js-corretamente.md#como-aprender-javascript-corretamente--javascriptis-sexy) [`Original`](http://javascriptissexy.com/how-to-learn-javascript-properly/) 58 | 1. Objetos JavaScript em Detalhe - [`Tradução`](javascript/002-objetos-js-em-detalhe.md#objetos-javascript-em-detalhe) [`Original`](http://javascriptissexy.com/javascript-objects-in-detail/) 59 | 1. Escopo de Variável e Hoisting no JavaScript Explicado - [`Tradução`](javascript/003-escopo-de-variavel-js-e-hoisting-explicado.md#escopo-de-vari%C3%A1vel-javascript-e-hoisting-explicado) [`Original`](http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/) 60 | 1. Entenda Closures no JavaScript com Facilidade - [`Tradução`](javascript/004-entenda-closures-no-javaScript-com-facilidade.md#entenda-closures-no-javascript-com-facilidade) [`Original`](http://javascriptissexy.com/understand-javascript-closures-with-ease/) 61 | 1. Protótipos JavaScript em uma Linguagem Simples - [`Tradução`](javascript/005-prototipos-javascript-em-uma-linguagem-simples.md#prot%C3%B3tipos-javascript-em-uma-linguagem-simples) [`Original`](http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/) 62 | 1. Entenda Funções Callback no JavaScript e Use-as - [`Tradução`](javascript/006-entenda-callbacks-js.md) [`Original`](http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/) 63 | 1. Um Mergulho no JavaScript Puro - [`Tradução`](javascript/007-um-mergulho-no-javascript-puro.md) [`Original`](http://blog.adtile.me/2014/01/16/a-dive-into-plain-javascript/) 64 | 1. Programação Funcional Deve Ser Sua Prioridade número #1 em 2015 - [`Tradução`](javascript/008-programacao-funcional-prioridade-2015.md) [`Original`](https://medium.com/@jugoncalves/functional-programming-should-be-your-1-priority-for-2015-47dd4641d6b9) 65 | 1. Uma Suave Introdução ao JavaScript Funcional: Parte 1 - [`Tradução`](javascript/009-uma-suave-introducao-ao-javascript-parte-1.md) [`Original`](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-intro/) 66 | 1. Uma Suave Introdução ao JavaScript Funcional: Parte 2 - [`Tradução`](javascript/010-uma-suave-introducao-ao-javascript-parte-2.md) [`Original`](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-arrays/) 67 | 1. Uma Suave Introdução ao JavaScript Funcional: Parte 3 - [`Tradução`](javascript/011-uma-suave-introducao-ao-javascript-parte-3.md) [`Original`](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-functions/) 68 | 1. Uma Suave Introdução ao JavaScript Funcional: Parte 4 - [`Tradução`](javascript/012-uma-suave-introducao-ao-javascript-parte-4.md) [`Original`](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-style/) 69 | 70 | ## MongoDB 71 | 72 | 1. Uma introdução ao MongoDB - [`Tradução`](mongodb/001-uma-introducao-ao-mongodb.md) [`Original`](https://scotch.io/tutorials/an-introduction-to-mongodb) 73 | 74 | ## Node.js 75 | 76 | 1. Guia Para Absolutos Iniciantes em Node.js - [`Tradução`](nodejs/001-guia-para-iniciantes-absolutos-em-nodejs.md) [`Original`](http://blog.modulus.io/absolute-beginners-guide-to-nodejs) 77 | 1. Guia para um dev. front-end iniciar Com Node.js, Express, Jade e MongoDB - [`Tradução`](nodejs/002-simples-guia-nodejs-jade-express-mongodb.md) [`Original`](http://cwbuecheler.com/web/tutorials/2013/node-express-mongo/) 78 | 79 | ## Programação Funcional 80 | 81 | 1. A beleza da recursão e pattern matching em linguagens de programação funcionais - [`Tradução`](programacao-funcional/beleza-da-programacao-funcional.md) [`Original`](https://dev.to/ericdouglas/the-beauty-of-recursion-and-pattern-matching-in-functional-programming-languages-hmn) 82 | 83 | ## React 84 | 85 | 1. Sua Linha do Tempo para Aprender React - [`Tradução`](react/01-sua-linha-do-tempo-para-aprender-react.md) [`Original`](https://daveceddia.com/timeline-for-learning-react/) 86 | 1. Introdução ao React para pessoas que sabem apenas o suficiente de jQuery para sobreviver - [`Tradução`](react/02-introducao-ao-react-para-pessoas-que-sabem-apenas-jquery.md) [`Original`](http://reactfordesigners.com/labs/reactjs-introduction-for-people-who-know-just-enough-jquery-to-get-by/) 87 | -------------------------------------------------------------------------------- /angularjs/002-aprenda-angularjs-com-5-exemplos.md: -------------------------------------------------------------------------------- 1 | ![Aprenda Angular 5 exemplos](../img/angularJS-5-exemplos.png) 2 | 3 | * **Artigo Original**: [Learn AngularJS With These 5 Practical Examples](http://tutorialzine.com/2013/08/learn-angularjs-5-examples/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | Você provavalemente ouviu sobre [AngularJS](http://angularjs.org/) - o empolgante framework open source desenvolvido pela Google, que muda a maneira que pensamos sobre as aplicações web. Temos muita coisa escrita sobre isso, mas eu ainda não encontrei algo que fosse escrito para desenvolvedores que preferem exemplos rápidos e práticos. Isto muda hoje. Abaixo você irá encontrar o básico da construção de blocos de aplicativos Angular - Models (Modelos), Views (Vistas), Controllers (Controladores), Services (Serviços) e Filters (Filtros) - explicados em 5 exemplos práticos que você pode editar diretamente no navegador*. Se você preferir abri-los no seu editor de códigos favorito, pegue o arquivo zip. 7 | 8 | Notas do tradutor: Caso deseje fazer as alterações no navegador (junto onde se apresenta o artigo), vá para o artigo original. Irei deixar também disponíveis no CodePen os códigos com os comentários traduzidos. 9 | 10 | Faça o download do código fonte dos exemplos com os comentários em português [aqui](https://doc-0g-1g-docs.googleusercontent.com/docs/securesc/f8bvcjen03911q1dff7brgoos9hvboh6/0i1jlajnp9aicdcbtk1pj9jqfm7aka3f/1382529600000/18036872927410112600/18036872927410112600/0B-ok-PijFYOPRDA4UXM4eWdmY2s?e=download&h=16653014193614665626&nonce=f19cr1b0jlu9m&user=18036872927410112600&hash=6ddugak9eqqiijugnojj0e7569jp74ef) 11 | 12 | Complementar a este artigo, leia o [Guia Definitivo de como aprender AngularJS](https://github.com/eoop/traduz-ai/blob/master/angularjs/001-guia-definitivo-para-aprender-angularjs.md#guia-definitivo-para-aprender-angularjs-em-um-dia) , pois nele encontramos melhores práticas para o desenvolvimento das aplicações Angular. Se você iniciar por este tutorial mais direto, recomendo que você o veja e depois refaça todos os exemplos embasados nas melhores práticas mostradas no Guia Definitivo. Ex: criar um namespace para aplicação, evitando as variáveis globais. 13 | 14 | Link para arquivo zip: [link](http://demo.tutorialzine.com/2013/08/learn-angularjs-5-examples/angularjs-examples.zip) 15 | 16 |

O que é AngularJS?

17 | 18 | De forma básica, AngularJS é um framework que liga seu HTML (views) com objetos JavaScript (models). Quando seus modelos mudam, a página é atualizada automaticamente. O contrário também é válido - um modelo, associado com um campo de texto, é atualizado quando o conteúdo do campo é alterado. O Angular manuseia toda essa 'cola' do código, então você não precisa atualizar manualmente o HTML ou escutadores (listeners) para os eventos, como você faz com jQuery. Como aliás, nenhum destes exemplos incluem jQuery! 19 | 20 | Para usar o AngularJS, você tem que incluí-lo na sua página antes do fechamento da tag body. [Google's CDN](https://developers.google.com/speed/libraries/devguide#angularjs) é recomendado para um carregamento mais rápido: 21 | 22 | 23 | ```html 24 | 25 | 26 | 27 | ``` 28 | 29 | O AngularJS lhe dá um grande número de [Diretivas](http://docs.angularjs.org/guide/directive) que permitem a associação de elementos HTML com os Modelos. Elas são atributos que iniciam com ng- e podem ser adicionadas a qualquer elemento. O mais importante atributo que você deve incluir em qualquer página, se você for usar o Angular, é o ng-app: 30 | 31 | ```html 32 | 33 | 34 | 35 | ``` 36 | 37 | Isso pode ser adicionado a um elemento que engloba o resto da página, como o elemento body ou uma div externa. O Angular olha para ele quando a página é carregada e automaticamente analisa todas as Diretivas que enxerga nos elementos filhos. 38 | 39 | Chega de teoria! Agora vamos ver algum código. 40 | 41 |

Menu de Navegação

42 | 43 | Para o primeiro exemplo, nós vamos construir um menu de navegação que destaca a entrada selecionada. O exemplo usa somente Diretivas do Angular, e é a mais simples aplicação possível de uso do framework. Click em no botão "Edit" para ver o código fonte. Ele está pronto para experimentação! 44 | 45 | * para testar no browser, vá para o artigo original * 46 | 47 | * Link para codepen com comentários traduzidos > [aqui](http://codepen.io/eoop/pen/FJeLu) 48 | 49 | No código acima, nós estamos usando as Diretivas Angular para definir e ler a variável ativa. Quando isso muda, causa no HTML uma atualização automática. Na terminologia Angular, esta variável é chamada um modelo. Está disponível para todas as diretivas no escopo atual, e pode ser acessada nos seus controladores (mais sobre estes no próximo exemplo). 50 | 51 | Se você já utilizou templates JavaScript antes, você é familiar com a sintaxe {{var}}. Quando o framework vê esta string, ele a substitui com o conteúdo da variável. Essa operação é repetida toda hora que a variável for modificada. 52 | 53 |

Editor Inline

54 | 55 | Para nosso segundo exemplo, nós vamos criar um simples editor inline - clicando no parágrafo vamos mostrar um tooltip (dica) com um campo de texto. Nós vamos usar um controlador que vai inicializar os modelos e declarar 2 métodos para alternar a visibilidade do tooltip. Controladores são funções regulares do JavaScript que são executadas automaticamente pelo Angular, e que são associadas com sua página usando a diretiva `ng-controller`: 56 | 57 | * para testar no browser, vá para o artigo original * 58 | 59 | * Link para codepen com comentários traduzidos > [aqui](http://codepen.io/eoop/pen/hbLKi) 60 | 61 | Quando a função controladora é executada, ela pega o objeto especial $scope como um parâmetro, adicionando propriedades ou funções para torná-los disponíveis para o View. Usando o ng-model ligado no campo de texto, faz com que o Angular atualize esta variável quando o valor do campo muda (fazendo com que re-renderizemos o parágrafo com o valor). 62 | 63 |

3. Formulário de Pedido

64 | 65 | Neste exemplo, nós vamos criar um formulário com um preço total atualizado em tempo real, usando outra das úteis propriedades do Angular - os [Filtros](http://docs.angularjs.org/guide/dev_guide.templates.filters). Filtros permitem que você modifique os modelos e possa os encadear juntos usando o caracter barra vertical `|`. No exemplo ebaixo, eu estou usando o [currency filter](http://docs.angularjs.org/api/ng.filter:currency), para tornar um número em um preço corretamente formatado, completo com um símbolo dólar e centavos. Você pode facilmente criar seus próprios filtros, como você verá no exemplo #4. 66 | 67 | * para testar no browser, vá para o artigo original * 68 | 69 | * Link para codepen com comentários traduzidos > [aqui](http://codepen.io/eoop/pen/Jnbjf) 70 | 71 | A ligação [`ng-repeat`](docs http://docs.angularjs.org/api/ng.directive:ngRepeat) é outra propriedade útil do framework. Ela permite que você faça um loop em um array de item e gere um marcador para eles. Quando um item é deletado, isso é atualizado de forma inteligente. 72 | 73 | Nota: Para uma versão completa, veja este tutorial http://tutorialzine.com/2013/05/quick-tip-convert-backbone-to-angularjs/, que foi baseado neste [outro](http://tutorialzine.com/2013/04/services-chooser-backbone-js/), escrito com Backbone.js. 74 | 75 |

4. Busca Instantânea

76 | 77 | Este exemplo vai permitir aos usuários filtrarem uma lista de itens digitando dentro de um campo de texto. Este é um outro ponto onde o Angular brilha, e é um perfeito caso de uso para escrever um filtro customizado. Para fazer isso entretanto, nós primeiro temos que transformar nossa aplicação em um módulo. 78 | 79 | Módulos são uma forma de se organizar aplicações JavaScript dentro de componentes auto-suficientes que podem ser combinados de formas novas e interessantes. O Angular depende desta técnica para o isolamento do código e requer que sua aplicação siga isso antes de criar um filtro. Há apenas duas coisas que você precisa fazer para tornar sua aplicação um módulo: 80 | 81 | 1. Usar a função `angular.module("name", [])` chamada em seu JS. Isso irá instanciar e retornar um novo módulo; 82 | 83 | 2. Passar o nome do módulo como valor da diretiva `ng-app`. 84 | 85 | Criando um filtro que é tão simples com chamar o método `filter()` no objeto retornado pelo módulo `angular.module ("name", [])` 86 | 87 | * Para testar no browser, vá para o artigo original * 88 | 89 | * Link para codepen com comentários traduzidos > [aqui](http://codepen.io/eoop/pen/sBkte) 90 | 91 | Filtros seguem a filosofia do AngularJS - cada pedaço de código que você escreve deve ser auto-suficiente, testável e reutilizável. Você pode usar este filtro em todas as suas Views e até mesmo combiná-lo com outros através do encadeamento. 92 | 93 |

5. Grade Alternável

94 | 95 | Outra interação UI (user interface) popular é mudar entre modelos diferentes de layout (grid ou lista) *grid = grade* com o click de um botão. Isto é muito fácil de se fazer no Angular. Em adição, eu vou introduzir outro importante conceito - Services. Eles são objetos que podem ser usados em sua aplicação para se comunicar com o servidor, uma API ou outra fonte de dados. No nosso caso, nós vamos escrever um serviço que comunica com [API do Instagram](http://instagram.com/developer/) e retorna um array com as mais populares fotos do momento. 96 | 97 | Note que para este código funcionar, teremos que incluir um arquivo adicional Angular.js na página: 98 | 99 | ```html 100 | 101 | 102 | 103 | ``` 104 | 105 | Isso inclui o módulo [ngResource](http://docs.angularjs.org/api/ngResource.$resource) para um simples trabalho com API's AJAX (o módulo é exposto como a variável `$resource` no código). Este arquivo é automaticamente incluso no editor abaixo. 106 | 107 | * para testar no browser, vá para o artigo original * 108 | 109 | * Link para codepen com comentários traduzidos > [aqui](http://codepen.io/eoop/pen/aJmvg) 110 | 111 | Services são totalmente auto-suficientes, tornando possível escrever diferentes implementações sem que isso afete o resto do seu código. Por exemplo, durante o teste, você pode preferir retornar um array hard-coded (com código inserido diretamente no seu programa) para acelerar seus testes. 112 | 113 |

Leitura Adicional

114 | 115 | Se você tiver alcançado este ponto, você já compreendeu o básico do desenvolvimento com AngularJS. Entretanto, há muito mais a se aprender se você quiser se tornar um profissional. Aqui temos uma lista de recursos que vão ajudá-lo nesta questão: 116 | 117 | * [AngularJS Home Page](http://angularjs.org/) 118 | * [AngularJS Guide](http://docs.angularjs.org/guide/overview) 119 | * [Tutorial Oficial do AngularJS](http://docs.angularjs.org/tutorial) 120 | * [Lista de muitos e muitos recursos, vídeos e tutoriais](https://github.com/jmcunningham/AngularJS-Learning) 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /angularjs/005-entendendo-diretivas.md: -------------------------------------------------------------------------------- 1 | # Entendendo Diretivas 2 | 3 | * **Artigo Original**: [Understanding Directives](https://github.com/angular/angular.js/wiki/Understanding-Directives) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | Este documento é uma tentativa de explicar como as Diretivas no AngularJS e suas engines compiladoras relacionadas trabalham, para que você não sinta que está se deparando com *um macarrão* a primeira vez que tentar resolver isso sozinho. 7 | 8 | ## Injetando, Compilando e Linkando funções 9 | 10 | Quando você cria uma diretiva, existem essencialmente 3 camadas de função que para você definir: 11 | 12 | ```js 13 | myApp.directive('uiJq', function InjectingFunction() { 14 | 15 | // === InjectingFunction === // 16 | // Lógica é executada 0 ou 1 vez por app 17 | // (dependendo se a diretiva é usada) 18 | // Útil para inicialização e configuração global 19 | 20 | return { 21 | compile: function CompilingFunction($templateElement, $templateAttributes) { 22 | 23 | // === CompilingFunction === // 24 | // Lógica é executada uma vez para cada instância de ui-jq no seu template original NÃO RENDERIZADO 25 | // Escopo está INDISPONÍVEL quando os modelos estão sendo cacheados. 26 | // Você PODE examinar o DOM e informação de cache sobre as variáveis ou expressões 27 | // que você vai usar, mas ainda não consegue descobrir seus valores 28 | // Angular está cacheando os templates, agora é uma boa hora de injetar novos templates do Angular 29 | // como filhos ou futuros irmãos para rodarem automaticamente. 30 | 31 | return function LinkingFunction($scope, $linkElement, $linkAttributes) { 32 | 33 | // === LinkingFunction === // 34 | // A lógica é executada uma vez para cada instância renderizada 35 | // 36 | }; 37 | 38 | } 39 | }; 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /elixir/construindo-simples-armazenador-usando-logs-parte-1.md: -------------------------------------------------------------------------------- 1 | # Construindo um Simples Armazenador de Chave-Valor em Elixir, usando Logs - Parte 1 2 | 3 | - **Artigo original**: [Build a Simple Persistent Key-Value Store in Elixir, using Logs – Part 1](https://www.poeticoding.com/build-a-simple-persistent-key-value-store-in-elixir-using-logs-part-1/) 4 | - **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | ![Capa do artigo](https://i.imgur.com/fxj86xv.png) 7 | 8 | - [Construindo um Simples Armazenador de Chave-Valor em Elixir, usando Logs - Parte 1](#construindo-um-simples-armazenador-de-chave-valor-em-elixir-usando-logs---parte-1) - [⚠ WIP ⚠](#%e2%9a%a0-wip-%e2%9a%a0) - [Introdução](#introdu%c3%a7%c3%a3o) - [What is a log?](#what-is-a-log) - [O que é um log?](#o-que-%c3%a9-um-log) - [Using a Log to implement a simple KV store](#using-a-log-to-implement-a-simple-kv-store) - [Usando um Log para implementar um simples armazenador CV (chave-valor)](#usando-um-log-para-implementar-um-simples-armazenador-cv-chave-valor) 9 | 10 | ## ⚠ WIP ⚠ 11 | 12 | The code in this article is heavily inspired from the concepts amazingly explained in the book Designing Data-Intensive Applications by Martin Kleppmann. 13 | _O código neste artigo é fortemente inspirado em conceitos incrivelmente explicados no livro [Designing Data-Intensive Applications](https://dataintensive.net/) por Martin Kleppmann_ 14 | 15 | Disclaimer, all the code you find in this article, and on the github repo, is written for pure fun and meant just as an experiment. 16 | Aviso, todo o código que você encontrar nesse artigo e no repositório do GitHub, foi escrito por pura diversão e criado como um experimento. 17 | 18 | Published articles in the series: 19 | Artigos publicados nessa série: 20 | 21 | 1. Parte 1 (esse artigo) 22 | 1. Parte 2 23 | 24 | ## Introdução 25 | 26 | In the last year I’ve got interested in logs and how something so simple can be the solid foundation of databases like Riak, Cassandra and streaming systems like Kafka. 27 | No último ano fiquei interessado em _logs_ (registros) e como algo tão simples pode ser a fundação sólida de banco de dados como Riak, Cassandra e sistemas de _streaming_ como Kafka. 28 | 29 | In this series of articles we will see the different concepts behind a key-values store (Logs, Segments, Compaction, Memtable, SSTable) implementing a simple engine in Elixir, which is a great language to build highly-concurrent and fault-tolerant architectures. 30 | Nesta série de artigos vamos ver os diferentes conceitos por trás de armazenadores chave-valor (Logs, Segmentos, Compactação, _Memtable_ e _SSTable_) implementando um motor simples em Elixir, a qual é uma grande linguagem para construir arquiteturas altamente concorrentes e tolerantes a falha. 31 | 32 | In this first part we will see: 33 | Nessa parte vamos ver: 34 | 35 | - What is a log? 36 | - O que é um log? 37 | - Making a KV persistent using a log and an index. Using an example we will use along the series, crypto market prices and trades, we are going to see how to store the values in a log using using an index. 38 | - Como fazer um KV (_key-value_ ou chave-valor) persistente usando log e um índice. Com um exemplo que vamos usar ao longo da série, preços e transações do mercado de criptomoedas, iremos ver como armazenar os valores em um log usando um índice. 39 | - LogKV in Elixir. A initial super simple implementation in elixir of a Writer, an Index and a Reader. 40 | - LogKV em Elixir. Uma implementação inicial super simples em Elixir de um Escritor, um Índice e um Leitor. 41 | 42 | ## What is a log? 43 | 44 | ## O que é um log? 45 | 46 | Let’s think at the most common type of log file, the one we use everyday to debug events and error messages in our applications. This simple file enshrines an interesting property, it’s an append-only file. This means that only sequential writes are allowed and everything we write in the log is immutable. 47 | 48 | Vamos pensar no tipo de arquivo de log mais comum, aquele que usamos todos os dias para debugar eventos e mensagens de erro em nossas aplicações. Este arquivo simples consagra uma propriedade interessante, ele é um arquivo _append-only_ (que aceita adições de conteúdo apenas no fim do arquivo). Isso significa que apenas escritas sequenciais são permitidas e tudo que escrevemos no log é imutável. 49 | 50 | Why sequential writes could be important for us? Well… speed! 51 | 52 | Por que escrita sequencial pode ser importante pra nós? Bom... velocidade! 53 | 54 | ![Random vs Sequential Access – The Pathologies of Big Data](https://i.imgur.com/qDcMjkU.png) 55 | 56 | > Acesso Aleatório vs Sequencial - [As Patologias do Big Data](https://queue.acm.org/detail.cfm?id=1563874) 57 | 58 | We see the huge difference between random and sequential access on both classic magnetic disks, SSD and even memory. So, the idea is to leverage the sequential access speed using an append-only file to save the data of our key-value store. 59 | 60 | Pudemos ver a grande diferença entre acesso aleatório e sequencial em ambos discos magnéticos clássicos, SSD e até mesmo a memória. Então, a ideia é potencializar a velocidade do acesso sequencial usando um arquivo apenas de adição para salvar os dados do nosso armazenador chave-valor. 61 | 62 | ## Using a Log to implement a simple KV store 63 | 64 | ## Usando um Log para implementar um simples armazenador CV (chave-valor) 65 | 66 | Let’s start with a simple example. Let’s consider a realtime application where we have to store the last price in dollars of the Bitcoin (BTC), Ethereum (ETH) and Litecoin (LTC). 67 | 68 | Vamos começar com um simples exemplo. Vamos considerar uma aplicação em tempo real onde nós temos que armazenar o último preço em dólares do Bitcoin (BTC), Ethereum (ETH) e Litecoin (LTC). 69 | 70 | | Chave | Valor | 71 | | ----- | ------- | 72 | | BTC | 4478.12 | 73 | | ETH | 133.62 | 74 | | LTC | 33.19 | 75 | 76 | If we just need to keep this snapshot in memory, in Elixir we can use a Map. But persistence is another story. There are many different ways and technologies we could use to store this map and make it persistent. 77 | 78 | Se nós apenas precisássemos manter esse retrato em memória, com Elixir poderíamos usar um `Map`. Mas persistência é outra história. Existem várias formas diferentes e tecnologias que poderíamos usar para armazenar esse mapa e fazer isso persistente. 79 | 80 | If this snapshot would be updated just few times in a day, with just few currencies, then serialising the map into a file would be fine and easy to do, but this is obviously not our case! Our imaginary crypto application needs to keep track of any market’s movement with hundreds of updates per second for hundreds of currencies. 81 | 82 | Se esse retrato fosse atualizado apenas algumas vezes por dia, com apenas algumas moedas, então serializar o mapa dentro de um arquivo seria bom e fácil de fazer, mas isso obviamente não é o nosso caso! Nossa aplicação imaginária de criptomoedas precisa acompanhar qualquer movimento do mercado com centenas de atualizações por segundo para centenas de moedas. 83 | 84 | But how can we use an append-only file, where data written is immutable by nature, to store the mutable data of a key-value store, to leverage sequential access and to keep our map persistent? 85 | 86 | Mas como nós podemos usar um arquivo _append-only_ (apenas anexando informações a ele), onde os dados escritos são imutáveis por natureza, para armazenar dados mutáveis de um armazenador chave-valor, potencializar o acesso sequencial e manter nosso mapa persistente? 87 | 88 | The idea is pretty simple: 89 | 90 | A ideia é muito simples: 91 | 92 | - append to our log each single price update (value) for any currency (key) 93 | - use our Map as an index, keeping track of the position and size of the values within our logfile. 94 | 95 | - anexar ao nosso log cada simples atualização de preço (valor) para qualquer moeda (chave) 96 | - usar nosso `Map` como um índice, mantendo o controle da posição e tamanho dos valores dentro do arquivo de log. 97 | 98 | ![Concept of key-value persistence using a log](https://i.imgur.com/06A0ViN.png) 99 | 100 | > Concept of key-value persistence using a log 101 | > Conceito de persistência chave-valor usando um log 102 | 103 | 1. 17:14:59 – LTC trades at 32.85\$. We append the string "32.85" to the log and we update the "LTC" key of our index (implemented with a Map) with value’s offset (0 since it’s the first value in the file) and it’s size (5 bytes, since it’s a string). 104 | 2. 17:15:00 – ETH trades at 130.98\$. We append the string "130.98" to the log and we update the "ETH" key of our index with offset 5 and size 6 bytes. 105 | 3. 17:15:01 – BTC trades at 4411.99\$. We append the string "4411.99" to the log and we update the "BTC" key of our index with offset 11 and size 7 bytes. 106 | 107 | 4. 17:14:59 - LTC comercializado a \$32.85. Nós adicionamos a string `"32.85"` ao log e atualizamos a chave `"LTC"` do nosso índice (implementado com um [Map](https://hexdocs.pm/elixir/Map.html)) com o valor do _offset_ (deslocamento) (0 já que é o primeiro valor no arquivo) e seu tamanho (5 bytes, pois é uma string). 108 | 5. 17:15:00 - ETC comercializado a \$130.98. Nós adicionamos a string `130.98` ao log e atualizamos a chave "ETH" ao nosso índice com deslocamento 5 e tamanho 6 bytes. 109 | 6. 17:15:01 - BTC comercializado a \$4411.99. Nós adicionamos a string `4411.99` ao log e atualizamos a chave "BTC" do nosso índice com deslocamento 11 e tamanho 7 bytes. 110 | 111 | What happens if we receive a new price for ETH? How can we overwrite the value in the log since the value we wrote is immutable and we can just append? 112 | 113 | O que acontece se nós recebermos um novo preço para ETH? Como podemos sobrescrever o valor no log uma vez que o valor que escrevemos é imutável e só podemos adicionar? 114 | 115 | 4. 17:15:09 – ETH trades at 131.00\$. 116 | 117 | 5. 17:15:09 - ETH comercializado a \$131.00. 118 | 119 | ![Transação ETH](https://i.imgur.com/DiWczpP.png) 120 | 121 | Since to leverage sequential writes we can just append, we then just append the new value updating the index with the new offset and size. 122 | 123 | Já que para aumentar a velocidade da escrita sequencial nós só podemos adicionar, nós então apenas adicionamos o novo valor atualizando o índice com o novo deslocamento e tamanho. 124 | 125 | The read is efficient too. To retrieve the values from the log, we just use offset and size in the index and with need one seek of the disk to load our value into memory. 126 | 127 | A **leitura** é eficiente também. Para recuperar os valores do log, nós só precisamos usar **offset** (deslocamento) e **size** (tamanho) no _index_ (índice) e com uma "olhada" no disco para carregar nossos valores para memória. 128 | 129 | ## LogKV in Elixir 130 | 131 | ## LogKV em Elixir 132 | -------------------------------------------------------------------------------- /img/angularJS-5-exemplos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/angularJS-5-exemplos.png -------------------------------------------------------------------------------- /img/callback-js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/callback-js.png -------------------------------------------------------------------------------- /img/guia-definitivo-angular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/guia-definitivo-angular.png -------------------------------------------------------------------------------- /img/js-prototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/js-prototype.png -------------------------------------------------------------------------------- /img/node-absolute-begginer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/node-absolute-begginer.png -------------------------------------------------------------------------------- /img/traduz-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericdouglas/traduz-ai/83b66de350842dd6fb38134c433e0c7696b962bd/img/traduz-ai.png -------------------------------------------------------------------------------- /javascript/003-escopo-de-variavel-js-e-hoisting-explicado.md: -------------------------------------------------------------------------------- 1 | # Escopo e _Hoisting_ de Variáveis no JavaScript Explicados 2 | 3 | * **Artigo Original**: [JavaScript Variable Scope and Hoisting Explained](http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | Nesta postagem, iremos aprender sobre escopo e hoisting (hasteamento) de variáveis no JavaScript e tudo sobre as idiossincrasias (peculiaridades) de ambos. 7 | 8 | É imperativo que nós tenhamos entendimento de como o escopo e o hasteamento de variável funcionam no JavaScript, se quisermos entender bem o JS. Estes conceitos podem parecer óbvios, mas não são. Há algumas importantes sutilezas que nós devemos compreender, se realmente quisermos ser desenvolvedores JavaScript bem sucedidos. 9 | 10 | ##Escopo de Variáveis 11 | 12 | Um escopo de variável é o contexto no qual a variável existe. O escopo especifica de onde você pode acessar uma variável e se você tem acesso à variável naquele contexto. 13 | 14 | Variáveis têm ou um escopo local ou um escopo global. 15 | 16 | ##Variáveis Locais (Escopo Nível-de-Função) 17 | 18 | Ao contrário da maioria das linguagens de programação, o JavaScript não tem um escopo em nível-de-bloco (variáveis com o escopo envolto por chaves); como alternativa, no JavaScript temos escopo por nível-de-função. As variáveis declaradas dentro de uma função são variáveis locais, e são somente acessíveis por dentro dessa função ou por funções dentro dessa função. Veja a minha postagem de [Closures](https://github.com/cerebrobr/traduz-ai/blob/master/javascript/004-entenda-closures-no-javaScript-com-facilidade.md) para saber mais em como acessar variáveis em funções exteriores a partir de funções interiores. 19 | 20 | Demonstração de Escopo de Nível-de-Função 21 | 22 | ```javascript 23 | var name = "Richard"; 24 | 25 | function showName() { 26 | var name = "Jack"; // variável local; somente acessível na função showName 27 | console.log(name); // Jack 28 | } 29 | 30 | console.log(name); // Richard: a variável global 31 | ``` 32 | 33 | Sem Escopo de Nível-de-Bloco 34 | 35 | ```javascript 36 | var name = "Richard"; 37 | // O bloco nesta condicional if não cria um contexto local para a variável name 38 | if (name) { 39 | name = "Jack"; // este name é a variável global name e está sendo alterada para "Jack" aqui 40 | console.log(name); // Jack: ainda como a variável global 41 | } 42 | 43 | // Aqui, a variável name é a mesma variável global name, mas ela foi modificada na condicional if 44 | console.log(name); // Jack 45 | ``` 46 | 47 | ### Se você não declarar as suas variáveis locais, encrenca está perto 48 | 49 | Sempre declare suas variáveis locais antes de usá-las. Aliás, você deveria usar o [JSHint](http://www.jshint.com/) para verificar seu código por erros de sintaxe e guias de estilo. Aqui está o problema ao não declarar variáveis locais: 50 | 51 | ```javascript 52 | // Se você não declarar suas variáveis locais com a palavra-chave var, 53 | // elas se tornam parte do escopo global 54 | var name = "Michael Jackson"; 55 | 56 | function showCelebrityName() { 57 | console.log(name); 58 | } 59 | 60 | function showOrdinaryPersonName() { 61 | // Note a ausência da palavra-chave var, 62 | // tornando esta variável global: 63 | name = "Johnny Evers"; 64 | console.log(name); 65 | } 66 | 67 | showCelebrityName(); // Michael Jackson 68 | 69 | // name não é uma variável local, ele simplesmente muda a variável global name 70 | showOrdinaryPersonName(); // Johnny Evers 71 | 72 | // A variável global é agora Johnny Evers, não mais o name da celebridade Michael Jackson 73 | showCelebrityName(); // Johnny Evers 74 | 75 | // A solução é declarar sua variável local com a palavra-chave var 76 | function showOrdinaryPersonName() { 77 | // Agora name é sempre uma variável local 78 | // e não irá sobrescrever a variável global 79 | var name = "Johnny Evers"; 80 | console.log(name); 81 | } 82 | ``` 83 | 84 | ### Variáveis locais têm prioridade sobre variáveis globais nas funções 85 | 86 | Se você declarar uma variável global e uma variável local com o mesmo nome, a variável local terá prioridade quando você tentar usá-la dentro de uma função (escopo local): 87 | 88 | ```javascript 89 | var name = "Paul"; 90 | 91 | function users() { 92 | // Aqui, a variável name é local 93 | // e prevalece sobre a mesma variável name no escopo global 94 | var name = "Jack"; 95 | 96 | // A busca por name começa bem aqui dentro da função 97 | // antes de tentar enxergar fora da função no escopo global 98 | console.log(name); 99 | } 100 | 101 | users(); // Jack 102 | ``` 103 | 104 | ## Variáveis Globais 105 | 106 | Todas as variáveis declaradas fora de uma função estão no escopo global. No navegador, que é onde estamos interessados como desenvolvedores front-end, o contexto ou escopo global é o objeto _window_ (ou o documento HTML inteiro). 107 | 108 | - Qualquer variável declarada ou inicializada fora de uma função é uma variável global, e estará portanto disponível para toda a aplicação. Por exemplo: 109 | 110 | ```javascript 111 | // Para declarar uma variável global, você pode utilizar quaisquer das seguintes estratégias: 112 | var myName = "Richard"; 113 | 114 | // ou mesmo 115 | firstName = "Richard"; 116 | 117 | // ou 118 | var name; 119 | name; 120 | ``` 121 | 122 | É importante notar que todas as variáveis globais são anexadas no objeto _window_. Então, todas as variáveis globais que nós declaramos podem ser acessadas pelo object _window_ como assim: 123 | 124 | ```javascript 125 | console.log(window.myName); // Richard; 126 | 127 | // ou 128 | console.log("myName" in window); // true 129 | console.log("firstName" in window); // true 130 | ``` 131 | 132 | - Se uma variável é inicializada (atribuída com um valor) sem primeiro ser declarada com a palavra-chave var, ela é automaticamente adicionada ao contexto global, sendo deste modo uma variável global: 133 | 134 | ```javascript 135 | function showAge() { 136 | // age é uma variável global porque ela não foi declarada 137 | // com a palavra-chave var dentro da função: 138 | age = 90; 139 | console.log(age); 140 | } 141 | 142 | // age está no contexto global, portanto está disponível aqui também: 143 | console.log(age); // 90 144 | ``` 145 | 146 | Demonstração de variáveis que estão no Escopo Global mesmo que pareça o contrário: 147 | 148 | ```javascript 149 | // Ambas variáveis firstName estão no escopo global, 150 | // mesmo embora a segunda esteja envolta pelo bloco {}: 151 | var firstName = "Richard"; 152 | { 153 | var firstName = "Bob"; 154 | } 155 | 156 | // Para reiterar: JavaScript não tem escopo por nível-de-bloco 157 | 158 | // A segunda declaração de firstName simplesmente redeclara e sobrescreve a primeira 159 | console.log(firstName); // Bob 160 | ``` 161 | 162 | Outro exemplo: 163 | 164 | ```javascript 165 | for (var i = 1; i <= 10; ++i) { 166 | console.log(i); // imprime 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 167 | } 168 | 169 | // A variável i é uma variável global e está acessível 170 | // na seguinte função com o último valor que foi-lhe atribuído acima 171 | function aNumber() { 172 | console.log(i); 173 | } 174 | 175 | // A variável i na função aNumber abaixo é a variável global i que foi alterada no laço acima. 176 | // Seu último valor foi 11, atribuído um momento antes da saída do laço: 177 | aNumber(); // 11 178 | ``` 179 | 180 | ### Variáveis de setTimeout são Executadas no Escopo Global 181 | Note que todas as funções no setTimeout são executadas no escopo global. Isto é ligeiramente complicado; considere isto: 182 | 183 | ```javascript 184 | // O uso do objeto "this" dentro da função setTimeout refere-se ao objeto Window, não ao myObj 185 | 186 | var highValue = 200; 187 | var constantVal = 2; 188 | var myObj = { 189 | highValue: 20, 190 | constantVal: 5, 191 | calculateIt: function () { 192 | setTimeout (function () { 193 | console.log(this.constantVal * this.highValue); 194 | }, 2000); 195 | } 196 | }; 197 | 198 | // O objeto "this" na função setTimeout usou as variáveis globais highValue e constantVal, 199 | // porque a referência ao "this" na função setTimeout refere-se ao objeto global window, 200 | // não ao objeto myObj como anteciparíamos. 201 | 202 | myObj.calculateIt(); // 400 203 | 204 | // Este é um ponto importante a ser lembrado! 205 | ``` 206 | 207 | ### Não Polua o Escopo Global 208 | 209 | Se você quer se tornar um mestre em JavaScript, o que certamente você quer ser (caso contrário você estaria assistindo 'Honey Boo Boo' neste exato momento), você tem que saber que é importante evitar criar muitas variáveis no escopo global, tal como este: 210 | 211 | ```javascript 212 | // Estas duas variáveis estão no escopo global e elas não deveriam estar aqui: 213 | var firstName, lastName; 214 | 215 | function fullName() { 216 | console.log("Full name: " + firstName + " " + lastName); 217 | } 218 | ``` 219 | 220 | Este é o código melhorado e a maneira apropriada de se evitar poluir o escopo global: 221 | 222 | ```javascript 223 | // Declare as variáveis dentro da função onde serão variáveis locais: 224 | function fullName() { 225 | var firstName = "Michael", lastName = "Jackson"; 226 | 227 | console.log("Full Name: " + firstName + " " + lastName); 228 | } 229 | ``` 230 | 231 | Neste último exemplo, a função fullName está no escopo global. 232 | 233 | ## Hasteamento de Variáveis (Variable Hoisting) 234 | 235 | Todas declarações de variáveis são hasteadas (erguidas e declaradas) ao topo da função se definida dentro duma função; ou no topo do contexto global se definida fora duma função. 236 | 237 | É importante saber que somente declarações de variáveis são hasteadas ao topo, não a inicialização ou as atribuições (quando para uma variável é atribuído um valor) de variáveis. 238 | 239 | Exemplo de Hasteamento de Variável: 240 | 241 | ```javascript 242 | function showName() { 243 | console.log("First Name: " + name); 244 | var name = "Ford"; 245 | console.log("Last Name: " + name); 246 | } 247 | 248 | showName (); 249 | // First Name: undefined 250 | // Last Name: Ford 251 | 252 | // A razão para a primeira impressão ser undefined é que a variável local name foi hasteada ao topo da função 253 | // Que significa que é esta a variável local que é chamada na primeira vez. 254 | // Veja como o código realmente é processado pela engine (motor) JavaScript 255 | 256 | function showName() { 257 | // name é hasteada (note que está indefinida (undefined) até este ponto, 258 | // já que a atribuição acontece depois mais abaixo): 259 | var name; 260 | console.log("First Name: " + name); // First Name: undefined 261 | 262 | name = "Ford"; // é atribuído um valor a name 263 | 264 | // Agora name é Ford 265 | console.log("Last Name: " + name); // Last Name: Ford 266 | } 267 | ``` 268 | 269 | ### Declaração de Função Sobrescreve Declaração de Variável Quando Hasteada 270 | 271 | Ambas declarações de funções e variáveis são hasteadas para o topo do escopo que as contém. E a declaração de função tem prioridade sobre declarações de variável (mas não sobre atribuição de variável). Como notado acima, atribuição de variável não é hasteada, e nem atribuição de função. Como um lembrete, isto é uma atribuição de função: `var myFunction = function () {};`. 272 | Aqui temos um exemplo básico para demonstração: 273 | 274 | ```javascript 275 | // Tanto a variável quanto a função são nomeadas de myName: 276 | var myName; 277 | 278 | function myName() { 279 | console.log("Rich"); 280 | } 281 | 282 | // A declaração da função sobrescreve a variável myName: 283 | console.log(typeof myName); // function 284 | ``` 285 | 286 | ```javascript 287 | // Mas neste exemplo, a atribuição da variável sobrescreve a declaração da função 288 | 289 | // Isso é a atribuição de variável (inicialização) que sobrescreve a declaração da função: 290 | var myName = "Richard"; 291 | 292 | function myName() { 293 | console.log("Rich"); 294 | } 295 | 296 | console.log(typeof myName); // string 297 | ``` 298 | 299 | É importante notar que as expressões função, tais como o exemplo abaixo, não são hasteadas: 300 | 301 | ```javascript 302 | var myName = function() { 303 | console.log("Rich"); 304 | }; 305 | ``` 306 | 307 | No modo estrito (`"strict mode";`), um erro ocorrerá se você atribuir a uma variável algum valor sem primeiro declarar a variável. Sempre declare as suas variáveis! 308 | 309 | Sê bom. Durma bem. E curta programar! 310 | -------------------------------------------------------------------------------- /javascript/004-entenda-closures-no-javaScript-com-facilidade.md: -------------------------------------------------------------------------------- 1 | # Entenda Closures no JavaScript com Facilidade 2 | 3 | * **Artigo Original**: [Understand JavaScript Closures With Ease](http://javascriptissexy.com/understand-javascript-closures-with-ease/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | Closures são adoráveis e muito úteis: Eles permitem aos programadores programarem criativamente, expressivamente e concisamente. Eles são usados frequentemente no JavaScript e, não importa seu nível de habilidade no JavaScript, você sem dúvidas irá encontrá-los. Claro, closures podem parecer complexos e além do seu alcance, mas depois que você ler este artigo, os closures vão ser muito mais fáceis de se entender e mais atraentes para serem usados todo os dias quando você programar em JavaScript. 7 | 8 | Este é um artigo curto ( e doce =] ) com os detalhes dos closures no JavaScript. Você deve estar familirializado com o [Escopo de Variáveis JavaScript](https://github.com/eoop/traduz-ai/blob/master/javascript/003-escopo-de-variavel-js-e-hoisting-explicado.md#artigo-traduzido-postado-originalmente-em-javascriptissexy-em-31012013) antes de começar essa leitura adicional, porque para se entender closures você deve entender o escopo de variáveis no JavaScript. 9 | 10 | ### O que é um closure? 11 | 12 | Um closure é uma função interior que tem acesso a variáveis de uma função exterior - cadeia de escopo. O closure tem três cadeias de escopo: ele tem acesso ao seu próprio escopo (variáveis definidas entre suas chaves), ele tem acesso as variáveis da função exterior e tem acesso as variáveis globais. 13 | 14 | A função interior tem acesso não somente as variáveis da função exterior, mas também aos parâmetros dela. Note que a função interior não pode chamar o objeto *arguments* da função exterior, entretanto, pode chamar parâmetros da função externa diretamente. 15 | 16 | Você cria um closure adicionando uma função dentro de outra função. 17 | 18 | **Um Exemplo Básico de Closures no JavaScript:** 19 | 20 | ```javascript 21 | 22 | function showName (firstName, lastName) { 23 | var nameIntro = "Your name is "; 24 | 25 | //esta função interior tem acesso as variáveis da função exterior, incluindo os parâmetros 26 | function makeFullName () { 27 | return nameIntro + firstName + " " + lastName; 28 | } 29 | 30 | return makeFullName (); 31 | } 32 | 33 | showName ("Michael", "Jackson"); //Your name is Michael Jackson 34 | 35 | ``` 36 | 37 | Closures são usados extensivamente no Node.js; eles são complicados no Node.js assíncrono, com arquitetura não bloqueante. Closures também são frequentemente usados no jQuery e em todo pedaço de código JavaScript que você lê. 38 | 39 | #### Um Clássico exemplo de Closures no jQuery: 40 | 41 | ```javascript 42 | 43 | $(function () { 44 | var selections = []; 45 | $(".niners").click(function () { //este closure tem acesso as variáveis de selections 46 | selections.push(this.prop ("name")); //atualiza a variável selection no escopo da função exterior 47 | }); 48 | }); 49 | 50 | ``` 51 | 52 | ## Regra dos Closures e Efeitos Colaterais 53 | 54 | ### 1. Closures tem acesso a variável das funções exteriores mesmo após o retorno da função exterior 55 | Uma da mais importantes e delicadas características dos closures é que a função interior continua tendo acesso as variáveis da função exterior mesmo após ela ter retornado. Sim, você leu corretamente. Quando funções no JavaScript executam, elas usam a mesma cadeia de escopo que estavam em vigor quando foram criadas. Isso significa que mesmo depois da função exterior retornar, a função interior continua tendo acesso as variáveis da função exterior. Portanto, você pode chamar a função interior depois em seu programa. Este exemplo demonstra isso: 56 | 57 | ```javascript 58 | 59 | function celebrityName (firstName) { 60 | var nameIntro = "This celebrity is "; 61 | 62 | //essa função interior tem acesso as variáveis da função exterior, incluindo os parâmetros 63 | function lastName (theLastName) { 64 | return nameIntro + firstName + " " + theLastName; 65 | } 66 | return lastName; 67 | } 68 | 69 | var mjName = celebrityName ("Michael"); 70 | //Nesta conjuntura, a função exterior celebrityName foi retornada 71 | 72 | //O closure (lastName) é chamado aqui depois da função exterior ter retornado acima 73 | //Sim, o closure continua tendo acesso as variáveis da função exterior e parâmetros 74 | mjName ("Jackson"); //This celebrity is Michael Jackson 75 | 76 | ``` 77 | 78 | ### 2. Closures armazenam referências para as variáveis da função exterior 79 | 80 | Eles não armazenam o valor real. Closures ficam mais interessantes quando o valor da variável da função exterior muda antes que o closure seja chamado, e esta poderosa característica pode ser aproveitada de formas criativas, como este exemplo de variável privada primeiramente demonstrada por Douglas Crockford: 81 | 82 | ```javascript 83 | 84 | function celebrityID () { 85 | var celebrityID = 999; 86 | //Nós retornamos um objeto com algumas funções interiores 87 | //Todas as funções interiores têm acesso as variáveis'da função exterior 88 | return { 89 | getID: function () { 90 | //Esta função interior vai retornar a variável celebrityID ATUALIZADA 91 | return celebrityID; 92 | }, 93 | setID: function (theNewId) { 94 | //Esta função interior vai mudar a variável da função exterior a qualquer hora 95 | celebrityID = theNewId; 96 | } 97 | } 98 | } 99 | 100 | var mjID = celebrityID (); //Nesta atual conjuntura, a função exterior celebrityID já retornou 101 | mjID.getID(); //999 102 | mjID.setID(567); //Muda a variável da função exterior 103 | mjID.getID(); //567 - retorna o valor atualizado da variável celebrityID 104 | 105 | ``` 106 | 107 | ### 3. Closures que deram errado 108 | 109 | Por causa dos closures terem acesso ao valor atualizado das variáveis das funções exteriores, eles podem também conduzir a erros quando a variável da função exterior muda com um loop for. Assim: 110 | 111 | ```javascript 112 | 113 | //Este exemplo é explicado em detalhe abaixo (logo após este bloco de código) 114 | function celebrityIDCreator (theCelebrities) { 115 | var i; 116 | var uniqueID = 100; 117 | for (i = 0; i < theCelebrities.length; i += 1) { 118 | theCelebrities[i]["id"] = function () { 119 | return uniqueID + i; 120 | } 121 | } 122 | 123 | return theCelebrities; 124 | } 125 | 126 | var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}]; 127 | 128 | var createIdForActionCelebs = celebrityIDCreator(actionCelebs); 129 | 130 | var stalloneID = createIdForActionCelebs[0]; 131 | 132 | console.log(stalloneID.id()); //103 133 | 134 | ``` 135 | 136 | No exemplo anterior, quando a função anônima é chamada, o valor de i é 3 (a contagem do array e então seus incrementos). O número 3 foi adicionado ao uniqueID para criar 103 para TODOS os celebrityID. Então cada posição no array retornado obteve o id = 103, ao invés do valor pretendido 100, 101, 102. 137 | 138 | A razão para isso acontecer foi porque, assim como nós discutimos no exemplo anterior, o closure (função anônima neste exemplo) teve acesso a variável da função exemplo por referência, não por valor. Então, igual ao exemplo anteriormente mostrado onde nós acessamos o valor atualizado da variável com o closure, neste exemplo, similarmente acessamos a variável `i` quando ela foi alterada, depois que a função exterior rodou o loop `for` inteiro e retorno o último valor, que foi 103. 139 | 140 | Para consertar este efeito colateral (bug) nos closures, você pode usar uma **Expressão de Função Imediatamente Invocada** (IIFE - immediately invoked function expression), como no exemplo seguinte: 141 | 142 | ```javascript 143 | 144 | function celebrityIDCreator (theCelebrities) { 145 | var i; 146 | var uniqueID = 100; 147 | for (i = 0; i < theCelebrities.length; i += 1) { 148 | theCelebrities[i]["id"] = function (j) { //a variável paramétrica j é o i passado na invocação da IIFE 149 | return function () { 150 | return uniqueID + j; 151 | //cada iteração do loop for passa no valor atual de i dentro desta IIFE e salva o valor correto no array 152 | } () //Adicionando () no fim da função, nós estamos executando-a imediatamente e retornando somente o valor de uniqueID + j, ao invés de retornar uma função 153 | } (i); //invocando imediatamente a função passando a variável i como um parâmetro 154 | } 155 | return theCelebrities; 156 | } 157 | 158 | var actionCelebs = [{name: "Stallone", id:0}, {name: "Cruise", id:0}, {name: "Willis", id:0}]; 159 | 160 | var createIdForActionCelebs = celebrityIDCreator (actionCelebs); 161 | 162 | var stalloneID = createIdForActionCelebs [0]; 163 | console.log(stalloneID.id); //100 164 | 165 | var cruiseID = createIdForActionCelebs [1]; 166 | console.log(cruiseID.id); //101 167 | 168 | ``` 169 | -------------------------------------------------------------------------------- /javascript/008-programacao-funcional-prioridade-2015.md: -------------------------------------------------------------------------------- 1 | # Programação Funcional Deve Ser Sua Prioridade número #1 em 2015 2 | ### - OOP não pode mais nos salvar do *Cloud Monster* 3 | 4 | * **Artigo Original**: [Functional Programming should be your #1 priority for 2015](https://medium.com/@jugoncalves/functional-programming-should-be-your-1-priority-for-2015-47dd4641d6b9) 5 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) e [Diogo Beato](https://github.com/diogobeato) 6 | 7 | Você provavelmente já ouviu expressões como "Clojure", "Scala", "Erlang", ou mesmo "Java agora tem *lambdas*". E você deve saber que isso tem alguma coisa a ver com "Programação Funcional". Se você participa de qualquer comunidade de programação, esse assunto provavelmente apareceu alguma vez. 8 | 9 | Se você já buscou por "Functional Programming" (ou Programação Funcional), viu que não existe nada de novo. A segunda linguagem criada já utilizava isso, apareceu por volta da década de 50, nominada *Lisp*. Por que, então, as pessoas estão empolgadas com isso apenas agora? Quase 60 anos depois!? 10 | 11 | ## No início, os computadores eram realmente lentos 12 | 13 | Acredite nisso ou não, computadores eram muuuuito mais lentos que o DOM. Não, sério. E naquele tempo, existiam duas mentalidades principais em termos de arquitetura e implementação de linguagens de programação: 14 | 15 | 1. Iniciar pela Arquitetura Von Neumann e adicionar abstração. 16 | 1. Iniciar pela Matemática e remover abstração. 17 | 18 | Os computadores não tinham tanto poder de processamento para lidar com abstrações por todo o caminho e executar os programas funcionais. Então, Lisp acabou sendo mortalmente lenta, portanto, não adequada para o trabalho. Foi quando a programação imperativa começou sua dominação, especialmente com a ascenção do *C*. 19 | 20 | ### Mas os computadores melhoraram muito 21 | 22 | Agora é virtualmente possível rodar a maioria das aplicações sem se preocupar muito sobre em qual linguagem foi escrita. Finalmente, linguagens funcionais tiveram sua segunda chance. 23 | 24 | ## Programação Funcional 50.5 25 | 26 | Isso não é uma introdução a *FP* (*Functional Programming*). No fim dessa seção, você deverá ter uma ideia de o que *FP* é e como começar sua jornada. 27 | 28 | Você pode entender Programação Funcional por programação com funções, que é, de fato, muito mais literal do que você pode imaginar agora. Você vai criar funções em termos de outras funções e compor funções (Você se lembra `f ∘ g` da escola? Isso vai ser útil agora). 29 | 30 | Aqui temos uma (não-exaustiva) lista de características da FP: 31 | 32 | 1. First-Class Functions (Funções de Primeira Classe) 33 | 1. High-Order Functions (Funções de Alta Ordem) 34 | 1. Pure Functions (Funções Puras) 35 | 1. Closures 36 | 1. Immutable State (Imutabilidade de Estado) 37 | 38 | Você não deve se preocupar com nomes *sofisticados* agora: apenas entenda o que eles significam. 39 | 40 | **First-Class Functions**, ou *Funções de Primeira Classe*, significa que você vai armazenar funções dentro de uma variável. Acredito que você já fez algo parecido com isso em JavaScript: 41 | 42 | ```js 43 | var add = function(a, b){ 44 | return a + b 45 | } 46 | ``` 47 | 48 | Você está apenas armazenando uma função anônima que recebe `a` e `b`, e retorna `a + b`, dentro de uma variável denominada `add`. 49 | 50 | **High-Order Functions**, ou *Funções de Alta Ordem*, significa que funções podem retornar funções ou receber funções como parâmetro. 51 | 52 | Novamente, em JavaScript: 53 | 54 | ```js 55 | document.querySelector('#button') 56 | .addEventListener('click', function(){ 57 | alert('yay, i got clicked') 58 | }) 59 | ``` 60 | 61 | ou 62 | 63 | ```js 64 | var add = function(a){ 65 | return function(b){ 66 | return a + b 67 | } 68 | } 69 | 70 | var add2 = add(2) 71 | add2(3) // => 5 72 | ``` 73 | 74 | Ambos os casos são um exemplo de Funções de Alta Ordem, mesmo que você nunca tenha usado algo parecido com isso, provavelmente você já viu algo assim em algum lugar. 75 | 76 | **Pure Functions**, ou *Funções Puras*, significa que funções não mudam nenhum valor, elas apenas recebem dados e retornam dados, assim como nossas amadas funções da Matemática. Isso também significa que, se você passar `2` para uma função `f` e ela retornar `10`, ela sempre irá retornar `10`. Não importa o ambiente, threads, ou qualquer ordem de avaliação. Ela não causa nenhum efeito colateral em outras partes do programa, e isso é realmente um conceito poderoso. 77 | 78 | **Closures** significa que você pode salvar algum dado dentro de uma função que é apenas acessível à função de retorno, isto é, a função retornada mantém seu ambiente de execução. 79 | 80 | ```js 81 | var add = function(a){ 82 | return function(b){ 83 | return a + b 84 | } 85 | } 86 | 87 | var add2 = add(2) 88 | add2(3) // => 5 89 | ``` 90 | 91 | Verifique o segundo exemplo de *High-Order Function* novamente. A variável foi *fechada* e é acessível somente para a função retornada. 92 | 93 | **Immutable State** ou *Estado Imutável* signifca que você não pode alterar o estado de forma alguma (embora você possa gerar um novo estado). No seguinte código (em OCaml), você pode usar `x` e `5` alternadamente em seu programa. `x` vai sempre ser `5`. 94 | 95 | ```ocaml 96 | let x = 5;; 97 | x = 6;; 98 | 99 | print_int x;; (* prints 5 *) 100 | ``` 101 | 102 | Isso parece muito mais com um ponto negativo que uma boa característica, mas você vai ver que isso salvará sua vida. 103 | 104 | ## Programação Orientada a Objetos não pode mais nos salvar 105 | 106 | Aquele momento de que teríamos aplicações concorrentes e distribuídas rodando finalmente chegou. 107 | 108 | Infelizmente, nós não estamos prontos: nosso "atual" (i.e., mais usado) modelo para concorrência e paralelismo, embora resolva o problema, ainda traz muita complexidade. 109 | 110 | Para termos melhores aplicações, precisamos de uma maneira simples e confiável para fazer isto. Você se lembra das features de FP mencionados acima? *Pure Functions* (Funções Puras) e *Immutable State* (Imutabilidade de Estado)? Exatamente. Você pode rodar uma função milhares de vezes em diferentes *cores* ou máquinas que ainda assim não terá resultados diferentes dos que teve anteriormente. Sendo assim, você pode usar o mesmo código para rodar em 1 *core* ou em 1k de *cores*. Podemos ser felizes novamente. 111 | 112 | > "Mas por que eu não posso continuar usando POO?" 113 | 114 | Ao menos para concorrência e paralelismo, POO não pode mais te salvar. Isso porque, POO precisa que haja estados mutáveis. Os métodos dos objetos que você invoca, normalmente, servem para alterar o estado do objeto em questão ou de outro. E, trabalhando com concorrência, precisamos adicionar muita complexidade para mantermos sincronizadas todas as threads que utilizam esses objetos concorrentemente ou paralelamente. 115 | 116 | Eu não estou aqui para argumentar que você deve sair do seu paradigma atual para o FP (mesmo que [algumas pessoas digam pra você fazer](https://blog.inf.ed.ac.uk/sapm/2014/03/06/enemy-of-the-state-or-why-oop-is-not-suited-to-large-scale-software/), mas definitivamente você precisa dominá-lo: O Java 8 e C++11 incorporaram as expressões lambda em suas plataformas. Posso afirmar que toda linguagem moderna e ainda mantida vai contar com features de FP em breve. E a maioria delas já tem. 117 | 118 | Vale a pena mencionar que você não vai parar de usar estados mutáveis. Nós precisamos para desenvolver funcionalidades como IO e etc, para termos bons softwares. Porém, a ideia principal que FP provê é: use estados mutáveis apenas quando for necessário. 119 | 120 | ## Eu não trabalho com Cloud, eu realmente preciso de FP? 121 | 122 | Sim. 123 | 124 | Programação Funcional irá te ajudar a escrever melhores programas e raciocinar sobre os problemas que você tem que resolver. 125 | 126 | >"Eu tentei. Mas é muito complexo e tem péssima legibilidade." 127 | 128 | Tudo é difícil no começo. Eu tenho certeza que você ralou para aprender a programar e também para aprender POO. Provavelmente começar a fazer algo em POO foi mais fácil do que escrever seu primeiro programa. Principalmente porque você já estava familiarizado com alguns conceitos comuns, como declaração de variáveis e estruturas de repetição como *for*/*while*. 129 | 130 | Para começar com FP, é quase como começar a aprender a programar de novo (dependendo de qual linguagem você escolher, será definitivamente como aprender a programar do zero). 131 | 132 | Muitos podem argumentar que FP tem má legibilidade. Se você vem de um *background* imperativo, códigos funcionais irão parecer como uma linguagem criptografada. Não porque está realmente criptografado, mas porque você ainda não conhece os conceitos comuns. Uma vez que você dominar esses fundamentos, se tornará muito mais fácil de ler. 133 | 134 | Veja esse código a seguir, escrito em Haskell e JavaScript (usando estilo imperativo): 135 | 136 | ```haskell 137 | guess :: Int -> [Char] 138 | guess 7 = "Much 7 very wow." 139 | guess x = "Ooops, try again." 140 | ``` 141 | 142 | ```js 143 | function guess(x){ 144 | if(x == 7){ 145 | return "Much 7 very wow." 146 | } 147 | else { 148 | return "Oops, try again." 149 | } 150 | } 151 | ``` 152 | 153 | Esse é um programa muito simples que exibe uma mensagem de parabéns quando o usuário digita `7` e uma mensagem de erro para outros valores. Pode parecer magia negra como o Haskell faz isso em apenas 2 linhas de código (ignore a primeira linha por enquanto, é apenas "anotações de tipo"). Mas é muito simples depois que você entende *Pattern Matching* (que não é só implementado em linguagens FP, mas principalmente nelas). 154 | 155 | O que o Haskell está fazendo: 156 | 157 | Se o argumento da função `guess` for igual a `7`, retorna **"Much 7 very wow."** ou retorne **“Ooops, try again.”** para qualquer outro valor. E é exatamente o que o código JavaScript está fazendo, mas o Haskell está identificando através de um "padrão" provido pelo programador. 158 | 159 | Pode parecer que não vale a pena usar isso uma vez que você pode simplesmente usar um if/else. Mas isso é muito poderoso quando estamos trabalhando com estruturas de dados complexas. 160 | 161 | ```haskell 162 | plus1 :: [Int] -> [Int] 163 | plus1 [] = [] 164 | plus1 (x:xs) = x + 1 : plus1 xs 165 | 166 | -- plus1 [0,1,2,3] 167 | -- > [1,2,3,4] 168 | ``` 169 | 170 | No programa acima, **plus1** é uma função que recebe uma lista de Ints e e adiciona `1` para cada elemento da lista. Ele identifica o padrão de uma lista vazia `[]` (e retorna outra lista vazia, já que não há elementos para adicionar `1`) e quando ele identificar o padrão de uma lista com elementos: nomeia o primeiro elemento da lista como **x** e os elementos restantes como **xs**. Então, executa a soma e concatena com o retorno da chamada recursiva. 171 | 172 | Eu tenho certeza que você passaria por maus bocados tentando reescrever a função `plus1` usando estilo imperativo em duas linhas de código e ainda deixá-lo legível. 173 | 174 | 175 | ## Então, vamos começar 176 | 177 | Exite muito conteúdo por aí falando sobre Programação Funcional, mas alguns que você não pode perder são: 178 | 179 | * [Principles of Functional Programming in Scala](https://www.coursera.org/course/progfun) 180 | 181 | * [Introduction to Functional Programming](https://www.edx.org/course/introduction-functional-programming-delftx-fp101x) ([Contents](https://github.com/fptudelft/FP101x-Content)) 182 | * [Paradigms of Computer Programming — Fundamentals](https://www.edx.org/course/paradigms-computer-programming-louvainx-louv1-1x#.VKXX2orF_rd) 183 | 184 | Infelizmente, eles costumam iniciar no fim do ano, mas você pode seguir o conteúdo e os videos que estão disponíveis no youtube. 185 | 186 | Por outro lado, se você prefere livros, eu recomendo fortemente esses a seguir: 187 | 188 | * [Structure and Interpretation of Computer Programs](https://mitpress.mit.edu/sicp/full-text/book/book.html) 189 | 190 | * [How to Design Programs](http://htdp.org/) 191 | 192 | * [Concepts, Techniques, and Models of Computer Programming](http://www.amazon.com/Concepts-Techniques-Models-Computer-Programming/dp/0262220695) 193 | 194 | Boa Sorte no seu novo ano Funcional! ☺ 195 | -------------------------------------------------------------------------------- /javascript/009-uma-suave-introducao-ao-javascript-parte-1.md: -------------------------------------------------------------------------------- 1 | # Uma Suave Introdução ao JavaScript Funcional: Parte 1 2 | 3 | * **Artigo Original**: [A GENTLE INTRODUCTION TO FUNCTIONAL JAVASCRIPT: PART 1](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-intro/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | > *Escrito por James Sinclair em 29 de Janeiro de 2016* 7 | 8 | Essa é a parte um de uma série de quatro artigos introduzindo a programação funcional no JavaScript. Nesse artigo, vamos ver os blocos fundamentais que fazem o JavaScript uma linguagem funcional, e vamos examinar como isso pode ser útil. 9 | 10 | - Parte 1: Blocos fundamentais e motivação (esse artigo) 11 | - [Parte 2: Trabalhando com Arrays e Listas](010-uma-suave-introducao-ao-javascript-parte-2.md) 12 | - [Parte 3: Funções para fazer funções](011-uma-suave-introducao-ao-javascript-parte-3.md) 13 | - Parte 4: Fazendo isso com estilo 14 | 15 | ## Por que Funcional? 16 | O que é toda essa propaganda sobre JavaScript Funcional? E por que isso é chamado *funcional*? Não é como se houvesse alguém que parasse para escrever JavaScript *dis*funcional ou JavaScript que não funciona. Para que isso é bom? Por que você deveria se preocupar? 17 | 18 | Para mim, aprender programação funcional é um pouco como [obter um Thermomix](https://www.youtube.com/watch?v=4yr_etbfZtQ&feature=youtu.be): 19 | 20 | - É um preciso um investimento inicial; 21 | - Você vai começar a dizer para seus amigos e família o quão incrível isso é; 22 | - Eles começam a se perguntar se você se juntou a algum tipo de culto. 23 | 24 | Mas isso realmente faz algumas tarefas de uma forma muito mais simples. Isso pode até automatizar certas coisas que de outra forma seriam muito tediosas e gastariam um bom tempo para serem feitas. 25 | 26 | ## Blocos Fundamentais 27 | Vamos começar com algumas funcionalidades básicas do JavaScript que tornam a programação "funcional" possível, antes de irmos para porque isso é uma boa ideia. No JavaScript nós temos dois blocos fundamentais: *variáveis* e *funções*. Variáveis são como contêineres que podemos colocar coisas dentro. Você pode criar um assim: 28 | 29 | ```js 30 | var myContainer = "Hey everybody! Come see how good I look!"; 31 | ``` 32 | 33 | Isso cria um contêiner chamado `myContainer` e coloca uma *string* nele. 34 | 35 | Agora a função, por outro lado, é uma forma de agrupar algumas instruções para que você possa usá-las novamente, ou apenas deixar as coisas organizadas, dessa forma você não vai ficar tentando pensar em tudo de uma vez. Pode-se criar uma função assim: 36 | 37 | ```js 38 | function log(someVariable) { 39 | console.log(someVariable); 40 | return someVariable; 41 | } 42 | ``` 43 | 44 | E você pode chamar uma função assim: 45 | 46 | ```js 47 | log(myContainer); 48 | // Hey everybody! Come see how good I look! 49 | ``` 50 | 51 | Mas, o fato é, se você já viu algum JavaScript anteriormente, então você vai saber que também podemos escrever e chamar nossa função dessa forma: 52 | 53 | ```js 54 | var log = function(someVariable) { 55 | console.log(someVariable); 56 | return someVariable; 57 | } 58 | 59 | log(myContainer); 60 | // Hey everybody! Come see how good I look! 61 | ``` 62 | 63 | Vamos olhar para isso cuidadosamente. Quando escrevemos a definição da função dessa forma, parece que criamos uma variável chamada `log` e grudamos uma função nela. E isso é exatamente o que fizemos. Nossa função `log` *é* uma variável; o que significa que podemos fazer as mesmas coisas que fazemos com outras variáveis. 64 | 65 | Vamos testar isso. Poderíamos, talvez, passar uma função como um parâmetro para outra função? 66 | 67 | ```js 68 | var classyMessage = function() { 69 | return "Stay classy San Diego!"; 70 | } 71 | 72 | log(classyMessage); 73 | // [Function] 74 | ``` 75 | 76 | Bem, não muito útil. Vamos testar de uma forma diferente. 77 | 78 | ```js 79 | var doSomething = function(thing) { 80 | thing(); 81 | } 82 | 83 | var sayBigDeal = function() { 84 | var message = "I’m kind of a big deal"; 85 | log(message); 86 | } 87 | 88 | doSomething(sayBigDeal); 89 | // I’m kind of a big deal 90 | ``` 91 | 92 | Isso pode não ser muito excitante para você, mas cientistas da computação ficam bastante animados. Essa habilidade de colocar funções dentro de variáveis é algumas vezes descrita dizendo que "funções são objetos de primeira classe no JavaScript". O que isso quer dizer é que funções (praticamente) não são tratadas de forma diferente de outros tipos de dados como objetos e *strings*. E essa pequena funcionalidade é surpreendentemente poderosa. Para entender porque, porém, precisamos de falar sobre código *DRY*. 93 | 94 | ## *Don't Repeat Yourself* (Não se repita) 95 | Programadores gostam de falar sobre o princípio DRY - Don't Repeat Yourself. A ideia é que se você precisa fazer a mesma série de tarefas várias vezes, junte-as em algum tipo de pacote reutilizável (como uma função). Dessa forma, se você precisar alterar algo nessa série de tarefas, você consegue fazer isso em apenas um lugar. 96 | 97 | Vamos ver um exemplo. Digamos que nós queremos colocar 3 carrosséis em uma página usando uma biblioteca de carrossel (uma biblioteca imaginária para exemplificar): 98 | 99 | ```js 100 | var el1 = document.getElementById('main-carousel'); 101 | var slider1 = new Carousel(el1, 3000); 102 | slider1.init(); 103 | 104 | var el2 = document.getElementById('news-carousel'); 105 | var slider2 = new Carousel(el2, 5000); 106 | slider2.init(); 107 | 108 | var el3 = document.getElementById('events-carousel'); 109 | var slider3 = new Carousel(el3, 7000); 110 | slider3.init(); 111 | ``` 112 | 113 | Esse código é um tanto repetitivo. Desejamos inicializar um carrossel para os elementos da página, cada um com um ID específico. Então, vamos descrever como inicializar um carrossel em uma função, e então chamar essa função para cada ID. 114 | 115 | ```js 116 | function initialiseCarousel(id, frequency) { 117 | var el = document.getElementById(id); 118 | var slider = new Carousel(el, frequency); 119 | slider.init(); 120 | return slider; 121 | } 122 | 123 | initialiseCarousel('main-carousel', 3000); 124 | initialiseCarousel('news-carousel', 5000); 125 | initialiseCarousel('events-carousel', 7000); 126 | ``` 127 | 128 | Esse código é mais claro e simples de manter. E temos um padrão a seguir: quando tivermos o mesmo conjunto de ações que queremos tomar em diferentes conjuntos de dados, podemos encapsular essas ações em uma função. Mas e se tivermos um padrão onde as ações alteram? 129 | 130 | ```js 131 | var unicornEl = document.getElementById('unicorn'); 132 | unicornEl.className += ' magic'; 133 | spin(unicornEl); 134 | 135 | var fairyEl = document.getElementById('fairy'); 136 | fairyEl.className += ' magic'; 137 | sparkle(fairyEl); 138 | 139 | var kittenEl = document.getElementById('kitten'); 140 | kittenEl.className += ' magic'; 141 | rainbowTrail(kittenEl); 142 | ``` 143 | 144 | Esse código é um pouco mais complicado de se refatorar. Existe definitivamente um padrão repetido, mas estamos chamando uma função diferente para cada elemento. Podemos resolver parte do problema encapsulando a chamada `document.getElementById()` e adicionando a `className` dentro de uma função. Isso vai salvar um pouco de repetição: 145 | 146 | ```js 147 | function addMagicClass(id) { 148 | var element = document.getElementById(id); 149 | element.className += ' magic'; 150 | return element; 151 | } 152 | 153 | var unicornEl = addMagicClass('unicorn'); 154 | spin(unicornEl); 155 | 156 | var fairyEl = addMagicClass('fairy'); 157 | sparkle(fairyEl); 158 | 159 | var kittenEl = addMagicClass('kitten'); 160 | rainbow(kittenEl); 161 | ``` 162 | 163 | Mas podemos fazer isso ainda mais DRY, se lembrarmos que o JavaScript permite que passemos funções como parâmetros para outras funções: 164 | 165 | ```js 166 | function addMagic(id, effect) { 167 | var element = document.getElementById(id); 168 | element.className += ' magic'; 169 | effect(element); 170 | } 171 | 172 | addMagic('unicorn', spin); 173 | addMagic('fairy', sparkle); 174 | addMagic('kitten', rainbow); 175 | ``` 176 | 177 | Isso é muito mais conciso e fácil de manter. A habilidade de passar funções como variáveis abre muitas possibilidades. Na próxima parte vamos olhar como usar essa habilidade para trabalhar com *arrays* de uma forma mais agradável. 178 | -------------------------------------------------------------------------------- /javascript/010-uma-suave-introducao-ao-javascript-parte-2.md: -------------------------------------------------------------------------------- 1 | # Uma Suave Introdução ao JavaScript Funcional: Parte 2 2 | 3 | * **Artigo Original**: [A GENTLE INTRODUCTION TO FUNCTIONAL JAVASCRIPT: PART 2](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-arrays/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | > *Escrito por James Sinclair em 30 de Janeiro de 2016* 7 | 8 | Essa é a parte 2 de uma série de 4 artigos introduzindo a programação funcional no JavaScript. No artigo anterior, nós vimos como as funções podem ser usadas para fazer abstrações de código de forma mais fácil. Nesse artigo vamos aplicar essas técnicas em listas. 9 | 10 | - [Parte 1: Blocos fundamentais e motivação](009-uma-suave-introducao-ao-javascript-parte-1.md) 11 | - Parte 2: Trabalhando com Arrays e Listas (esse artigo) 12 | - [Parte 3: Funções para fazer funções](011-uma-suave-introducao-ao-javascript-parte-3.md) 13 | - Parte 4: Fazendo isso com estilo 14 | 15 | ## Trabalhando com Arrays e Listas 16 | Relembre que no artigo anterior, falamos sobre código DRY. Vimos que funções são úteis para juntar grupos de ações que podem se repetir. Mas e se estivermos repetindo a mesma função várias vezes? Por exemplo: 17 | 18 | ```js 19 | function addColour(colour) { 20 | var rainbowEl = document.getElementById('rainbow'); 21 | var div = document.createElement('div'); 22 | div.style.paddingTop = '10px'; 23 | div.style.backgroundColour = colour; 24 | rainbowEl.appendChild(div); 25 | } 26 | 27 | addColour('red'); 28 | addColour('orange'); 29 | addColour('yellow'); 30 | addColour('green'); 31 | addColour('blue'); 32 | addColour('purple'); 33 | ``` 34 | 35 | A função `addColor` é chamada várias vezes. Estamos nos repetindo - algo que queremos evitar. Uma forma de evitar isso é movendo a lista de cores para um array, e chamar `addColor` em um loop `for`: 36 | 37 | ```js 38 | var colours = [ 39 | 'red', 'orange', 'yellow', 40 | 'green', 'blue', 'purple' 41 | ]; 42 | 43 | for (var i = 0; i < colours.length; i = i + 1) { 44 | addColour(colours[i]); 45 | } 46 | ``` 47 | 48 | Esse código é perfeitamente aceitável. Ele finaliza o trabalho e é menos repetitivo que a versão anterior. Mas não é particularmente expressivo. Temos que dar ao computador instruções muito específicas sobre criar uma variável de indicação (*index*) e incrementá-la, verificando se é hora de parar. E se pudéssemos encapsular todo esse loop `for` em uma função? 49 | 50 | ### For-Each (Para Cada) 51 | Uma vez que o JavaScript nos permite passar uma função como parâmetro para outra função, escrever uma função `forEach` é relativamente simples: 52 | 53 | ```js 54 | function forEach(callback, array) { 55 | for (var i = 0; i < array.length; i = i + 1) { 56 | callback(array[i], i); 57 | } 58 | } 59 | ``` 60 | 61 | Essa função recebe outra função, `callback`, como um parâmetro e a chama em cada item do array. 62 | 63 | Agora, com nosso exemplo, nós queremos rodar a função `addColor` em cada item no array. Usando nossa função `forEach` podemos expressar essa intenção em apenas uma linha: 64 | 65 | ```js 66 | forEach(addColour, colours); 67 | ``` 68 | 69 | Chamar uma função em cada item de um array é uma ferramenta tão útil que implementações modernas do JavaScript incluem isso como uma função nativa nos arrays. Então ao invés de usarmos nossa própria função `forEach`, podemos usar a função nativa dessa forma: 70 | 71 | ```js 72 | var colours = [ 73 | 'red', 'orange', 'yellow', 74 | 'green', 'blue', 'purple' 75 | ]; 76 | 77 | colours.forEach(addColour); 78 | ``` 79 | 80 | Você pode achar mais informações sobre o método nativo [`forEach` na referência JavaScript da MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) 81 | 82 | ### Map 83 | Nossa função `forEach` é útil, mas é de alguma forma limitada. Se a função *callback* que passamos retornar um valor, `forEach` apenas ignora-o. Com um pequeno ajuste, podemos alterar nossa função `forEach` e ela vai nos dar qualquer valor que a função callback retornar. Vamos ter então um novo array com o valor correspondente a cada valor no array original. 84 | 85 | Vamos ver um exemplo. Se temos um arrays com IDs, e queremos pegar o elemento correspondente a cada um deles. Em uma solução da forma procedural usaríamos um loop `for`: 86 | 87 | ```js 88 | var ids = ['unicorn', 'fairy', 'kitten']; 89 | var elements = []; 90 | for (var i = 0; i < ids.length; i = i + 1) { 91 | elements[i] = document.getElementById(ids[i]); 92 | } 93 | // elements now contains the elements we are after 94 | ``` 95 | 96 | Novamente, tivemos que dizer ao computador como criar uma variável *index* e incrementá-la - detalhes que realmente não devemos nos preocupar. Vamos refatorar o loop `for` assim como fizemos com `forEach` e colocá-lo numa função chamada `map`: 97 | 98 | ```js 99 | var map = function(callback, array) { 100 | var newArray = []; 101 | for (var i = 0; i < array.length; i = i + 1) { 102 | newArray[i] = callback(array[i], i); 103 | } 104 | return newArray; 105 | } 106 | ``` 107 | 108 | A função `map` pega funções pequenas e triviais, tornando-as em funções super-herói - ela multiplica a efetividade da função aplicando-a em um array inteiro apenas com uma chamada. 109 | 110 | Assim como `forEach`, `map` é tão útil que implementações modernas do JavaScript a tem como um método nativo para objetos array. Você pode chamar o método nativo da seguinte forma: 111 | 112 | ```js 113 | var ids = ['unicorn', 'fairy', 'kitten']; 114 | var getElement = function(id) { 115 | return document.getElementById(id); 116 | }; 117 | var elements = ids.map(getElement); 118 | ``` 119 | 120 | Você pode ler mais sobre o método nativo [`map` na referência JavaScript da MDN.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 121 | 122 | ### Reduce 123 | `map` é muito útil, mas nós podemos fazer uma função ainda mais poderosa se pegarmos um array inteiro e retornar apenas um valor. Isso pode parecer inicialmente um pouco contraintuitivo - como uma função que retorna um valor ao invés de vários é mais *poderosa*? Para descobrir o porquê, temos que primeiro olhar como essa função trabalha. 124 | 125 | Para ilustrar, vamos considerar dois problemas similares: 126 | 127 | 1. Dado um array de números, calcule a soma; e 128 | 1. Dado um array de palavras, junte-as com um espaço entre cada palavra. 129 | 130 | Isso pode parecer exemplos bobos, triviais - e eles são. Mas tenha paciência comigo, após vermos como a função `reduce` trabalha, nós vamos aplicá-la de formas mais interessantes. 131 | 132 | A forma "procedural" de resolver esses problemas é, novamente, com loops `for`: 133 | 134 | ```js 135 | // Given an array of numbers, calculate the sum 136 | var numbers = [1, 3, 5, 7, 9]; 137 | var total = 0; 138 | for (var i = 0; i < numbers.length; i = i + 1) { 139 | total = total + numbers[i]; 140 | } 141 | // total is 25 142 | 143 | // Given an array of words, join them together with a space between each word. 144 | var words = ['sparkle', 'fairies', 'are', 'amazing']; 145 | var sentence = ''; 146 | for (i = 0; i < words.length; i++) { 147 | sentence = sentence + ' ' + words[i]; 148 | } 149 | // ' sparkle fairies are amazing' 150 | ``` 151 | 152 | Essas duas soluções tem muito em comum. Ambas usam um loop `for` para iterar sobre um array; ambas tem uma variável trabalhando ( `total` e `sentence`); e ambas definem o valor trabalhado com um valor inicial. 153 | 154 | Vamos refatorar a parte interior de cada loop, e tornar isso em uma função: 155 | 156 | ```js 157 | var add = function(a, b) { 158 | return a + b; 159 | } 160 | 161 | // Given an array of numbers, calculate the sum 162 | var numbers = [1, 3, 5, 7, 9]; 163 | var total = 0; 164 | for (i = 0; i < numbers.length; i = i + 1) { 165 | total = add(total, numbers[i]); 166 | } 167 | // total is 25 168 | 169 | function joinWord(sentence, word) { 170 | return sentence + ' ' + word; 171 | } 172 | 173 | // Given an array of words, join them together with a space between each word. 174 | var words = ['sparkle', 'fairies', 'are', 'amazing']; 175 | var sentence = ''; 176 | for (i = 0; i < words.length; i++) { 177 | sentence = joinWord(sentence, words[i]); 178 | } 179 | // 'sparkle fairies are amazing' 180 | ``` 181 | 182 | Isso é muito mais conciso e o padrão ficou claro. Ambas funções interiores pegam a variável de trabalho como primeiro parâmetro e o elemento atual do array como segundo. Agora que conseguimos ver o padrão de forma mais clara, nós podemos mover os loops `for` para dentro da função: 183 | 184 | ```js 185 | var reduce = function(callback, initialValue, array) { 186 | var working = initialValue; 187 | for (var i = 0; i < array.length; i = i + 1) { 188 | working = callback(working, array[i]); 189 | } 190 | return working; 191 | }; 192 | ``` 193 | 194 | Agora que temos nossa função `reduce`, vamos usá-la: 195 | 196 | ```js 197 | var total = reduce(add, 0, numbers); 198 | var sentence = reduce(joinWord, '', words); 199 | ``` 200 | 201 | Assim como `forEach` e `map`, `reduce` também é nativa no padrão JavaScript como um método do objeto Array. Podemos usá-la assim: 202 | 203 | ```js 204 | var total = numbers.reduce(add, 0); 205 | var sentence = words.reduce(joinWord, ''); 206 | ``` 207 | 208 | Você pode ler mais sobre o método nativo [`reduce` na referência JavaScript do MDN.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) 209 | 210 | ## Juntando Tudo 211 | Como mencionamos anteriormente, esses são exemplos triviais - as funções `add` e `joinWord` são muito simples - e esse é o ponto na verdade. Funções simples e pequenas são mais fáceis de pensar e testar. Mesmo quando pegamos duas funções pequenas e simples e as combinamos (como `add` e `reduce` por exemplo), o resultado ainda é mais fácil de se imaginar do que uma única função gigante e complicada. Mas, com isso dito, podemos fazer coisas mais interessantes do que adicionar números. 212 | 213 | Vamos tentar fazer algo um pouco mais complicado. Começaremos com dados formatados de forma não convencional, e usar as funções `map` e `reduce` para transformar isso em uma lista HTML. Aqui estão nossos dados: 214 | 215 | ```js 216 | var ponies = [ 217 | [ 218 | ['name', 'Fluttershy'], 219 | ['image', 'http://tinyurl.com/gpbnlf6'], 220 | ['description', 'Fluttershy is a female Pegasus pony and one of the main characters of My Little Pony Friendship is Magic.'] 221 | ], 222 | [ 223 | ['name', 'Applejack'], 224 | ['image', 'http://tinyurl.com/gkur8a6'], 225 | ['description', 'Applejack is a female Earth pony and one of the main characters of My Little Pony Friendship is Magic.'] 226 | ], 227 | [ 228 | ['name', 'Twilight Sparkle'], 229 | ['image', 'http://tinyurl.com/hj877vs'], 230 | ['description', 'Twilight Sparkle is the primary main character of My Little Pony Friendship is Magic.'] 231 | ] 232 | ]; 233 | ``` 234 | 235 | 236 | Os dados não estão muito arrumados. Seria muito mais claro se os arrays internos fossem objetos bem formatados. Previamente, nós usamos a função `reduce` para calcular simples valores como *strings* e números, mas ninguém disse que o valor retornado por `reduce` tem que ser simples. Nós podemos usar essa função com objetos, arrays ou até mesmo elementos DOM. Vamos criar uma função que recebe um desses arrays internos (como `['name', 'Fluttershy']`) e adiciona esse par chave/valor a um objeto. 237 | 238 | ```js 239 | var addToObject = function(obj, arr) { 240 | obj[arr[0]] = arr[1]; 241 | return obj; 242 | }; 243 | ``` 244 | 245 | Com essa função `addToObject` podemos converter cada "pequeno" array em um objeto: 246 | 247 | ```js 248 | var ponyArrayToObject = function(ponyArray) { 249 | return reduce(addToObject, {}, ponyArray); 250 | }; 251 | ``` 252 | 253 | Se usarmos nossa função `map` poderemos converter todo o array em algo mais arrumado: 254 | 255 | ```js 256 | var tidyPonies = map(ponyArrayToObject, ponies); 257 | ``` 258 | 259 | Agora temos um array de pequenos objetos. Com uma ajuda do [pequeno *template engine* de Thomas Fuchs](http://mir.aculo.us/2011/03/09/little-helpers-a-tweet-sized-javascript-templating-engine/), podemos usar `reduce` novamente para converter isso em um fragmento HTML. A *função template* pega uma string template e um objeto, e onde ela achar palavras envoltas com chaves (como `{name}` ou `{image}`), ela vai trocá-las com o valor correspondente no objeto. Por exemplo: 260 | 261 | ```js 262 | var data = { name: "Fluttershy" }; 263 | t("Hello {name}!", data); 264 | // "Hello Fluttershy!" 265 | 266 | data = { who: "Fluttershy", time: Date.now() }; 267 | t("Hello {name}! It's {time} ms since epoch.", data); 268 | // "Hello Fluttershy! It's 1454135887369 ms since epoch." 269 | ``` 270 | 271 | Então se quisermos converter um pequeno objeto em um item de uma lista, podemos fazer algo assim: 272 | 273 | ```js 274 | var ponyToListItem = function(pony) { 275 | var template = '
  • {name}' + 276 | '

    {name}

    {description}

    ' + 277 | '
  • '; 278 | return t(template, pony); 279 | }; 280 | ``` 281 | 282 | Isso nos dá uma forma de converter um item individual em HTML, mas para converter todo o array, precisaremos das nossas funções `reduce` e `joinWords`: 283 | 284 | ```js 285 | var ponyList = map(ponyToListItem, tidyPonies); 286 | var html = ''; 287 | ``` 288 | 289 | Você pode ver o resultado final [aqui](http://jsbin.com/wuzini/edit?html,js,output) 290 | 291 | Uma vez que você entenda os padrões onde `map` e `reduce` são adequados, você não vai mais precisar de escrever um loop `for` da maneira antiga. De fato, é um desafio útil ver se você consegue evitar completamente a escrita de loops `for` no seu próximo projeto. Depois que você usar `map` e `reduce` algumas vezes, você vai começar a notar ainda mais padrões que podem ser abstraídos. Alguns comuns incluem *[filtrar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)* e *[arrancar](http://ramdajs.com/docs/#pluck)* valores de um array. Uma vez que esses padrões aparecem regularmente, algumas pessoas criaram bibliotecas de programação funcional, assim você pode reutilizar código para solucionar padrões comuns. Algumas das bibliotecas mais populares são: 292 | 293 | - [Ramda](http://ramdajs.com/), 294 | - [Lodash](https://lodash.com/), e 295 | - [Underscore](http://underscorejs.org/). 296 | 297 | Agora que você viu quão útil é passar funções como variáveis, especialmente quando estamos lidando com listas, você deve ter um grande novo conjunto de técnicas no seu cinto de utildades metafórico. E se você escolher ir embora agora, está tudo bem. Você pode finalizar a leitura e ninguém vai pensar nada de ruim sobre você. Você pode ir e ser um programador bem sucedido e produtivo, e nunca perturbar seus sonhos com as complexidades da *partial application* (aplicação parcial), *currying* e *composition* (composição). Essas coisas não são para todo mundo. 298 | 299 | Mas, se você estiver afim de um pouco de aventura, [você pode continuar lendo e ver quão fundo a toca do coelho vai...](011-uma-suave-introducao-ao-javascript-parte-3.md) 300 | -------------------------------------------------------------------------------- /javascript/012-uma-suave-introducao-ao-javascript-parte-4.md: -------------------------------------------------------------------------------- 1 | # Uma Suave Introdução ao JavaScript Funcional: Parte 4 2 | 3 | * **Artigo Original**: [A GENTLE INTRODUCTION TO FUNCTIONAL JAVASCRIPT: PART 4](http://jrsinclair.com/articles/2016/gentle-introduction-to-functional-javascript-style/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | > *Escrito por James Sinclair em 11 de Fevereiro de 2016* 7 | 8 | Essa é a parte 4 de uma série de 4 artigos sobre introdução a programação funcional no JavaScript. No último artigo vamos ver sobre *high-order functions* (funções de ordem superior): funções para criar funções. Nesse artigo, nós discutimos como usar essas novas ferramentas com estilo. 9 | 10 | - [Parte 1: Blocos fundamentais e motivação](009-uma-suave-introducao-ao-javascript-parte-1.md) 11 | - [Parte 2: Trabalhando com Arrays e Listas](010-uma-suave-introducao-ao-javascript-parte-2.md) 12 | - [Parte 3: Funções para fazer funções](011-uma-suave-introducao-ao-javascript-parte-3.md) 13 | - Parte 4: Fazendo isso com estilo (esse artigo) 14 | 15 | ## Fazendo Isso Com Estilo 16 | No artigo anterior vimos sobre `partial`, `compose`, `curry`, `pipe`, e também como podemos usá-las para juntar pequenas, simples funções e criar outras grandes e complicadas. Mas o que isso faz pra gente? Vale a pena se importar quando já estamos escrevendo código perfeitamente válido? 17 | 18 | Parte da resposta é que sempre é útil ter mais ferramentas disponíveis para realizar o trabalho - desde que você saiba como usá-las - e programação funcional certamente nos dá um conjunto útil de ferramentas para escrever JavaScript. Mas eu penso que há mais do que isso. Programação Funcional nos abre um diferente *estilo* de programação. Isso por sua vez nos permite conceitualizar problemas e soluções de formas diferentes. 19 | 20 | Existem duas funcionalidades chave para programação funcional: 21 | 22 | 1. Escrever funções puras, o que é importante se você deseja testar programação funcional; e 23 | 1. Estilo de programação *pointfree* (sem pontos), o que não é *tão* importante mas é bom de se entender. 24 | 25 | ### Pureza 26 | Se você ler sobre programação funcional, você irá se deparar com o conceito de funções *puras* e *impuras*. Funções puras são funções que preenchem dois critérios: 27 | 28 | 1. Chamar a função com as mesmas entradas sempre *retorna* as mesmas saídas. 29 | 1. Chamar a função não produz efeitos colaterais: Sem chamadas na rede (*network*); nenhuma leitura ou escrita de arquivos; nenhuma consulta em banco de dados; nenhum elemento DOM modificado; nenhuma modificação de variáveis globais; e nenhuma saída no console. Nada. 30 | 31 | Funções impuras deixam programadores funcionais desconfortáveis. Tão desconfortáveis que eles as evitam o máximo possível. O problema com isso é que o grande ponto de escrever programas de computador *são* os efeitos colaterais. Fazer uma chamada na rede e renderizar elementos DOM está no núcleo do que uma aplicação web faz; esse foi o motivo pelo qual o JavaScript foi inventado. 32 | 33 | Então o que um aspirante a programador funcional faz? Bom, a chave é que nós não evitamos funções impuras inteiramente, nós apenas damos a elas uma boa quantidade de respeito, e deixamos de lidar com elas até que nós absolutamente precisemos. Elaboramos um plano claro e testado para o que queremos fazer *antes* de tentar fazer isso. Como Eric Elliot colocou em [*The Dao of Immutability*](https://medium.com/javascript-scene/the-dao-of-immutability-9f91a70c88cd): 34 | 35 | > **Separação:** Lógica é pensamento. Efeitos são ações. Portanto, o sábio pensa antes de agir, e age somente quando o pensamento está terminado. Se você tentar executar efeitos e lógica ao mesmo tempo, você vai criar efeitos colaterais ocultos que causam *bugs* (problemas) na lógica. Mantenha as funções pequenas. Faça uma coisa de cada vez, e faça isso bem. 36 | 37 | Em outras palavras, com programação funcional, nós geralmente trabalhamos a lógica do que estamos tentando fazer primeiro, antes de fazer qualquer coisa que potencialmente tenha efeitos colaterais. 38 | 39 | Outra forma de pensar sobre isso é a diferença de usar uma metralhadora e um *rifle sniper*. Com a metralhadora você dispara o máximo de balas possível, contando com o fato que se você continuar atirando, eventualmente você vai acertar algo. Mas você pode também acertar coisas que você não queria. Porém um rifle sniper é direfente. Você escolhe o lugar mais vantajoso, alinha o tiro, toma em conta a velocidade do vento e a distância do alvo. Você pacientemente, metodicamente, cuidadosamente configura todas as coisas e no momento certo, puxa o gatilho. Muito menos munição, e um efeito muito mais preciso. 40 | 41 | Então como tornamos nossas funções puras? Vamos ver um exemplo: 42 | 43 | ```js 44 | var myGlobalMessage = '{{verb}} me'; 45 | 46 | var impureInstruction = function(verb) { 47 | return myGlobalMessage.replace('{{verb}}', verb); 48 | } 49 | 50 | var eatMe = impureInstruction('Eat'); 51 | //=> 'Eat me' 52 | var drinkMe = impureInstruction('Drink'); 53 | //=> 'Drink me' 54 | ``` 55 | 56 | Essa função é impura pois depende da variável global `myGlobalMessage`. Se a variável mudar, se torna difícil dizer o que `impureInstruction` vai fazer. Uma forma de torná-la pura é mover a variável para dentro: 57 | 58 | ```js 59 | var pureInstruction = function (verb) { 60 | var message = '{{verb}} me'; 61 | return message.replace('{{verb}}', verb); 62 | } 63 | ``` 64 | 65 | Essa função agora vai sempre retornar o mesmo resultado dado um mesmo conjunto de entradas. Mas algumas vezes não podemos usar essa ténica. Por exemplo: 66 | 67 | ```js 68 | var getHTMLImpure = function(id) { 69 | var el = document.getElementById(id); 70 | return el.innerHTML; 71 | } 72 | ``` 73 | 74 | Essa função é impura pois depende do objeto `document` para acessar o DOM. Se o DOM mudar isso *pode* produzir resultados diferentes. Mas nós não podemos definir `document` dentro de nossa função porque isso é uma API do navegador, mas nós *podemos* passar isso como um parâmetro: 75 | 76 | ```js 77 | var getHTML = function(doc, id) { 78 | var el = doc.getElementById(id); 79 | return el.innerHTML; 80 | } 81 | ``` 82 | 83 | Isso pode parecer trivial e sem sentido, mas é uma técnica útil. Imagine você estava tentando fazer um teste unitário nessa função. Normalmente, teríamos que configurar algum tipo de browser para pegar o objeto `document` e poder testar isso. Uma vez que temos o parâmetro `doc`, é fácil passar um objeto *stub* - uma simulação do objeto real - ao invés disso: 84 | 85 | ```js 86 | var stubDoc = { 87 | getElementById: function(id) { 88 | if (id === 'jabberwocky') { 89 | return { 90 | innerHTML: '

    Twas brillig…' 91 | }; 92 | } 93 | } 94 | }; 95 | 96 | assert.equal(getHTML('jabberwocky'), '

    Twas brillig…'); 97 | //=> test passes 98 | ``` 99 | 100 | Escrever esse *stub* pode parecer um pouco trabalhoso, mas agora podemos testar essa função sem precisar de um navegador. Se quisermos, podemos rodar isso na linha de comando sem um navegador *headless*. E como um bônus, o teste vai rodar muito, muito mais rápido do que um que tenha o objeto `document` inteiro. 101 | 102 | Uma outra forma de ter uma função pura é retornar outra função que eventualmente irá fazer algo impuro quando a chamarmos. Isso inicialmente parece um truque sujo, mas é totalmente legítimo. Por exemplo: 103 | 104 | ```js 105 | var htmlGetter = function(id) { 106 | return function() { 107 | var el = document.getElementById(id); 108 | return el.innerHTML; 109 | } 110 | } 111 | ``` 112 | 113 | A função `htmlGetter` é pura porque rodando-a não acessamos uma variável global - ao invés disso, ela sempre retorna exatamente a mesma função. 114 | 115 | Fazer coisas dessa forma não é muito útil para testes unitários, e isso não remove a impureza completamente - apenas a posterga. E isso não é necessariamente uma coisa ruim. Lembre-se, queremos lidar com toda a lógica previamente nas funções puras e depois puxar o gatilho em quaisquer efeitos colaterais. 116 | 117 | ### *Pointfree* (sem pontos) 118 | Programação *Pointfree* ou programação *tácita* é um estilo particular de programação que funções de ordem superior como `curry` e `compose` tornam possível. Para explicar isso, vamos olhar novamente para o exemplo do poema do último artigo: 119 | 120 | > **Nota do tradutor:** Programação tácita, também chamada estilo **point-free** (sem pontos), é um paradigma de programação em que definições de função não identificam os argumentos (ou "pontos") em que elas operam. Ao invés disso, as definições meramente compõem outras funções, onde essas são combinadores que manipulam os argumentos. [Fonte](https://en.wikipedia.org/wiki/Tacit_programming). 121 | 122 | ```js 123 | var poem = 'Twas brillig, and the slithy toves\n' + 124 | 'Did gyre and gimble in the wabe;\n' + 125 | 'All mimsy were the borogoves,\n' + 126 | 'And the mome raths outgrabe.'; 127 | 128 | var replace = curry(function(find, replacement, str) { 129 | var regex = new RegExp(find, 'g'); 130 | return str.replace(regex, replacement); 131 | }); 132 | 133 | var wrapWith = curry(function(tag, str) { 134 | return '<' + tag + '>' + str + ''; 135 | }); 136 | 137 | var addBreaks = replace('\n', '
    \n'); 138 | var replaceBrillig = replace('brillig', wrapWith('em', 'four o’clock in the afternoon')); 139 | var wrapP = wrapWith('p'); 140 | var wrapBlockquote = wrapWith('blockquote'); 141 | 142 | var modifyPoem = compose(wrapBlockquote, wrapP, addBreaks, replaceBrillig); 143 | ``` 144 | 145 | Note que `compose` espera que cada função passada receba exatamente um parâmetro. Então, usamos 'curry' para mudar nossas funções multi-parâmetros `replace` e `wrapWith` em funções de um único parâmetro. Note também que fomos um pouco criteriosos com a ordem de nossas funções, então `wrapWith`, por exemplo, recebe a *tag* como seu primeiro parâmetro ao invés do texto para ser envolvido. Se formos cuidadosos dessa forma na maneira como configuramos nossas funções, isso fará a criação de funções por composição fácil. 146 | 147 | > **Nota do autor**: A maioria das bibliotecas funcionais (como [Ramda](http://ramdajs.com/)), também incluem utilitários para trabalhar com funções que não tem seus parâmetros em uma ordem conveniente. 148 | 149 | Isso se torna tão fácil que você pode escrever *todo* o seu código dessa maneira. Mas note um pequeno efeito colateral: quando definimos a função `modifyPoem` final, nós nunca mencionamos em nenhum lugar que ela recebe um único argumento *string*. E se você olhar para as funções *curried*, `addBreaks`, `replaceBrillig`, `wrapP` e `wrapBlockquote`, nenhuma delas mencionam que recebem também apenas uma simples variável *string*. Isso é programação *pointfree* (sem pontos): começar com um conjunto base de funções utilitárias (como Ramda ou functional.js) e escrever seu código de uma forma que você nunca vai mencionar as variáveis de entrada. 150 | 151 | O que isso nos dá? Bom, nada de especial em relação ao próprio código. A coisa inteligente sobre o estilo sem pontos é que ele te força a usar `compose`, `curry`, `pipe`, etc. Por sua vez, isso *encoraja fortemente* que você mantenha funções pequenas e simples reunidas de maneira sensata. Em outras palavras, isso é uma limitação autoimposta, como um *haiku* ou um soneto. Nem toda poesia tem que ser escrita dessa forma - e seguir todas as regras não garante um belo poema - mas algumas poesias escritas nesses estilos podem ser incrivelmente belas. 152 | 153 | Fazer tudo no estilo sem pontos não é sempre prático. Algumas vezes, isso adiciona complicações desnecessárias em uma função simples. Mas dar uma chance e *tentar* escrever todas as suas funções sem pontos é uma boa maneira de entender melhor a programação funcional. 154 | 155 | ### Assinatura de Tipos de Hindley-Milner 156 | Uma vez que você esteja fazendo tudo "sem pontos" (*pointfree*), isso deixa uma dúvida, como comunicar outros programadores qual tipo de parâmetro eles devem passar para sua função. Para facilitar isso, programadores funcionais desenvolveram uma notação especial para especificar quais tipos de parâmetro uma função recebe, e o que ela retorna. A notação é chamada *assinatura de tipos de Hindley-Milner*. Nós a escrevemos como comentários onde definimos a função. Vamos ver alguns exemplos: 157 | 158 | ```js 159 | // instruction :: String -> String 160 | var instruction = function(verb) { 161 | return verb + ' me'; 162 | } 163 | ``` 164 | 165 | A assinatura de tipo diz que `instruction` recebe uma *String* como entrada e retorna outra *String*. Por enquanto, tudo bem. E se tivermos uma função que recebe dois parâmetros? 166 | 167 | ```js 168 | // wrapWith :: String -> (String -> String) 169 | var wrapWith = curry(function(tag, str) { 170 | return '<' + tag + '>' + str + ''; 171 | }); 172 | ``` 173 | 174 | Isso é um pouco mais complicado, mas não tão difícil. Essa notação diz que `wrapWith` recebe uma *String* e retorna uma *Função*, e essa função recebe uma *String* e retorna uma *String*. Note que isso funciona porque nós aplicamos *curry* na função. Quando estivermos usando esse estilo, está assumido que você sempre vai usar *curry* em todas suas funções. 175 | 176 | E algo com três parâmetros ao invés de dois? Uma forma de escrever isso seria: 177 | 178 | ```js 179 | // replace :: String -> (String -> (String -> String)) 180 | var replace = curry(function(find, replacement, str) { 181 | var regex = new RegExp(find, 'g'); 182 | return str.replace(regex, replacement); 183 | }); 184 | ``` 185 | 186 | Agora temos uma função que retorna uma função que retorna uma função que retorna uma *string*. Isso ainda faz sentido, mas porque sempre assumimos que tudo está sendo *curried*, tendemos a remover os parênteses: 187 | 188 | ```js 189 | // replace :: String -> String -> String -> String 190 | ``` 191 | 192 | E se tivermos um parâmetro de um tipo diferente: 193 | 194 | ```js 195 | // formatDollars :: Number -> String 196 | var formatDollars = replace('${{number}}', '{{number}}'); 197 | 198 | formatDollars(100); 199 | //=> $100 200 | ``` 201 | 202 | Aqui temos uma função sem pontos (*pointfree*), e se torna claro porque as assinaturas de tipos são úteis. Essa pega um número e retorna uma *string*. E se tivéssemos um array? 203 | 204 | ```js 205 | // sum :: [Number] -> Number 206 | var sum = reduce(add, 0); 207 | ``` 208 | 209 | Essa recebe um array de números e retorna um número (assumindo que aplicamos *curry* na função `reduce` do segundo artigo). 210 | 211 | Alguns exemplos finais: 212 | 213 | ```js 214 | // identity :: a -> a 215 | var identity = function(x) { return x }; 216 | 217 | // map :: (a -> b) -> [a] -> [b] 218 | var map = curry(function(callback, array) { 219 | return array.map(callback); 220 | }); 221 | ``` 222 | 223 | A função `identity` acima recebe um parâmetro de um tipo e retorna uma variável do mesmo tipo. A função `map` por outro lado, recebe uma função que recebe uma variável do tipo *a* e retorna uma variável do tipo *b*. Depois então pega um array de valores, todos do tipo *a* e retorna um array de valores, todos do tipo *b*. 224 | 225 | Você verá que bibliotecas como [Ramda](http://ramdajs.com/), por exemplo, usam essa notação para documentar todas as funções da biblioteca. 226 | 227 | ### Indo Mais Fundo 228 | Nós mal arranhamos a superfície da programação funcional. Mas entendendo funções de primeira classe, aplicação parcial e composição nos dá os blocos básicos para irmos muito mais longe. Se você estiver interessado em ler mais, há uma lista de links úteis abaixo: 229 | 230 | - [Can Your Programming Language do This?](http://www.joelonsoftware.com/items/2006/08/01.html) by Joel Spolsky 231 | - [The Dao of Immutability](https://medium.com/javascript-scene/the-dao-of-immutability-9f91a70c88cd) by Eric Elliot 232 | - [Why Ramda?](http://fr.umio.us/why-ramda/), by Scott Sauyet 233 | - [Professor Frisby’s Mostly Adequate Guide to Functional Programming](https://github.com/MostlyAdequate/mostly-adequate-guide) by Brian Lonsdorf 234 | - [JavaScript Allongé](https://leanpub.com/javascriptallongesix/read) by Reg “raganwald” Braithwaite 235 | -------------------------------------------------------------------------------- /mongodb/001-uma-introducao-ao-mongodb.md: -------------------------------------------------------------------------------- 1 | # Uma introdução ao MongoDB 2 | 3 | * **Artigo Original**: [An Introduction to MongoDB](https://scotch.io/tutorials/an-introduction-to-mongodb) 4 | * **Tradução**: [Felipe Batista](https://github.com/fsbatista) 5 | 6 | O MongoDB se declarou a principal referência em base de dados NoSQL. Com bases em suas estatísticas é dificil argumentar que a tecnologia não é popular. 7 | 8 | MongoDB vem sido usado no prestigiado 'MEAN' stack (referência a utlização das tecnologias de desenvolvimento: MongoDB, Angular, Express e Nodejs). Os benefícios de se utilizar uma base de dados documental como esta significa que é possível trabalhar com documentos (registros) com sintaxe semelhante ao JSON em toda a estrutura de um aplicativo. 9 | 10 | É possível trabalhar com JSON no frontend (Angular), backend (Node) e na base de dados (MongoDB). 11 | 12 | Para sabe mais benefícios de se trabalhar com o MongoDB, visite o site [oficial](http://mongodb.org/). Agora vamos prosseguir e entrar em detalhes de como instalar e user o MongoDB. 13 | 14 | ##Instalando e utilizando o MongoDB 15 | 16 | É possível instalar o MongoDB em seu computador seguindo alguns passos simples: 17 | 18 | 1. Realizar os procedimentos de instalação 19 | 2. Criar um diretório fisico onde a base de dados será armazenada 20 | 21 | Deste modo, de maneira simples, nós podermos usar o MongoDB localmente! 22 | 23 | As instruções a seguir são para Mac, o site oficial possui uma documentação ótima para instalação em [Windows](http://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/) e [Linux](http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/). 24 | 25 | A pasta de trabalho padrão na instalação será /data/db. Será nesta pasta que tudo sera armazenado, por isso você precisa ter certeza que possui permissão para utilizar este diretório para que o MongoDB possa gravar dados nele. 26 | 27 | Nós podemos instalar no Mac manualmente ou usando o Homebrew. Neste artigo iremos focar no Homebrew. 28 | 29 | ```sh 30 | 31 | //Atualize todos os seus packages 32 | 33 | $ brew update 34 | 35 | // Instale o MongoDB 36 | 37 | $ brew install mongodb 38 | 39 | ``` 40 | Se voce preferir não usar o Homebrew, é só seguir as [instruções](http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/#install-mongodb-manually) no site oficial. 41 | 42 | ## Começando a utilizar o MongoDB 43 | 44 | Existem dois passos que devem ser seguidos para se utilizar o MongoDB localmente: 45 | 46 | 47 | 1. Começar o processo (Iniciar o MongoDB) 48 | 2. Conectar 49 | 50 | Parece bem simples, não é? Vamos começar! 51 | 52 | 53 | ### Iniciando uma instância do MongoDB 54 | 55 | Antes de começarmos a criar e salvar registros em nossa base de dados, nós precisamos iniciar uma instância do MongoDB. Não conseguiremos salvar nada se não iniciarmos esta instância (ou serviço). Basta um comando bem simples para inicia-la: 56 | 57 | ```sh 58 | 59 | $ mongod 60 | 61 | ``` 62 | Assim que entrarmos com este comando, o MongoDB irá ser iniciado e você deve ver uma mensagem: 'waiting for connections on port 27017' (Esperando por conexões na porta 27017). 63 | 64 | ![Inicio do MongoDB](https://scotch.io/wp-content/uploads/2014/11/mongo-start.jpg) 65 | 66 | 67 | ### Conectando a uma instância do MongoDB 68 | 69 | Com nossa instância do MongoDB rodando, agora só precisamos nos conectar a ela. Enquanto o comando 'mongod' inicia uma instância do MongoDB, o comando 'mongo' se conecta a ela: 70 | 71 | ```sh 72 | 73 | $ mongo 74 | 75 | ``` 76 | Agora estamos conectados e podemos enviar commandos ao MongoDB. 77 | 78 | ![Inicio do MongoDB](https://scotch.io/wp-content/uploads/2014/11/mongo-connect.jpg) 79 | 80 | Note que no lado direito, estamos conectados ('connecting to test') e no lado esquerdo nossa conexão foi logada ('1 connection new open'). 81 | 82 | ## Comandos de Base de Dados Comuns 83 | 84 | Listar todas as Base de Dados 85 | 86 | ```sh 87 | $ show dbs 88 | 89 | ``` 90 | ### Criando uma base de dados 91 | 92 | O MongoDB não irá criar uma base de dados até que você insira alguma informação na base de dados. 93 | 94 | O truque é que você não precisa se preocupar em criar uma base de dados explicítamente! Você pode simplesmente usar a base de dados (mesmo que não a tenha criado ainda), criar uma coleção e um documento (registro) e tudo será criado automáticamente para você! 95 | 96 | 97 | Iremos analisar a criação de coleções e documentos na seção de comandos para CRUD (Criar, Ler, Atualizar e Deletar). 98 | 99 | 100 | Mostrar a base de dados atual: 101 | ```sh 102 | 103 | $ db 104 | 105 | ``` 106 | Selecionar uma base de dados: 107 | 108 | 109 | ```sh 110 | 111 | $ use db_name 112 | 113 | ``` 114 | 115 | ## Comandos para CRUD (Criar, Ler, Atualizar e Deletar) 116 | 117 | ###Criar 118 | ```sh 119 | 120 | // Salvar um usuário 121 | 122 | $ db.users.save({ name: 'Alberto' }); 123 | 124 | // Salvar vários usuários 125 | 126 | $ db.users.save({ name: 'Alberto'}, { name: 'Maria' }); 127 | 128 | ``` 129 | Ao salvar um documento (registro) na coleção de usuários na base de dados que está sendo utilizada, você criou, com sucesso, tanto a base de dados quanto a coleção (se estas ainda não existiam). 130 | 131 | ###Ler 132 | 133 | ```sh 134 | // Mostrar todos os usuários 135 | 136 | $ db.users.find(); 137 | 138 | // Encontrar um usuário específico 139 | 140 | $ db.users.find({ name: 'Maria' }); 141 | 142 | ``` 143 | ###Atualizar 144 | 145 | ```sh 146 | db.users.update({ name: 'Maria' }, { name: 'Maria da Graça' }); 147 | ``` 148 | ###Deletar 149 | ```sh 150 | // Remover todos 151 | db.users.remove({}); 152 | 153 | // Remover um 154 | db.users.remove({ name: 'Maria' }); 155 | 156 | ``` 157 | Esta é apenas uma visão geral dos tipos de comandos que podem ser feitos. A [documentação](http://docs.mongodb.org/manual/core/crud-introduction/) do MongoDB é bem extensa, o que a torna um ótimo recurso para aqueles que queiram se aprofundar. 158 | 159 | O MongoDB também possui um ótimo [tutorial](http://try.mongodb.org/) interativo para guia-lo na execução dos comandos acima. 160 | 161 | ## Usando MongoDB com Node.js 162 | 163 | Utilizar o MongoDB local com Node é bem simples. Nós utilizaremos o 'mongooseJS', um package do Node para trabalhar com o MongoDB. 164 | 165 | Tudo que você precisa fazer é configurar o mongoose para se conectar a base de dados local. Isso é um processo simples já que nem precisamos de criar a base de dados. Só precisamos nos certificar que a instância do MongoDB foi inicada: 166 | 167 | ```sh 168 | 169 | $ mongod 170 | 171 | ``` 172 | Nós também daremos ao mongoose um nome para nossa base de dados a ser conectada (ela não precisa ser criada antes já que o mongoose irá criá-la para nós). 173 | 174 | Segue uma amostra de código de como criar uma base de dados no Node. 175 | 176 | ```js 177 | 178 | // Requere os packages que precisamos 179 | 180 | var mongoose = require('mongoose'); 181 | 182 | mongoose.connect('mongodb://localhost/nome_base_de_dados'); 183 | 184 | ``` 185 | 186 | É isso! A partir do momento em que começarmos a salvar itens em nossa base de dados, esta será criada com o nome de 'nome_base_de_dados' 187 | 188 | Para mais informações de como usar o Mongoose com o Node, leia: [Using MongooseJS in Node.js and MongoDB Applications](https://scotch.io/bar-talk/using-mongoosejs-in-node-js-and-mongodb-applications) 189 | 190 | 191 | ## Ferramenta GUI: Robomongo 192 | 193 | Mesmo que seja fácil de usar o terminal para acessar nossas base de dados MongoDB, exite também uma GUI para aqueles que gostem deste tipo de interface. 194 | 195 | Faça o download do [Robomongo](http://robomongo.org/) e o inicie. 196 | 197 | Criar uma conexão para nossa base de dados é bem fácil. Basta colocar o endereço como 'localhost' e a porta em 27017. Nomeie sua conexão como quiser. 198 | https://scotch.io/wp-content/uploads/2014/11/robomongo-connect-local.jpg 199 | robomongo-connect-local 200 | ![Robomongo](https://scotch.io/wp-content/uploads/2014/11/robomongo-connect-local.jpg) 201 | 202 | Uma vez que você conectar, terá acesso a todas as bases de dados e suas respectivas coleções! Agora você tem uma GUI para lidar com operações de base de dados. É possível até abrir o terminal (shell) e utilizar os comandos discutidos acima. 203 | 204 | ![Robomongo Terminal](https://scotch.io/wp-content/uploads/2014/11/robomongo-local-db.jpg) 205 | 206 | ## Conclusão 207 | 208 | O MongoDB é uma ótima base de dados NoSQL que pode ser configurada rápidamente e usada em qualquer um dos seus aplicativos. Em aplicativos que usam Node, é possível iniciar e chegar rápidamente a parte mais divertida do desenvolvimento, a construção do aplicativo! 209 | 210 | -------------------------------------------------------------------------------- /nodejs/001-guia-para-iniciantes-absolutos-em-nodejs.md: -------------------------------------------------------------------------------- 1 | # Guia Para Absolutos Iniciantes em Node.js 2 | 3 | ![node-baby](../img/node-absolute-begginer.png) 4 | 5 | * **Artigo Original**: [AN ABSOLUTE BEGINNER'S GUIDE TO NODE.JS](http://blog.modulus.io/absolute-beginners-guide-to-nodejs) 6 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 7 | 8 | > Veja uma versão atualizada desse artigo [aqui](https://github.com/ericdouglas/traduz-ai/blob/master/nodejs/-atualizado-simples-guia-nodejs-jade-express-mongodb.md) 9 | 10 | Não existe uma escassez de tutoriais para Node.js, mas a maioria deles cobrem casos de uso específicos ou tópicos que são aplicáveis só se você já tiver um conhecimento prático do Node. Eu vejo vários comentários que se parecem com coisas do tipo: "Eu fiz o download do node, agora o que fazer?" Este tutorial responde esta questão e explica como iniciar bem do princípio. 11 | 12 | ## O que é Node.js? 13 | 14 | Muitos iniciantes em Node tem a dúvida de o quê exatamente ele é, e a descrição em [nodejs.org](http://nodejs.org/) definitivamente não ajuda. 15 | 16 | Uma coisa importante de se perceber é que o Node não é um servidor web. Por ele próprio, não se tem nada. Ele não funciona como o Apache. Não existe um arquivo de configuração onde você o aponta para seus arquivos html. Se você quer que o Node seja um servidor HTTP, você tem que escrever um servidor HTTP (com a ajuda das bibliotecas incluídas). O Node.js é somente outra forma de executar código em seu computador. Ele é simplesmente um *JavaScript runtime* (ambiente de execução de código JavaScript). 17 | 18 | ## Instalando o Node.js 19 | 20 | Node.js é muito simples de ser instalado. Se você estiver usando Windows ou Mac, os instaladores estão disponíveis na [página de download](http://nodejs.org/download). 21 | 22 | ## Já tenho o Node instalado, e agora o que fazer? 23 | 24 | Uma vez instalado, agora você tem acesso a um novo comando chamado `node`. Você pode usar o comando `node` de duas formas diferentes. A primeira é sem argumentos. Isto irá abrir um shell interativo (REPL: read-eval-print-loop), onde você pode executar código JavaScript puro. 25 | 26 | ```sh 27 | 28 | $ node 29 | > console.log('Hello World'); 30 | Hello World 31 | undefined 32 | 33 | ``` 34 | 35 | No exemplo acima eu digitei `console.log('Hello World')` dentro do shell e apertei enter. O Node vai então executar o código e nós podemos ver nossa mensagem registrada. Ele também imprime `undefined` pelo fato de sempre mostrar o valor de retorno de cada comando, e `console.log` não retorna nada. 36 | 37 | A outra forma de rodar o Node é fornecendo a ele um arquivo JavaScript para execução. Isto será na maioria das vezes a maneira como você irá utilizá-lo. 38 | 39 | `hello.js` 40 | 41 | ```js 42 | 43 | console.log('Hello World'); 44 | 45 | ``` 46 | 47 | ```sh 48 | 49 | $ node hello.js 50 | Hello World 51 | 52 | ``` 53 | 54 | Neste exemplo, eu movi o comando `console.log()` para dentro de um arquivo e então passei este arquivo para o comando node como um argumento. O Node então roda o JavaScript contido neste arquivo e imprime "Hello World". 55 | 56 | ## Fazendo Algo Útil 57 | 58 | Rodar código JavaScript é divertido e tal, mas não é muito útil. Ai é onde o Node.js também inclui um poderoso conjunto de [bibliotecas](http://nodejs.org/api/) (módulos) para se fazer coisas reais. No primeiro exemplo eu vou abrir um arquivo de registros e analisá-lo. 59 | 60 | `example-log.txt` 61 | ``` 62 | 63 | 2013-08-09T13:50:33.166Z A 2 64 | 2013-08-09T13:51:33.166Z B 1 65 | 2013-08-09T13:52:33.166Z C 6 66 | 2013-08-09T13:53:33.166Z B 8 67 | 2013-08-09T13:54:33.166Z B 5 68 | 69 | ``` 70 | 71 | O que esses dados registrados significam não importa, mas basicamente cada mensagem contém uma data, uma letra e um valor. Eu quero somar os valores para cada letra. 72 | 73 | A primeira coisa que nós precisamos fazer é ler o conteúdo do arquivo. 74 | 75 | `my-parser.js` 76 | ```js 77 | 78 | // Carregando o módulo fs (filesystem) 79 | var fs = require('fs'); 80 | 81 | // Leia o conteúdo do arquivo para a memória 82 | fs.readFile('example-log.txt', function ( err, logData ) { 83 | 84 | // Se um erro ocorrer, será lançada uma 85 | // exceção, e a aplicação irá ser encerrada 86 | if ( err ) throw err; 87 | 88 | // logData é um Buffer, converta-o para string 89 | var text = logData.toString(); 90 | }); 91 | 92 | ``` 93 | 94 | Felizmente o Node.js faz a entrada e saída (I/O) do arquivo facilmente com o módulo embutido [filesystem](http://nodejs.org/api/fs.html) (`fs`). O módulo `fs` tem uma função chamada [readFile](http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback) que pega o caminho de um arquivo e um callback. O callback vai ser invocado quando o arquivo for lido por completo. O dado do arquivo vem na forma de um [Buffer](http://nodejs.org/api/buffer.html), que é basicamente um array de bytes. Nós podemos convertê-lo para uma string usando a função [`toString()`](http://nodejs.org/api/buffer.html#buffer_buf_tostring_encoding_start_end). 95 | 96 | Agora vamos adicionar o *parsing* (analisador). 97 | 98 | `my-parser.js` 99 | ```js 100 | 101 | // Carregando o módulo fs (filesystem) 102 | var fs = require('fs'); 103 | 104 | // Leia o conteúdo do arquivo para a memória 105 | fs.readFile('example-log.txt', function ( err, logData ) { 106 | 107 | // Se um erro ocorrer, será lançada uma 108 | // exceção, e a aplicação irá ser encerrada 109 | if ( err ) throw err; 110 | 111 | // logData é um Buffer, converta para string 112 | var text = logData.toString(); 113 | 114 | var results = {}; 115 | 116 | // Quebrando o arquivo em linhas 117 | var lines = text.split( '\n' ); 118 | 119 | lines.forEach(function ( line ) { 120 | var parts = line.split( ' ' ); 121 | var letter = parts[ 1 ]; 122 | var count = parseInt( parts[ 2 ] ); 123 | 124 | if ( !results[ letter ] ) { 125 | results[ letter ] = 0; 126 | } 127 | 128 | results[ letter ] += parseInt( count ); 129 | }); 130 | 131 | console.log( results ); 132 | // { A: 2, B: 14, C: 6 } 133 | }); 134 | 135 | ``` 136 | 137 | Agora vamos passar este arquivo como um argumento para o comando `node` e ele vai imprimir o resultado e sair. 138 | 139 | ```sh 140 | 141 | $ node my-parser.js 142 | { A: 2, B: 14, C: 6 } 143 | 144 | ``` 145 | 146 | Eu uso muito o Node.js para scripts como este. É uma alternativa muito mais simples e poderosa que os scripts bash. 147 | 148 | ## Callbacks Assíncronos 149 | 150 | Como você viu no exemplo anterior, o padrão típico do Node.js é o uso de callbacks assíncronos. Basicamente você está dizendo a ele para fazer algo e quando isso estiver terminado ele irá chamar sua função (callback). Isto porque o Node é de *thread* única. Enquanto você está esperando pelo disparo do callback, o Node pode fazer outras coisas ao invés de bloquear até que a requisição esteja terminada. 151 | 152 | Isso é especialmente importante para servidores web. Isto é muito comum em aplicações web modernas para acessar banco de dados. Enquanto você espera pelo retorno do banco de dados, o Node pode processar mais requisições. Isso permite que você manipule milhares de conexões conjuntas com pequenos acréscimos, comparado a criar uma thread separada para cada conexão. 153 | 154 | ## Fazendo Algo Útil - Servidor HTTP 155 | 156 | Como disse anteriormente, o Node não faz nada por si só. Um dos módulos embutidos tornam a criação de [servidores HTTP](http://nodejs.org/api/http.html#http_http_createserver_requestlistener) simples muito fácil, que é o [exemplo na página inicial do Node.js](http://nodejs.org/). 157 | 158 | `my-web-server.js` 159 | ```js 160 | 161 | var http = require('http'); 162 | 163 | http.createServer(function ( req, res ) { // req = requisição, res = resposta 164 | 165 | res.writeHead( 200, { 'Content-Type': 'text/plain' } ); 166 | res.end( 'Hello World\n' ); 167 | }).listen( 8080 ); 168 | 169 | console.log( 'Servidor rodando na porta 8080' ); 170 | 171 | ``` 172 | 173 | Quando eu digo básico, quero dizer básico mesmo. Este não é um servidor HTTP completo. Ele não pode servir qualquer arquivo HTML ou de imagem. De fato, não importa sua requisição, ela vai retornar 'Hello World'. No entanto, você pode rodar isto e verá em seu navegador no endereço `http://localhost:8080` o texto "Hello World". 174 | 175 | ```sh 176 | 177 | $ node my-web-server.js 178 | 179 | ``` 180 | 181 | Você pode ter percebido uma coisa diferente agora. Sua aplicação node.js não fechou. Isto acontece pois você criou um servidor e sua aplicação node vai continuar rodando e respondendo as requisições até que você mesmo mate o processo. 182 | 183 | Se você quiser ter um servidor web completo, você terá que fazer este trabalho. Você deve checar o que foi requisitado, ler os arquivos apropriados e enviar o conteúdo de volta. Pessoas já fizeram este trabalho duro para você. 184 | 185 | ## Fazendo Algo Útil - Express 186 | 187 | [Express](http://expressjs.com/) é um framework que torna a criação de sites normais muito simples. A primeira coisa que você tem que fazer é instalá-lo. Juntamente com o comando `node`, você também tem acesso a um comando chamado `npm`. Esta ferramenta permite que você acesse uma enorme coleção de módulos criados pela comunidade, e um deles é o Express. 188 | 189 | ```sh 190 | 191 | $ cd /my/app/location 192 | $ npm install express 193 | 194 | ``` 195 | 196 | Quando você instala um módulo, ele vai ser colado em uma pasta chamada *node_modules* dentro do diretório da sua aplicação. Você pode agora requisitar (*require*) este módulo como um módulo embutido. Vamos criar um arquivo estático básico usando o Express. 197 | 198 | `my-static-file-server.js` 199 | ```js 200 | 201 | var express = require('express'); 202 | app = express(); 203 | 204 | app.use(express.static(__dirname + '/public')); 205 | 206 | app.listen(8080); 207 | 208 | ``` 209 | ```sh 210 | 211 | $ node my-static-file-server.js 212 | 213 | ``` 214 | 215 | Agora você tem um servidor de arquivos estáticos bastante eficiente. Tudo que você colocar dentro da pasta `/public` poderá ser requisitado pelo seu navegador e será mostrado. HTML, imagens, enfim, tudo. Por exemplo, se você colocar uma imagem chamada `my-image.png` dentro da pasta `public`, você pode acessá-la usando seu navegador no endereço `http://localhost:8080/my-image.png`. Claro que o Express tem vários outros recursos, mas você pode olhá-los a medida que continua desenvolvendo. 216 | 217 | ## NPM 218 | 219 | Nós usamos um pouco o [NPM](https://npmjs.org/) nas seções anteriores, mas eu quero enfatizar o quão importante esta ferramenta se faz no desenvolvimento para Node.js. Existem milhares de módulos disponíveis que resolvem quase todos os problemas típicos que você encontra. Lembre-se de checar o NPM antes de re-inventar a roda. Não é inédito para uma aplicação Node ter dezenas de dependências. 220 | 221 | No exemplo anterior nós instalamos o Express manualmente. Se você tiver muitas dependências, essa não será uma forma muito interessante de instalá-las. É por isso que o NPM faz uso do arquivo `package.json`. 222 | 223 | `package.json`. 224 | ```js 225 | 226 | { 227 | "name" : "MyStaticServer", 228 | "version" : "0.0.1", 229 | "dependencies" : { 230 | "express" : "3.3.x" 231 | } 232 | } 233 | 234 | ``` 235 | 236 | Um arquivo [`package.json`](https://npmjs.org/doc/files/package.json.html) contém um resumo da sua aplicação. Existem vários campos disponíveis, sendo este apenas o mínimo. A seção *dependencies* (dependências) descreve o nome e a versão dos módulos que você gostaria de instalar. Neste caso eu vou aceitar qualquer versão do Express 3.3. Você pode listar quantas dependências quiser nesta seção. 237 | 238 | Agora, ao invés de instalar cada dependência em separado, nós podemos rodar um simples comando e instalar todas elas. 239 | 240 | ```sh 241 | 242 | $ npm install 243 | 244 | ``` 245 | 246 | Quando você roda este comando, o npm vai verificar na pasta atual pelo arquivo `package.json`. Se ele encontrar um, então irá instalar cada dependência listada. 247 | 248 | ## Organização do Código 249 | 250 | Até agora só usamos um único arquivo, que não é muito sustentável. Na maioria das aplicações, seu código vai ser dividido em vários arquivos. Não existe nenhuma norma ou organização imposta dizendo para onde os arquivos vão. Isto não é Rails. Não há conceitos de views e controllers acontecendo aqui. Você pode fazer o que quiser. 251 | 252 | Vamos refatorar o script de análise de registros (log parsing). Ele será muito mais testável e manutenível se nós separarmos a lógica de análise (parsing) dentro de um arquivo próprio. 253 | 254 | `parser.js` 255 | ```js 256 | 257 | // Construtor Parser 258 | var Parser = function () { 259 | 260 | }; 261 | 262 | // Analisa o texto especificado 263 | Parser.prototype.parse = function ( text ) { 264 | 265 | var results = {}; 266 | 267 | // Quebra o arquivo em linhas 268 | var lines = text.split('\n'); 269 | 270 | lines.forEach(function ( line ) { 271 | var parts = line.split( ' ' ); 272 | var letter = parts[ 1 ]; 273 | var count = parseInt( parts[2] ); 274 | 275 | if ( !results[ letter ] ) { 276 | results[ letter ] = 0; 277 | } 278 | 279 | results[ letter ] += parseInt( count ); 280 | }); 281 | 282 | return results; 283 | }; 284 | 285 | // Exportando o construtor Parser neste módulo 286 | module.exports = Parser; 287 | 288 | ``` 289 | 290 | O que eu fiz foi criar um novo arquivo para conter a lógica da análise dos registros. Isto é apenas JavaScript puro e existe várias formas de se encapsular este código. Eu escolhi por definir um novo objeto JavaScript pois assim é mais fácil de se fazer testes unitários. 291 | 292 | A parte importante para isso é a linha `module.exports`. Isso diz ao Node que você está exportando deste arquivo. Neste caso exportei um construtor, então os usuários podem criar instâncias do meu objeto `Parser`. Você pode exportar qualquer coisa que quiser. 293 | 294 | Agora vamos ver como importar este arquivo e fazer uso do novo objeto `Parser`. 295 | 296 | `my-parser.js` 297 | ```js 298 | 299 | // Requisitando o arquivo parser.js 300 | var Parser = require('./parser'); 301 | 302 | // Carregandoo módulo fs (filesystem) 303 | var fs = require('fs'); 304 | 305 | // Lendo o conteúdo do arquivo para a memória 306 | fs.readFile('example-log.txt', function ( err, logData ) { 307 | 308 | // Se um erro ocorrer, irá ser lançada 309 | // a exceção e a app será encerrada 310 | if ( err ) throw err; 311 | 312 | // logData é um Buffer, converta-o para string 313 | var text = logData.toString(); 314 | 315 | // Criando uma instância do objeto Parser 316 | var parser = new Parser(); 317 | 318 | // Chame a função parse 319 | console.log( parser.parse( text ) ); 320 | // { A: 2, B: 14, C: 6 } 321 | }); 322 | 323 | ``` 324 | 325 | Arquivos são incluídos da mesma forma que os módulos, exceto que você inclui um caminho ao invés de um nome. A extensão `.js` é implícita, então você pode omití-la se quiser. 326 | 327 | Tendo sido exportado um construtor, é isso que vai ser retornado da declaração `require`. Eu posso agora criar instâncias do meu objeto `Parser` e usá-las. 328 | 329 | ## Resumo 330 | 331 | Esperamos que este tutorial tenha feito a ponte entre a parte de fazer o download do Node.js e construir sua primeira ferramenta. O Node.js é uma tecnologia extremamenta poderosa e flexível que pode resolver uma vastidão de tipos de problemas. 332 | 333 | Eu quero que cada um de vocês se lembre que o Node.js é somente limitado pela sua imaginação. As bibliotecas de seu núcleo foram cuidadosamente projetadas para fornecer as peças do quebra-cabeça necessárias para se construir qualquer fotografia. Combine-as com módulos disponíveis no NPM e será incrível o quão rápido você poderá começar a construir aplicações muito complexas e atraentes. 334 | -------------------------------------------------------------------------------- /programacao-funcional/beleza-da-programacao-funcional.md: -------------------------------------------------------------------------------- 1 | # A Beleza da Recursão e Pattern Matching (Casamento de Padrões) em Linguagens de Programação Funcionais 2 | 3 | ![Função lookup para retornar valor de uma árvore binária](https://i.imgur.com/lFXKbhd.png) 4 | 5 | * **Artigo original**: [The beauty of recursion and pattern matching in functional programming languages](https://dev.to/ericdouglas/the-beauty-of-recursion-and-pattern-matching-in-functional-programming-languages-hmn) 6 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 7 | 8 | ```erl 9 | %% Função lookup recebe uma Key e um Node 10 | lookup(_, {node, 'nil'}) -> 11 | undefined; 12 | lookup(Key, {node, {Key, Val, _, _}}) -> 13 | {ok, Val}; 14 | lookup(Key, {node, {NodeKey, _, Smaller, _}}) when Key < NodeKey -> 15 | lookup(Key, Smaller); 16 | lookup(Key, {node, {_, _, _, Larger}}) -> 17 | lookup(Key, Larger). 18 | 19 | %% Explicação sobre parâmetros e estrutura de dados 20 | %% 21 | %% Nó vazio -> {node, 'nil'} 22 | %% Nó não vazio -> {node, {Key, Val, Smaller, Larger}} 23 | %% node -> é apenas um atom, como uma constante 24 | %% Key e Val -> podem ser de tipos diferentes 25 | %% Smaller e Larger -> Pode ser estruturas de nós vazios ou não vazios, 26 | %% então você pode ter sua árvore binária 27 | ``` 28 | 29 | Gostaria de te convidar para admirar a beleza, concisão e poder do código acima [1]. 30 | 31 | É uma função que encontra um valor em uma árvore binária, usando _recursão_ e _pattern matching_ ([casamento de padrões](https://pt.wikipedia.org/wiki/Casamento_de_padr%C3%B5es)). 32 | 33 | Podemos ver quão simples e extremamente declarativo é escrever uma função com esses conceitos e técnicas oriundas de linguagens de programação funcional. 34 | 35 | **Temos absolutamente ZERO instruções dizendo COMO o algoritmo deve trabalhar!** Nós apenas expressamos **O QUÊ** ele deve fazer, não como. 36 | 37 | O código foi escrito em **Erlang**. 38 | 39 | ## Explicação detalhada 40 | 41 | Essa função vai buscar em uma árvore binária pela chave `Key` passada para ela, e vai retornar uma tupla com o valor `Val` (valor) associado com a chave passada, ou `undefined` se a chave não for encontrada. 42 | 43 | Uma grande vantagem que temos no Erlang e Elixir é a possibilidade de criar mais casos para a mesma função apenas mudando o padrão em seus parâmetros. 44 | 45 | A função tem o mesmo nome e aridade (número de parâmetros), mas como o padrão é diferente, é como se fosse uma outra função. 46 | 47 | Os casos vão ser verificados de cima pra baixo, então devemos colocar os casos específicos primeiro, e casos gerais no fim. Pense nisso como uma forma funcional de escrever declarações `switch` ou `if / else`. 48 | 49 | Nós temos quatro casos possíveis em nossa função `lookup/2`, então vamos ver o que cada um faz: 50 | 51 | ### `lookup(_, {node, 'nil'})` 52 | 53 | O primeiro `lookup` vai ignorar o primeiro valor passado para ele (`_`), e se o segundo valor casar, ele vai retornar `undefined`. Como você pode ver, o segundo valor é um nó vazio. 54 | 55 | ### `lookup(Key, {node, {Key, Val, _, _}})` 56 | 57 | O segundo `lookup` vai ver se a chave `Key` que passamos é a mesma `Key` do nó passado. Se for, nós acabamos de encontrar o nó que contém o valor que queremos retornar. 58 | 59 | Nesse caso, `lookup` retorna `{ok, Val}`, onde `Val` é o valor que estávamos interessados. 60 | 61 | ### `lookup(Key, {node, {NodeKey, _, Smaller, _}}) when Key < NodeKey` 62 | 63 | O terceiro `lookup` vai identificar com o caso onde a chave que passamos é diferente da chave do nó passado. 64 | 65 | Também temos uma _cláusula de guarda_ na assinatura da função, para deixá-la mais específica. A cláusula de guarda `when Key < NodeKey` é importante para decidirmos em que direção devemos ir para buscar o valor que esperamos. 66 | 67 | Nesse caso, sabemos que se a chave `Key` é menor que `NodeKey`, nós precisamos continuar nossa busca no nó `Smaller`. Então usamos _pattern match_ (casamento de padrão) para extrair o valor `Smaller` (menor) e ignorar o resto dos dados que não vamos usar com `_` novamente. 68 | 69 | Para continuar nossa busca, quando nós paramos na terceira função `lookup`, nós vamos chamá-la recursivamente, agora com os seguintes dados `lookup(Key, Smaller)`. 70 | 71 | _Isso é **recursão** e **casamento de padrões** em ação! ❤_ 72 | 73 | ### `lookup(Key, {node, {_, _, _, Larger}})` 74 | 75 | No último caso, e o mais geral, é quando todas as prévias funções `lookup` não foram "casadas". Nós sabemos que isso só vai acontecer quando a chave `Key` passada é diferente da `Key` do nó atual, e a `Key` passada é maior que a chave no nó atual, então temos que continuar a buscar no nó maior `Larger`. 76 | 77 | Nesse caso, vamos chamar `lookup` recursivamente com os seguintes dados `lookup(Key, Larger)`. 78 | 79 | **E é isso!** 80 | 81 | Com ZERO instruções sobre COMO fazer, nós temos uma função super simples, declarativa e completa, que retorna um valor de uma árvore binária! Isso é absolutamente incrível e surpreendente <3. 82 | 83 | Espero que tenha gostado! 84 | 85 | Abraço! :) 86 | 87 | ## Referências 88 | 89 | 1. Código extraído do capítulo 7 - Recursão, seção "Mais que listas", do livro _Learn You Some Erlang for Great Good_. **[LINK](https://learnyousomeerlang.com/recursion)** 90 | -------------------------------------------------------------------------------- /react/01-sua-linha-do-tempo-para-aprender-react.md: -------------------------------------------------------------------------------- 1 | # Sua Linha do Tempo para Aprender React 2 | 3 | * **Artigo original**: [Your Timeline for Learning React](https://daveceddia.com/timeline-for-learning-react/) 4 | * **Tradução**: [Eric Douglas](https://github.com/ericdouglas) 5 | 6 | Esta é sua linha do tempo para aprender React. 7 | 8 | Pense nestes passos como camadas em uma fundação. 9 | 10 | Se você estivesse construindo uma casa, você pularia alguns passos para ter a casa concluída mais rapidamente? Talvez pular direto para o concreto antes de colocar algumas pedras no lugar? Você construiria as paredes no chão puro? 11 | 12 | Ou sobre fazer um bolo de casamento: a parte de cima parece a mais legal de decorar, então por que não começar por ai? Vamos pensar sobre a parte de baixo depois. 13 | 14 | Não? 15 | 16 | Claro que não. Você sabe que tais coisas o levariam ao fracasso. 17 | 18 | Então por que você abordaria React tentando aprender ES6 + Webpack + Babel + React + Redux + Routing + AJAX *tudo de uma vez*? Isso não soa como se você estivesse se levando para o fracasso? 19 | 20 | Um pé na frente do outro. Reserve um pouco de tempo a cada dia, isso é provavelmente algo para algumas semanas de aprendizado. 21 | 22 | O tema deste artigo é: evite ficar sobrecarregado. Lento e constante, assim se aprende React. 23 | 24 | ## Passo 0: JavaScript 25 | 26 | Assumo que você já sabe JavaScript, pelo menos ES5. Se você ainda não sabe JS, pare o que está fazendo, aprenda o [básico](https://developer.mozilla.org/pt-BR/docs/Aprender/Getting_started_with_the_web/JavaScript_basico), e *só depois* continue em frente. 27 | 28 | Se você já conhece ES6, vá em frente e use-o. Só para você saber, a API do React tem algumas diferenças entre ES5 e ES6. É útil saber ambos os "sabores" - quando algo dá errado, você vai encontrar uma ampla gama de respostas úteis se você conseguir traduzir mentalmente entre ambos os estilos. 29 | 30 | ## Passo 0.5: npm 31 | 32 | npm é o gerenciador de pacotes dominante no mundo JavaScript. Não há muita coisa para se aprender aqui. Depois de [instalá-lo junto com Node.js](https://nodejs.org/en/), tudo que você realmente precisa saber é como instalar pacotes (`npm install `). 33 | 34 | ## Passo 1: React 35 | 36 | Comece com o [Olá Mundo](https://daveceddia.com/test-drive-react). Use um arquivo HTML em branco com algumas tags `