Slide 1

Slide 1 text

p o r q u e e c o m o CONJUNTOS EM 3 ATOS Porque conjuntos simplificam a lógica,
 e como eles são construídos em Elixir Luciano Ramalho @ramalhoorg Com emojis de gatinhos!

Slide 2

Slide 2 text

PALESTRA EM 3 ATOS 1
 Porque conjuntos podem simplificar seu código 2 2
 Como é a API de MapSet 3
 Como implementar
 uma coleção como MapSet

Slide 3

Slide 3 text

PORQUE USAR CONJUNTOS Alguns casos de usos comuns para conjuntos 3

Slide 4

Slide 4 text

CASO DE USO #1: RUNE FINDER 4 query = ["FACE"] Exibir item se todas as palavras da consulta aparecem na descrição.

Slide 5

Slide 5 text

CASO DE USO #1: RUNE FINDER 5 query = ["FACE"] Exibir item se todas as palavras da consulta aparecem na descrição.

Slide 6

Slide 6 text

CASO DE USO #1: RUNE FINDER 6 query = ["FACE"] Exibir item se todas as palavras da consulta aparecem na descrição.

Slide 7

Slide 7 text

CASO DE USO #1: RUNE FINDER 7

Slide 8

Slide 8 text

CASO DE USO #1: RUNE FINDER 8 UnicodeData.txt ... 1F637;FACE WITH MEDICAL MASK 1F638;GRINNING CAT FACE WITH SMILING EYES 1F639;CAT FACE WITH TEARS OF JOY 1F63A;SMILING CAT FACE WITH OPEN MOUTH 1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES 1F63C;CAT FACE WITH WRY SMILE 1F63D;KISSING CAT FACE WITH CLOSED EYES 1F63E;POUTING CAT FACE 1F63F;CRYING CAT FACE 1F640;WEARY CAT FACE 1F641;SLIGHTLY FROWNING FACE 1F642;SLIGHTLY SMILING FACE 1F643;UPSIDE-DOWN FACE 1F644;FACE WITH ROLLING EYES ...

Slide 9

Slide 9 text

CASO DE USO #1: RUNE FINDER 9 query = ["FACE"] ... 1F637;FACE WITH MEDICAL MASK 1F638;GRINNING CAT FACE WITH SMILING EYES 1F639;CAT FACE WITH TEARS OF JOY 1F63A;SMILING CAT FACE WITH OPEN MOUTH 1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES 1F63C;CAT FACE WITH WRY SMILE 1F63D;KISSING CAT FACE WITH CLOSED EYES 1F63E;POUTING CAT FACE 1F63F;CRYING CAT FACE 1F640;WEARY CAT FACE 1F641;SLIGHTLY FROWNING FACE 1F642;SLIGHTLY SMILING FACE 1F643;UPSIDE-DOWN FACE 1F644;FACE WITH ROLLING EYES ...

Slide 10

Slide 10 text

CASO DE USO #1: RUNE FINDER 10 query = ["FACE", "CAT"] ... 1F637;FACE WITH MEDICAL MASK 1F638;GRINNING CAT FACE WITH SMILING EYES 1F639;CAT FACE WITH TEARS OF JOY 1F63A;SMILING CAT FACE WITH OPEN MOUTH 1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES 1F63C;CAT FACE WITH WRY SMILE 1F63D;KISSING CAT FACE WITH CLOSED EYES 1F63E;POUTING CAT FACE 1F63F;CRYING CAT FACE 1F640;WEARY CAT FACE 1F641;SLIGHTLY FROWNING FACE 1F642;SLIGHTLY SMILING FACE 1F643;UPSIDE-DOWN FACE 1F644;FACE WITH ROLLING EYES ...

Slide 11

Slide 11 text

CASO DE USO #1: RUNE FINDER 11 query = ["FACE", "CAT", "EYES"] ... 1F637;FACE WITH MEDICAL MASK 1F638;GRINNING CAT FACE WITH SMILING EYES 1F639;CAT FACE WITH TEARS OF JOY 1F63A;SMILING CAT FACE WITH OPEN MOUTH 1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES 1F63C;CAT FACE WITH WRY SMILE 1F63D;KISSING CAT FACE WITH CLOSED EYES 1F63E;POUTING CAT FACE 1F63F;CRYING CAT FACE 1F640;WEARY CAT FACE 1F641;SLIGHTLY FROWNING FACE 1F642;SLIGHTLY SMILING FACE 1F643;UPSIDE-DOWN FACE 1F644;FACE WITH ROLLING EYES ...

Slide 12

Slide 12 text

CASO DE USO #1: SOLUÇÃO DESCONJUNTADA Já escrevi código assim em Go* 12 *Go 1.12 ainda não tem conjuntos na sua biblioteca padrão

Slide 13

Slide 13 text

CASO DE USO #1: SOLUÇÃO DESCONJUNTADA Já escrevi código assim em Go* 13 *Go 1.12 ainda não tem conjuntos na sua biblioteca padrão

Slide 14

Slide 14 text

CASO DE USO #1: SOLUÇÃO DESCONJUNTADA 2 Mais legível, mas ainda deixa a desejar... 14

Slide 15

Slide 15 text

CASO DE USO #1: SOLUÇÃO DESCONJUNTADA 2 Mais legível, mas ainda deixa a desejar... 15

Slide 16

Slide 16 text

16 E se… Agora não! Estou muito ocupado codando laços aninhados! www.workcompass.com/

Slide 17

Slide 17 text

JOHN BACKUS — TURING AWARD LECTURE, 1977 17

Slide 18

Slide 18 text

CASO DE USO #1: RUNE FINDER 18 www.workcompass.com/ Exibir item se todas as palavras da consulta aparecem na descrição.

Slide 19

Slide 19 text

CASO DE USO #1: RUNE FINDER 19 Q ⊂ D www.workcompass.com/ Exibir item se todas as palavras da consulta aparecem na descrição.

Slide 20

Slide 20 text

CASO DE USO #1: RUNE FINDER 20 https://github.com/standupdev/rf

Slide 21

Slide 21 text

CASO DE USO #1: RUNE FINDER 21 Tokenize: transforma query e descrição em conjuntos www.workcompass.com/ https://github.com/standupdev/rf

Slide 22

Slide 22 text

CASO DE USO #1: RUNE FINDER 22 Q ⊂ D www.workcompass.com/ https://github.com/standupdev/rf

Slide 23

Slide 23 text

CASO DE USO #2: GIMEL Outro buscador de emojis, com uma estratégia diferente. rf.exs: percorre UnicodeData.txt inteiro a cada consulta; estratégia grep. Gimel: percorre UnicodeData.txt só uma vez ao iniciar, criando dois índices que são usados nas consultas; estratégia índice invertido. 23

Slide 24

Slide 24 text

GIMEL: UM CONSOLE PARA ACHAR CARACTERES UNICODE 24

Slide 25

Slide 25 text

GIMEL: UM CONSOLE PARA ACHAR CARACTERES UNICODE 25

Slide 26

Slide 26 text

GIMEL: UM CONSOLE PARA ACHAR CARACTERES UNICODE 26

Slide 27

Slide 27 text

COMO FUNCIONA UM ÍNDICE INVERTIDO %{ palavra_chave => conjunto_de_ocorrências, … } 27

Slide 28

Slide 28 text

COMO FUNCIONA UM ÍNDICE INVERTIDO Para encontrar os três gatinhos, pegue a intersecção das ocorrências de "FACE", "CAT", e "EYES": 28

Slide 29

Slide 29 text

INTERSECÇÃO DAS OCORRÊNCIAS: 3 GATINHOS 29 ⚄ ⾯面 ☹ ὺ ⚃ ☺ ⚀ ⚂ ⚁ ☻ ⚅ ꊶ (F ∩ C) ∩ E Face Cat Eyes query = ["FACE", "CAT", "EYES"] Nota: este diagrama não está correto. Deveria haver emojis nas intersecções entre dois conjuntos: F ∩ C, F ∩ E, C ∩ E

Slide 30

Slide 30 text

CASO DE USO #2: GIMEL, FUNÇÃO SEARCH/2 30 https://github.com/standupdev/gimel

Slide 31

Slide 31 text

CASO DE USO #2: GIMEL, FUNÇÃO SEARCH/2 31 https://github.com/standupdev/gimel Inicia redução com ocorrências da primeira palavra

Slide 32

Slide 32 text

CASO DE USO #2: GIMEL, FUNÇÃO SEARCH/2 32 https://github.com/standupdev/gimel A ∩ B ∩ C ∩ D...

Slide 33

Slide 33 text

CASO DE USO #3: LOJA ONLINE 33 Destacar todos os produtos favoritados, exceto aqueles que já estão no carrinho de compras.

Slide 34

Slide 34 text

CASO DE USO #3: LOJA ONLINE 34 Destacar todos os produtos favoritados, exceto aqueles que já estão no carrinho de compras. F ∖ C Diferença entre
 conjuntos:

Slide 35

Slide 35 text

LÓGICA E CONJUNTOS Uma relação íntima 35

Slide 36

Slide 36 text

Nobody has yet discovered a branch of mathematics that has successfully resisted formalization into set theory. Thomas Forster
 Logic Induction and Sets, p. 167 36

Slide 37

Slide 37 text

Ninguém descobriu ainda um ramo da matemática que tenha resistido à formalização através da teoria dos conjuntos. Thomas Forster
 Indução Lógica e Conjuntos, p. 167 37

Slide 38

Slide 38 text

CONJUNÇÃO LÓGICA É INTERSECÇÃO "x pertence à intersecção de A com B" é o mesmo que: "x pertence a A e x pertence a B." Em matemática: x ∈ (A ∩ B) ⟺ (x ∈ A) ∧ (x ∈ B) Em Elixir: MapSet.intersection Bitwise.band/2, &&& 38

Slide 39

Slide 39 text

DISJUNÇÃO LÓGICA É UNIÃO "x pertence à união de A com B" é o mesmo que: "x pertence a A ou x pertence a B" Em matemática: x ∈ (A ∪ B) ⟺ (x ∈ A) ∨ (x ∈ B) Em Elixir: MapSet.union/2,
 Bitwise.bor/2, ||| 39

Slide 40

Slide 40 text

DIFERENÇA "x pertence a A mas não pertence a B" é o mesmo que: "elementos de A menos elementos de B" Notação matemática: x ∈ (A ∖ B) ⟺ (x ∈ A) ∧ (x ∉ B) Em Elixir: MapSet.difference/2 40

Slide 41

Slide 41 text

DIFERENÇA SIMÉTRICA "x pertence a A ou x pertence a B mas não pertence a ambos" é o mesmo que: "x pertence à união de A com B menos a intersecção de A com B" Em matemática: 
 Em Elixir: Bitwise.bxor/2, ^^^ 41 x ∈ (A ∆ B) ⟺ (x ∈ A) ⊻ (x ∈ B)

Slide 42

Slide 42 text

CONJUNTOS EM VÁRIAS LINGUAGENS Como Elixir se compara 42

Slide 43

Slide 43 text

CONJUNTOS EM VÁRIAS LINGUAGENS/PLATAFORMAS Amostra de linguagens ou APIs de plataformas que oferecem conjuntos em sua biblioteca-padrão. 43 Elixir MapSet: 14 métodos Ruby Set: > 10 métodos e operadores Python set, frozenset: > 10 métodos e operadores .Net (C# etc.) ISet interface: > 10 métodos; 2 implementações JavaScript (ES6) Set: < 10 métodos Java Set interface: < 10 métodos; 8 implementações Go Faça você mesmo, ou escolha um dos N pacotes...

Slide 44

Slide 44 text

CONJUNTOS EM VÁRIAS LINGUAGENS/PLATAFORMAS Amostra de linguagens ou APIs de plataformas que oferecem conjuntos em sua biblioteca-padrão. 44 Elixir MapSet: 14 métodos Ruby Set: > 10 métodos e operadores Python set, frozenset: > 10 métodos e operadores .Net (C# etc.) ISet interface: > 10 métodos; 2 implementações JavaScript (ES6) Set: < 10 métodos Java Set interface: < 10 métodos; 8 implementações Go Faça você mesmo, ou escolha um dos N pacotes...

Slide 45

Slide 45 text

MAPSET Recomendado desde Elixir v1.2 (2016) 45

Slide 46

Slide 46 text

INTERFACE DE MAPSET Construção 46 new() Cria um novo MapSet vazio. new(enum) Cria um MapSet a partir de um enumerável. new(enum, transform) Idem, aplicando função transform a cada elemento. member?(set, elemento) Testa se o elemento pertence ao MapSet. put(set, elemento) Insere o elemento. Se há membro igual, nada acontece. delete(set, elemento) Retira o elemento do MapSet. size(set) Devolve o número de elementos do MapSet. to_list(set) Cria uma lista a partir do MapSet. Operações básicas

Slide 47

Slide 47 text

INTERFACE DE MAPSET Operações entre conjuntos — devolvem novo MapSet 47 intersection(set1, set2) Intersecção entre dois MapSet. A ∩ B union(set1, set2) União de dois MapSet. A ∪ B difference(set1, set2) Diferença set1 ➖ set2. A ∖ B Testes — devolvem booleano member?(set, elemento) Elemento pertence ao MapSet? x ∈ A subset?(set1, set2) Todos os elementos de set1 estão em set2? A ⊆ B equal?(set1, set2) set1 e set2 tem os mesmos elementos? A = B disjoint?(set1, set2) set1 e set2 não tem elementos em comum? A ∩ B = ∅

Slide 48

Slide 48 text

UINTSET Conjunto para inteiros pequenos. 48

Slide 49

Slide 49 text

ORIGEM DA IDEIA: THE GO PROGRAMMING LANGUAGE The Go Programming Language Alan A. A. Donovan & Brian W. Kernighan 49

Slide 50

Slide 50 text

INTERFACE DE UINTSET Construção — como MapSet, só para elementos inteiros 50 new() Cria um novo UintSet vazio. new(enum) Cria um UintSet a partir de um enumerável. new(enum, transform) Idem, aplicando função transform a cada elemento. member?(set, elemento) Testa se o elemento pertence ao UintSet. put(set, elemento) Insere o elemento. Se há membro igual, nada acontece. delete(set, elemento) Retira o elemento do UintSet. length(set) Devolve o número de elementos do UintSet — O(n). to_list(set) Cria uma lista a partir do UintSet. Operações básicas — a função diferente: size/1 ≠ length/1

Slide 51

Slide 51 text

INTERFACE DE UINTSET Operações entre conjuntos — devolvem novo UintSet 51 intersection(set1, set2) Intersecção entre dois UintSet. A ∩ B union(set1, set2) União de dois UintSet. A ∪ B difference(set1, set2) Diferença set1 ➖ set2. A ∖ B Testes — devolvem booleano member?(set, elemento) Elemento pertence ao UintSet? x ∈ A subset?(set1, set2) Todos os elementos de set1 estão em set2? A ⊆ B equal?(set1, set2) set1 e set2 tem os mesmos elementos? A = B disjoint?(set1, set2) set1 e set2 não tem elementos em comum? A ∩ B = ∅

Slide 52

Slide 52 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 52

Slide 53

Slide 53 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 53

Slide 54

Slide 54 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 54

Slide 55

Slide 55 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 55

Slide 56

Slide 56 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 56

Slide 57

Slide 57 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 57

Slide 58

Slide 58 text

ESTRUTURA INTERNA DE UINTSET: UM (BIG) INTEGER 58

Slide 59

Slide 59 text

IMPLEMENTAÇÃO Código-fonte de UintSet 59

Slide 60

Slide 60 text

SHOW ME THE CODE 60 https://github.com/ramalho/uint_set

Slide 61

Slide 61 text

UINTSET: EMULANDO MAPSET SOBRE VETOR DE BITS 61

Slide 62

Slide 62 text

UINTSET: EMULANDO MAPSET SOBRE VETOR DE BITS Note o struct com 1 campo: bits 62

Slide 63

Slide 63 text

UINTSET: NEW/0 — NEW/1 — NEW/2 63

Slide 64

Slide 64 text

BITOPS: TRATANDO UM INTEIRO COMO VETOR DE BITS 64

Slide 65

Slide 65 text

BITOPS: SET_BIT/2 — UNSET_BIT/2 65

Slide 66

Slide 66 text

BITOPS: LIST_ONES/1 66

Slide 67

Slide 67 text

BITOPS: STREAM_ONES/1 67

Slide 68

Slide 68 text

UINTSET: NEW/0 — NEW/1 — NEW/2 68

Slide 69

Slide 69 text

UINTSET: DELETE/2 — DIFFERENCE/2 — DISJOINT/2 69

Slide 70

Slide 70 text

EQUAL?/2 INTERSECTION/2 LENGTH/1 MEMBER?/1 PUT/2 70

Slide 71

Slide 71 text

STREAM/1 — SUBSET/2 — TO_LIST/1 — UNION/2 71

Slide 72

Slide 72 text

PROTOCOLO ENUMERABLE 72

Slide 73

Slide 73 text

PROTOCOLOS: COLLECTABLE — INSPECT 73

Slide 74

Slide 74 text

CONCLUSÃO Resumindo 74

Slide 75

Slide 75 text

APRENDENDO COM CONJUNTOS Operações com conjuntos podem simplificar algoritmos. Elixir oferece uma implementação rica: MapSet. O código de MapSet é um excelente exemplo de abstração de dados usando struct e protocolos. A interface de UintSet é quase a mesma de MapSet,
 mas a implementação é mais simples, com operadores Bitwise para manipular inteiros como vetores de bits. 75 https://github.com/ramalho/uint_set

Slide 76

Slide 76 text

Luciano Ramalho
 @ramalhoorg | @standupdev
 [email protected] MUITO GRATO!

Slide 77

Slide 77 text

Luciano Ramalho
 @ramalhoorg | @standupdev
 [email protected] MUITO GRATO!