Uma biblioteca funcional prática para desenvolvedores JavaScript
Já existem várias bibliotecas funcionais excelentes, tipicamente, elas são supostamente feitas para ser um conjunto de ferramentas de general-purpose(propósitos gerais), adequadas para funcionarem em múltiplos paradigmas. Ramda tem um foco mais específico, nós queremos uma biblioteca projetada especificamente para o paradigma funcional, uma que deixa fácil criar pipelines funcionais, uma que nunca deixe os dados dos usuários mutáveis.
As características primárias que distinguem Ramda são:
-
Ramda enfatiza um estilo funcional puro. A ausência de Imutabilidade e side-effect(efeitos colaterais) são o coração da filosofia do design. Isso pode ajudá-lo a fazer o seu trabalho com um código simples e elegante.
-
As funções em Ramda são automaticamente curried(que é basicamente uma maneira de informar para a função os parâmetros de forma parcial, você pode injetar os parâmetros a medida que os mesmo ficarem disponíveis). Isso permite a você escrever novas funções a partir das antigas sem a necessidade de fornecer parâmetros finais.
-
Os parâmetros para funções em Ramda são predispostos para fazê-los serem convenientes para o currying. Os dados a serem trabalhados geralmente são fornecidos por último.
Os dois últimos pontos juntos deixam muito fácil criar funções como sequencias de funções mais simples, Cada um deles transforma os dados e passa ao próximo. Ramda é projetada para suportar esse estilo de código.
Introdução
- Introducing Ramda por Buzz de Cafe
- Why Ramda? por Scott Sauyet
- Favoring Curry por Scott Sauyet
- Why Curry Helps por Hugh Jackson
- Hey Underscore, You're Doing It Wrong! por Brian Lonsdorf
- Thinking in Ramda por Randy Coulman
Usar Ramda deveria ser como usar Javascript. É práticamente, Javascript funcional. Não iremos apresentar expressões lambdas em Strings, não estamos pegando emprestadas consed lists, não estamos portando Clojures.
Nossas estruturas de dados báscias são objetos Javascript puros, a nossas colletions são arrays. Nós também mantemos outras features de Javascript, tais como funções como objetos com propriedades.
Programação funcional é boa parte sobre objetos imutáveis e funções livres de side-effects. Enquanto Ramda não impõe isso, te permite tal estilo sem o menor atrito possível.
Nós buscamos uma implementação tanto quanto elegante e limpa, mas a peça chave é a API. Nós sacrificamos uma grande parte da elegância da implementação por uma API um pouco mais limpa.
Por último mas não menos importante, Ramda tem grande empenho em performance. Uma implementação confiável e rápida supera qualquer noção de pureza funcional.
Para usar com node:
$ npm install ramda
Então no console:
const R = require('ramda');
Para usar diretamente no browser:
<script src="path/to/yourCopyOf/ramda.js"></script>
Ou a versão minificada:
<script src="path/to/yourCopyOf/ramda.min.js"></script>
or através do CDN ou cdnjs:
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
Ou um dos links abaixo através de jsDelivr:
<script src="//cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/ramda@0.25/dist/ramda.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/ramda@latest/dist/ramda.min.js"></script>
(Note que usando latest
é levar em risco que a as mudanças da API ramda podem trazer breaking changes.)
Essas tags adicionam a variável R
no scopo global do navegador.
Or você pode injetar ramda em praticamente qualquer website utilizando the bookmarklet.
Notas para as versões > 0.25
As versões de Ramda acima de 0.25 não tem default export.
Então ao invés de usar import R from 'ramda';
, terá que usar import * as R from 'ramda';
Or melhor ainda, importe apenas as funções necessárias através de import { functionName } from 'ramda';
npm run build
cria os diretórios es
, src
e atualiza dist/ramda.js e dist/ramda.min.js
É possível buildar Ramda como um subset da funcionalidade para reduzir o seu tamanho. O sistema de build de Ramda tem suporte para flags de linha de comando.
Por exemplo, se você está usando R.compose
, R.reduce
e R.filter
você pode criar builds parciais com:
npm run --silent partial-build compose reduce filter > dist/ramda.custom.js
Para isso é necessário ter Node/io.js instalado e as dependências de Ramda (apenas use npm install
antes de rodar sua build parcial)
Por favor, revise: API documentation.
Também disponível em nosso Cookbook de built functions de Ramda que você pode achar útil.
Ok, então nos gostamos de carneiros. Isso é tudo. É um nome curto e que ainda não tinha sido utilizado.
Poderia facilmente ser aweda
, mas nos seríamos forçados a dizer eweda lamb!, e ninguém quer isso.
Para pessoas que não falam nativamente inglês, lambs são filhotes de carneiros, ewes são carneiros fêmeas e rams carneiros.
Então talvez Ramda é uma lambda crescida... provavelmente não.
(Ficou um pouco estranho, já que em português os nomes são diferentes carneiros
e ovelhas
, por isso essa parte ficou com os nomes em inglês).
Console:
Para rodar a suite de testes a partir do console, você precisar ter o mocha
instalado:
npm install -g mocha
Então a partir da raíz do projeto você precisa apenas rodar
mocha
Ou se você instalou as depedências pode ser através do:
npm install
então você poderá rodar os testes (e ver os output detalhado) rodando:
npm test
Browser:
Você pode usar
Browser: testem para testar para diferentes browsers (ou mesmo de forma headlessly), com livereloading dos testes. instale testem (npm install -g testem
) e rode testem
. Abra o link fornecido no seu browser e você verá
os resultados no seu terminal.
Se você tiver PhantomJS instalado, você poderá rodar testem -l phantomjs
para rodar os testes de forma completamente headlessly
Para as versões acima de v0.25
, importar a biblioteca inteira ou pegar os modules diretamente da biblioteca:
import * as R from 'ramda'
const {identity} = R
R.map(identity, [1, 2, 3])
A desestruturação dos imports do Ramda não necessariamente impede a importação de toda a biblioteca. Você pode manualmente fazer um cherry-pick dos métodos como a seguir, irá apenas pegar as partes necessárias para identity
funcionar:
import identity from 'ramda/src/identity'
identity()
Fazer cherry-pick dos métodos é um pouco maçante, entretanto. A maioria dos bundlers como Webpack e Rollup oferecem tree-shaking como uma maneira de remover códigos não usados e diminuir o tamanho do bundle, mas a performance varia, discutido Aqui. Aqui está um sumário da configuração ideal de acordo com a tecnologia que você está usando:
- Webpack + Babel - use
babel-plugin-ramda
to automatically cherry pick methods. Discussion here, example here - Webpack only - use
UglifyJS
plugin for treeshaking along with theModuleConcatenationPlugin
. Discussion here, with an example setup here - Rollup - does a fine job properly treeshaking, no special work needed; example here
Thanks to J. C. Phillipps for the Ramda logo. Ramda logo artwork © 2014 J. C. Phillipps. Licensed Creative Commons CC BY-NC-SA 3.0.