Programación funcional en JavaScript: The Arity and TUPLS

x

Privacidade e cookies

Este sitio usa cookies. Continuando, acepta o seu uso. Obteña máis información; Por exemplo, sobre como controlar as cookies.

Comprender

14787298814_2ed9b48a0_k.jpg

volvemos á serie de correos dedicada á programación funcional en JavaScript. Tivemos explicado a importancia do uso de métodos encadeados para obter un código máis expresivo.

Na publicación de hoxe falaremos das desvantaxes que nos traen o uso de métodos encadeados. Aprenderemos unha nova forma de modular o noso código e levar moito máis parte á reutilización do código a través do concepto de tubos que se poden usar na programación funcional.

explicaremos cales son os tubos Características Necesitamos que cumpran as funcións para poder lograr esa sensación de código que flúe mediante unha pipa conectada. Explicaremos o que é a ariedade e como os toques ou o currículo poden axudarnos a xestionar a complexidade dos altos arresses.

Como sempre, tenme á súa disposición nos comentarios no caso de que poida resolver calquera das súas dúbidas .. Empecemos:

O problema dos métodos encadeados

Os métodos encadeados axúdanos moito a escribir un código mellor. Poderiamos velo no capítulo anterior. Que non cambia. Non obstante, atopamos un gran problema para os métodos encadenados.

Se recordamos, por exemplo, o método de “filtro” de ES5, o método devolve un novo obxecto de matriz que contén de novo os métodos. De aí a maxia de poder concatenar. Desafortunadamente, o patrón é unha arma de dobre filo xa que os métodos están tan acordados ao tipo de obxecto que nos confina dános moi pouca flexibilidade de reutilización.

con métodos concatenados que estamos obrigados a usar só o conxunto de operacións que proporcionan o propio obxecto. Sería ideal que puidésemos romper esta cadea e dentro da asemblea poderiamos organizar funcións no noso desexo. Os métodos encadeados non son a solución, polo que teremos que buscarnos outra alternativa.

Os tubos

e a alternativa vén en forma de pipa. Se cos métodos encadeados perdemos a expresividade e gañamos demasiado acoplamento, coa organización de funcións nunha pipa que poderiamos ter o contrario.

A clave para organizar funcións en canalizacións é a de poder ter un O arsenal de funcións desacoplado que pode ser executado de xeito secuencial. Como nun tubo, as nosas funcións pasarían os estados dunha función a outra. Os parámetros de saída dunha función supoñerán os parámetros de entrada do seguinte.

Deste xeito, podo crear pezas de código moi independentes, que cumpren cunha función específica e que por composición das súas entradas e as súas saídas pode crear un programa importante.

Se usamos a notación usada en Haskell, podemos mellor explicar isto. Podemos definir as funcións deste xeito:

<nombre_funcion> :: <entradas> -> <salidas>

Ao final é moi similar á definición de lambdas, só neste caso, estamos máis interesados en saber que Os tipos de datos entran e deixan unha función. É a especificación dunha caixa negra.

Vin isto, vexamos un exemplo. Podo compoñer por medio de canalizacións as seguintes funcións:

f :: A -> Bg :: B -> C

onde f e g son o nome dunha función e A, B e C son diferentes tipos. Neste caso, como a saída de F coincide co tipo de B. Eu podería executalos coma se fose unha pipa:

g(f(A)); // donde se devuelve C

Isto a primeira vista parece Obviamente, pode axudarnos moito. Non será fácil conseguir isto en ambientes máis complexos xa que haberá funcións que devolven obxectos que non se poden reutilizar.

Con todo, é algo que temos que ter en conta ao deseñar funcións. É importante ver que necesitamos facer funcións compatibles entre si. A conciencia diso no proceso de deseño, é importante que consideremos dous factores: a compatibilidade dos tipos de entradas e saídas ea aridación das funcións.

Compatibilidade tipo

como Dicamos, a compatibilidade tipo refírese aos tipos de saída de función relacionándose cos tipos de parámetros de entrada doutro. Non é un problema que temos que preocuparnos moito en JavaScript porque ao final cando se atopa con linguaxe débilmente típica, podemos ter moita máis flexibilidade.

Ao final isto é o que normalmente se denomina “Tipos de pato”, non estou interesado en tubos de JavaScript tanto que os tipos son idénticos e que o obxecto que devolve unha función, compórtase como o tipo de O parámetro de entrada á espera da miña próxima función. É dicir, se vai como pato e grazna como un pato, é un pato. Se un obxecto se comporta un tipo específico e ten os atributos que espero neste tipo, para min é ese tipo. É o bo e o malo de JavaScript.

Se queremos facer que as nosas funcións sexan estrictamente compatibles, unha boa idea sería usar o tipo de tipo de complemento. Deixo o chat de Micael galego de novo aquí no caso de que estea interesado nesta alternativa.

Polo tanto, cando deseñamos funcións, temos que ter moi claro os mozos cos que xogan as nosas funcións. Imaxina que queremos facer un sistema que teña un número de identidade, eliminamos os espazos e os scripts para traballar mellor con el. Deseñaremos dúas funcións como estas:

trim :: String -> Stringnormalize :: String -> String

Creamos dúas funcións compatibles para a composición desde a entrada dun partido o tipo do outro. Eles tamén son conmutativa, porque se eu executar TRIM e despois normalizar, eu conseguir o mesmo resultado como se eu executar primeiro ‘normalizar’ e despois ‘tapaxuntas’. Vexamos a implementación.

Vale, o exemplo é moi parvo, pero é importante que nos coñecemos no futuro. Teremos máis problemas en JavaScript co número de parámetros que poden permitir unha función.

A ariedade e as tuplas

Sabemos por Arity no número de parámetros de entrada que aceptan unha función .. É común indicar-lo como unha lonxitude dunha función.

A ar ou unha función pode facer unha función gaña en complexidade. Que unha función acepta varios parámetros fai que todos os argumentos sexan calculados primeiro, isto fainos perder versatilidade.

Ademais, pode ser o caso de que a complexidade interna dunha función sexa maior (que é unha gran ariedade Non sempre se comporta unha maior complexidade, pode simplemente ser un síntoma de TI).

Tras ter erradas elevadas ademais, fainos ter menos funcións flexibles. As funcións con parámetro (ou unies) adoitan ser máis flexibles porque, en xeral, só teñen unha única responsabilidade, realizan algún tipo de operación ou calcule no parámetro de entrada e devolver o resultado.

Por desgraza, Na vida real é complicado para satisfacer só unies. Non obstante, podemos facer que unha función devolva unha tupla, deste xeito a seguinte función sería unarrión e xa tería todo o estado que necesita.

A tupla é unha lista de valores finita e ordenada Que están representados do seguinte xeito (A, B, C). As tuplas son un paquete de valores inmutables, que teñen unha relación e que se pode empregar para devolver varios valores a outras funcións.

Podemos simular este comportamento cun obxecto JSON ou con obxectos de matriz, axiña Como vemos, entón, coas tuplas temos máis vantaxes:

  • son inmutables.
  • Evite a creación de novos tipos. Moitas veces para crear clases para un único uso específico pode ser bastante barato para o desarrollador.
  • Evite crear matrices heteroxéneas: traballar con estas matrices heteroxéneas supón unha morea de desenvolvemento de cheques de tipo. As matrices son mellor simplemente usalas cando se traballa con coleccións de obxectos co mesmo tipo.

O problema que temos é que aínda que o tupes é un elemento na maioría das linguaxes de programación funcional como Scala, en JavaScript Non hai nada que admita as tuplas. A mellor opción para iso é que cremos que unha pequena librería que soporta as tuplas. A opción que a atención de Luís propón no seu libro é:

const Tuple = function () { const typeInfo = Array.prototype.slice.call(arguments, 0); const _T = function () { const values = Array.prototype.slice.call(arguments, 0); if (values.some((val) => val === null || val === undefined) { throw new ReferenceError('Tuples may not have any null values'); } if (values.length !== typeInfo.length) { throw new TypeErro('Tuple arity does not match its prototype'); } values.map(function (val, index) { this = checkType(typeInfo)(val); }, this); Object.freeze(this); }; _T.prototype.values = function () { return Object.keys(this).map(function (k) { return this; } } return _T;}

UF, si, moita chicha para cortar. Se nos damos conta, é unha función de tupla que devolverá unha clase. A función serve para que poidamos indicar o tamaño e os tipos dos elementos da tupla. Polo tanto, podemos facelo, por exemplo:

const Status = Tuple(Number, String);

‘Estado’ é unha clase. Se che dá Tuble, está volvendo _t. Por medio dun crocuser, regresa unha clase preconfigurada co que necesitamos. Máxico. Agora podemos definir unha nova tupla deste xeito:

const status = new Status(401, 'No Authorize');

Cando instanciamos o estado “fai un cheque que os valores nulos non están a suceder e iso O tamaño da tupla creada corresponde co tamaño da tupla predefinida. Tamén verifica que se espera que o tipo que ocorreu.

Finalmente, ten un método para que poidamos obter os valores en formato de matriz.É moi útil porque se usamos a destrución de novo, podemos obter os valores do Tupi deste xeito:

const = status.values();

bo … eles Non son os máis cómodos das tuplas do mundo en JavaScript, pero temos formas de simularlo. E se non tivésemos que simularlos? E se JS e as levantas serialmente? Ben de novo, o tipo de escrita axúdanos neste. Podería facelo:

let status: ; status = ; // OK status = ; // Error

moito mellor :). Repito, manteña en mente o tipo de tipo, chegou a quedarse.

As tuplas son un bo mecanismo para evitar a detención de funcións. Non obstante, hai outro método chamado currículo, que non só nos axudará coa ariedade, senón que é un bo mecanismo para mellorar a modularidade e a reutilización, pero … Creo que sairemos aquí para hoxe 🙂

Conclusión

Comprender as tuberías e as súas formas de usalas, axudaranos a desenvolver código máis lexible. Continuaremos falando sobre as técnicas necesarias para cubrir todos os conceptos que están presentes nos tubos.

Por agora, creo que é un bo paso sabendo que as funcións de deseño para que teñan unha ariedade reducida e coñecer a tipos a partir dos parámetros de entrada e saída das nosas funcións, nos axudaremos a facer un código moito máis mantible, modularizable e reutilizable.

Nós lemos 🙂

pd: deixo o conceptual Mapa desta entrada:

the-pipes-en-javascript

Publicacións de programación funcional de JavaScript anterior:

Introdución

  1. Programación funcional en javascript
  2. Programación funcional en JavaScript: os obxectos
  3. funcional Programación en JavaScript: Funcións

Control de fluxo funcional

  1. Programación funcional en JavaScript: Métodos funcionais
  2. Programación funcional en JavaScript: o Recursión

Modularidade funcional

  1. Programación funcional en JavaScript: Arity and Tupply
  2. Programación funcional en JavaScript: The Curricy

Imaxe de tapa | Flickr

Deixa unha resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *