Slide 1

Slide 1 text

Willian - BrazilJS 2024 Além do else! Categorizando Pokemóns com Pattern Matching no JavaScript

Slide 2

Slide 2 text

• Codo fofo desde 2004 • UI desde 2007 • Netflix - TVUI • Ex-UMA-PORRADA-DE- COISA • Podcast DNE e Lives Sobre Mim

Slide 3

Slide 3 text

Estrutura de decisões no JS

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Declaração vs expressão • Expressão sempre retorna um valor • Pode ser tão complexa quanto o autor do código quiser. (vide expression statements) • Declaração só executa o que está dentro dela • Declarações longas podem ser delimitada por `{` e `}`

Slide 7

Slide 7 text

Como a expressão condicional é avaliada • Faz a avaliação da expressão • Se a expressão resolver em Boolean, retorna o valor • Se a expressão resolver am algum desses valores: false, 0, -0, 0n, "", null, undefined, NaN, retorna false • Pra qualquer outro valor, retorna true.

Slide 8

Slide 8 text

• Nao existe else if • O if só executa a próxima instrução após a declaração. • O mesmo serve pro else • Pra executar mais de uma declaração, use se as {} pra delimitar um bloco declarativo E o else if if (condição) { // Mágica aqui 🪄 } else { //…Não tem mágica 😕 }

Slide 9

Slide 9 text

• Nao existe else if • O if só executa a próxima instrução após a declaração. • O mesmo serve pro else • Pra executar mais de uma declaração, use se as {} pra delimitar um bloco declarativo E o else if if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica🪄🐇 } else { //…Não tem mágica 😕 }

Slide 10

Slide 10 text

• Nao existe else if • O if só executa a próxima instrução após a declaração. • O mesmo serve pro else • Pra executar mais de uma declaração, use se as {} pra delimitar um bloco declarativo E o else if if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica🪄🐇 } else { //…Não tem mágica 😕 }

Slide 11

Slide 11 text

• Nao existe else if • O if só executa a próxima instrução após a declaração. • O mesmo serve pro else • Pra executar mais de uma declaração, use se as {} pra delimitar um bloco declarativo E o else if if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica🪄🐇 } else { //…Não tem mágica 😕 }

Slide 12

Slide 12 text

• Nao existe else if • O if só executa a próxima instrução após a declaração. • O mesmo serve pro else • Pra executar mais de uma declaração, use se as {} pra delimitar um bloco declarativo E o else if if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica🪄🐇 } else { //…Não tem mágica 😕 }

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

• Expressão como input A instrução switch switch(expressão) { case exp1: ... break; case exp2: case exp3: ... break; default: ... }

Slide 16

Slide 16 text

• Expressão como input • Comparação com a expressão da clausula case A instrução switch switch(expressão) { case exp1: ... break; case exp2: case exp3: ... break; default: ... }

Slide 17

Slide 17 text

• Expressão como input • Comparação com a expressão da clausula case • Ponto de entrada onde as expressões se correspondem A instrução switch switch(expressão) { case exp1: ... break; case exp2: case exp3: ... break; default: ... }

Slide 18

Slide 18 text

• Expressão como input • Comparação com a expressão da clausula case • Ponto de entrada onde as expressões se correspondem A instrução switch switch(expressão) { case exp1: ... break; case exp2: case exp3: ... break; default: ... }

Slide 19

Slide 19 text

• Expressão como input • Comparação com a expressão da clausula case • Ponto de entrada onde as expressões se correspondem • Clausula default pra caso a expressão não case com nada A instrução switch switch(expressão) { case exp1: ... break; case exp2: case exp3: ... break; default: ... }

Slide 20

Slide 20 text

• Pode substituir a cadeia de if- else usando true como de expressão de entrada E o switch true? if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica 🪄🐇 } else { // Não tem mágica 😕 }

Slide 21

Slide 21 text

• Pode substituir a cadeia de if- else usando true como de expressão de entrada • Expressões podem ser usadas tanto na expressão de entrada quanto na clausula case E o switch true? switch (true) { case condição: // Mágica aqui 🪄 break; case outraCondição: // Outra mágica 🪄🐇 break; default: // Não tem mágica 😕 }

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Qual é o resultado? switch (true) { case '1': console.info('uno'); break; case 1: console.info('numero'); break; case false: console.info('falso'); break; default: console.info('oche'); }

Slide 24

Slide 24 text

Qual é o resultado? switch (true) { case '1': console.info('uno'); break; case 1: console.info('numero'); break; case false: console.info('falso'); break; default: console.info('oche'); }

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

• Única expressão condicional do JS • Unico operador ternário da linguagem • Os tres operandos são expressões Operador ternário expression ? expIfTrue : expIfFalse;

Slide 28

Slide 28 text

• Única expressão condicional do JS • Unico operador ternário da linguagem • Os tres operandos são expressões Operador ternário expression ? expIfTrue : expIfFalse;

Slide 29

Slide 29 text

• Única expressão condicional do JS • Unico operador ternário da linguagem • Os tres operandos são expressões Operador ternário expression ? expIfTrue : expIfFalse;

Slide 30

Slide 30 text

• Única expressão condicional do JS • Unico operador ternário da linguagem • Os tres operandos são expressões Operador ternário expression ? expIfTrue : expIfFalse;

Slide 31

Slide 31 text

• Única expressão condicional do JS • Unico operador ternário da linguagem • Os tres operandos são expressões Operador ternário if (condição) { // Mágica aqui 🪄 } else if (outraCondição) { // Outra mágica🪄🐇 } else { //…Não tem mágica 😕 }

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

condição ? magica // Mágica aqui 🪄 : outraCondição ? outraMagica // Outra mágica 🪄🐇 : semMagica // Não tem mágica 😕

Slide 34

Slide 34 text

condição ? magica // Mágica aqui 🪄 : outraCondição ? outraMagica // Outra mágica 🪄🐇 : semMagica // Não tem mágica 😕

Slide 35

Slide 35 text

Categorização de Pokemon

Slide 36

Slide 36 text

Problema exemplo • Tenho um , um e um . • Se eu achar um pokemon do tipo: • Grama ou Inseto -> uso • Terra ou Agua -> uso • Fogo ou Pedra -> uso • Caso contrario -> Fuja

Slide 37

Slide 37 text

type Pokemon = { id: number; name: string; type: [string, string?]; }

Slide 38

Slide 38 text

const whatPokemon = enemy => { if (enemy.type[0] === 'Grama' || enemy.type[1] === 'Grama') { return 'Charmander'; } if (enemy.type[0] === 'Inseto' || enemy.type[1] === 'Inseto') { return 'Charmander'; } if (enemy.type[0] === 'Terra' || enemy.type[1] === 'Terra') { return 'Bulbasaur'; } if (enemy.type[0] === 'Agua' || enemy.type[1] === 'Agua') { return 'Bulbasaur'; } if (enemy.type[0] === 'Fogo' || enemy.type[1] === 'Fogo') { return 'Squirtle'; } if (enemy.type[0] === 'Pedra' || enemy.type[1] === 'Pedra') { return 'Squirtle'; } return "Fuja"; }

Slide 39

Slide 39 text

const whatPokemon = (enemy) => { if (['Grama', 'Inseto'].includes(enemy.type[0]) || ['Grama', 'Inseto'].includes(enemy.type[1])) { return 'Charmander'; } if (['Terra', 'Agua'].includes(enemy.type[0]) || ['Terra', 'Agua'].includes(enemy.type[1])) { return 'Bulbasaur'; } if (['Fogo', 'Pedra'].includes(enemy.type[0]) || ['Fogo', 'Pedra'].includes(enemy.type[1])) { return 'Squirtle'; } return "Fuja"; }

Slide 40

Slide 40 text

const whatPokemon = enemy => { switch (true) { case enemy.type[0] === 'Grama': case enemy.type[1] === 'Grama': case enemy.type[0] === 'Inseto': case enemy.type[1] === 'Inseto': return 'Charmander'; case enemy.type[0] === 'Terra': case enemy.type[1] === 'Terra': case enemy.type[0] === 'Agua': case enemy.type[1] === 'Agua': return 'Bulbasaur'; case enemy.type[0] === 'Fogo': case enemy.type[1] === 'Fogo': case enemy.type[0] === 'Pedra': case enemy.type[1] === 'Pedra': return 'Squirtle'; default: return 'Fuja'; } }

Slide 41

Slide 41 text

const whatPokemon = enemy => { switch (true) { case ['Grama', ‘Inseto’].includes(enemy.type[0] || ['Grama', 'Inseto'].includes(enemy.type[1]): return 'Charmander'; case ['Terra', ‘Agua’].includes(enemy.type[0]) || ['Terra', ‘Agua'].includes(enemy.type[1]): return 'Bulbasaur'; case ['Fogo', ‘Pedra'].includes(enemy.type[0]) || ['Fogo', 'Pedra'].includes(enemy.type[1]): return 'Squirtle'; default: return "Fuja"; } }

Slide 42

Slide 42 text

const whatPokemon = enemy => ['Grama', ‘Inseto'].includes(enemy.type[0]) || ['Grama', 'Inseto'].includes(enemy.type[1]) ? 'Charmander' : ['Terra', 'Agua'].includes(enemy.type[0]) || ['Terra', 'Agua'].includes(enemy.type[1]) ? 'Bulbasaur' : ['Fogo', 'Pedra'].includes(enemy.type[0]) || ['Fogo', 'Pedra'].includes(enemy.type[1]) ? 'Squirtle' : "Fuja";

Slide 43

Slide 43 text

Pattern Matching

Slide 44

Slide 44 text

• Expressão • Recebe um subject pra teste • Tenta casar com o pattern de cada clausula when • Quando casa, retorna o valor da expressão da clausula when • Se nada casa, retorna a expressão da clausula default Instrução match match() { when : ; ... default: ; }

Slide 45

Slide 45 text

const whatPokemon = enemy => match (enemy.type) { when ["Grama"]: 'Charmander'; default: 'Fuja'; }

Slide 46

Slide 46 text

const whatPokemon = enemy => match (enemy.type) { when ["Grama",...] or [,"Grama"]: 'Charmander'; default: 'Fuja'; }

Slide 47

Slide 47 text

const whatPokemon = enemy => match (enemy.type) { when ["Grama", ...] or [,"Grama"]: 'Charmander'; when ["Inseto", ...] or [,"Inseto"]: 'Charmander'; default: 'Fuja'; }

Slide 48

Slide 48 text

const whatPokemon = enemy => match (enemy.type) { when [/Grama|Inseto/, ...] or [,/Grama|Inseto/]: 'Charmander'; when [/Terra|Agua/, ...] or [,/Terra|Agua/]: 'Bulbasaur'; when [/Fogo|Pedra/, ...] or [,/Fogo|Pedra/]: 'Squirtle'; default: 'Fuja'; }

Slide 49

Slide 49 text

const whatPokemon = enemy => match (enemy.type) { when ['Grama' or 'Inseto', ...] or [,'Grama' or 'Inseto']: 'Charmander'; when ['Terra' or 'Agua', ...] or [,'Terra' or 'Agua']: 'Bulbasaur'; when ['Fogo' or 'Pedra', ...] or [,'Fogo' or 'Pedra']: 'Squirtle'; default: 'Fuja'; }

Slide 50

Slide 50 text

Custom matcher

Slide 51

Slide 51 text

const Pokemon = { };

Slide 52

Slide 52 text

const Pokemon = { BomPraCharmander: { }, };

Slide 53

Slide 53 text

const Pokemon = { BomPraCharmander: { [Symbol.customMatcher](subject) { } }, };

Slide 54

Slide 54 text

const Pokemon = { BomPraCharmander: { [Symbol.customMatcher](subject) { return ["Grama", “Inseto"].includes(subject[0]) || ["Grama", "Inseto"].includes(subject[1]); } }, };

Slide 55

Slide 55 text

const Pokemon = { BomPraCharmander: { [Symbol.customMatcher](subject) { return ["Grama", “Inseto"].includes(subject[0]) || ["Grama", "Inseto"].includes(subject[1]); } }, BomPraBulbasaur: { [Symbol.customMatcher](subject) { return ["Terra", “Agua"].includes(subject[0]) || ["Terra", "Agua"].includes(subject[1]); } }, BomPraSquirtle: { [Symbol.customMatcher](subject) { return ["Fogo", “Pedra"].includes(subject[0]) || ["Fogo", "Pedra"].includes(subject[1]); } } };

Slide 56

Slide 56 text

const whatPokemon = enemy => match (enemy.type) { when Pokemon.BomPraCharmander: 'Charmander'; when Pokemon.BomPraBulbasaur: 'Bulbasaur'; when Pokemon.BomPraSquirtle: 'Squirtle'; default: 'Fuja'; }

Slide 57

Slide 57 text

Operador is

Slide 58

Slide 58 text

• Operador binário • Primeiro operando é o subject • Segundo operando é o pattern • Resolve a expressão em booleano Operador is is ;

Slide 59

Slide 59 text

if (num >= 10 && num <= 20) { console.log(num); }

Slide 60

Slide 60 text

if (num is >= 10 and <= 20) { console.log(num); }

Slide 61

Slide 61 text

Conclusão • JS tem vários tipos de condicionais • Switch tem a estrutura mas falta expressividade • If tem a expressividade mas falta estrutura • Condicional ternário é a única condicional que é expressão • Pattern match cobre as limitações das expressões anteriores • Custom matcher e o operador is expande a expressividade de condicionaos no JS

Slide 62

Slide 62 text

Links • https://github.com/tc39/proposal-pattern-matching • https://tc39.es/proposal-pattern-matching/#sec-pattern-matching

Slide 63

Slide 63 text

Fim