Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elixir di lunga vita.

Elixir di lunga vita.

Elixir è un linguaggio funzionale, che offre un approccio diverso rispetto alla programmazione a oggetti a cui siamo tutti abituati.

Durante la presentazione approfondiremo i punti di forza di Elixir, che lo rendono un linguaggio moderno e versatile e un'ottima soluzione per diversi tipi di applicazioni.

E22edc988280c3b6ff183318bc1590c2?s=128

weLaika

July 04, 2016
Tweet

Transcript

  1. ELIXIR DI LUNGA VITA

  2. WHERE TO START? Basic concepts OTP GenServer Supervisor

  3. BASIC TYPES i e x > 1 # i n

    t e g e r i e x > 0 x 1 F # i n t e g e r i e x > 1 . 0 # f l o a t i e x > t r u e # b o o l e a n i e x > : a t o m # a t o m / s y m b o l i e x > " e l i x i r " # s t r i n g i e x > [ 1 , 2 , 3 ] # l i s t i e x > { 1 , 2 , 3 } # t u p l e
  4. ATOMS Atoms are constants where their name is their own

    value Some other languages call these symbols i e x > : h e l l o : h e l l o i e x > : h e l l o = = : w o r l d f a l s e The booleans true and false are, in fact, atoms i e x > t r u e = = : t r u e t r u e i e x > i s _ a t o m ( f a l s e ) t r u e i e x > i s _ b o o l e a n ( : f a l s e ) t r u e
  5. LISTS Elixir uses square brackets to specify a list of

    values i e x > [ 1 , 2 , t r u e , 3 ] [ 1 , 2 , t r u e , 3 ] i e x > l e n g t h [ 1 , 2 , 3 ] 3
  6. ++/2 AND --/2 OPERATORS i e x > [ 1

    , 2 , 3 ] + + [ 4 , 5 , 6 ] [ 1 , 2 , 3 , 4 , 5 , 6 ] i e x > [ 1 , t r u e , 2 , f a l s e , 3 , t r u e ] - - [ t r u e , f a l s e ] [ 1 , 2 , 3 , t r u e ] HD/1 AND TL/1 i e x > l i s t = [ 1 , 2 , 3 ] i e x > h d ( l i s t ) 1 i e x > t l ( l i s t ) [ 2 , 3 ]
  7. TUPLES Elixir uses curly brackets to define tuples. Like lists,

    tuples can hold any value i e x > { : o k , " h e l l o " } { : o k , " h e l l o " } i e x > t u p l e _ s i z e { : o k , " h e l l o " } 2
  8. ACCESSING A TUPLE ELEMENT PER INDEX OR GETTING THE TUPLE

    SIZE i e x > t u p l e = { : o k , " h e l l o " } { : o k , " h e l l o " } i e x > e l e m ( t u p l e , 1 ) " h e l l o " i e x > t u p l e _ s i z e ( t u p l e ) 2 PUT AN ELEMENT AT A PARTICULAR INDEX IN A TUPLE WITH PUT_ELEM/3 i e x > t u p l e = { : o k , " h e l l o " } { : o k , " h e l l o " } i e x > p u t _ e l e m ( t u p l e , 1 , " w o r l d " ) { : o k , " w o r l d " } i e x > t u p l e { : o k , " h e l l o " }
  9. LISTS OR TUPLES?

  10. LISTS Are stored in memory as linked lists Accessing the

    length of a list is a linear operation Updating a list is fast as long as we are prepending elements
  11. TUPLES Are stored contiguously in memory Get the tuple size

    or access an element by index is fast Updating or adding elements to tuples is expensive
  12. ASSIGNMENT: I DO NOT THINK IT MEANS WHAT YOU THINK

    IT MEANS.
  13. MATCH OPERATOR i e x > a = 1 1

    i e x > a + 3 4 the le -hand side is a variable and the right-hand side is an integer literal, so Elixir can make the match true by binding the variable a to value 1
  14. BUT THIS IS JUST AN ASSIGNEMENT, RIGHT?

  15. NOT REALLY

  16. i e x > a = 1 1 i e

    x > 1 = a 1 i e x > 2 = a * * ( M a t c h E r r o r ) n o m a t c h o f r i g h t h a n d s i d e v a l u e : 1
  17. PATTERN MATCHING WITH LISTS i e x > f i

    r s t _ l i s t = [ 1 , 2 , [ 3 , 4 , 5 ] ] [ 1 , 2 , [ 3 , 4 , 5 ] ] i e x > [ a , b , c ] = f i r s t _ l i s t [ 1 , 2 , [ 3 , 4 , 5 ] ] i e x > a 1 i e x > b 2 i e x > c [ 3 , 4 , 5 ] i e x > s e c o n d _ l i s t = [ 1 , 2 , 3 ] [ 1 , 2 , 3 ] i e x > [ d , 2 , e ] = s e c o n d _ l i s t [ 1 , 2 , 3 ] i e x > d 1 i e x > e
  18. PATTERN MATCHING WITH FUNCTIONS Pattern matching isn’t limited to just

    variables in Elixir, it can be applied to function signatures i e x > h a n d l e _ r e s u l t = f n . . . > { : o k , r e s u l t } - > I O . p u t s " y a d d a " . . . > { : e r r o r } - > I O . p u t s " b a d d a " . . . > e n d i e x > s o m e _ r e s u l t = 1 i e x > h a n d l e _ r e s u l t . ( { : o k , s o m e _ r e s u l t } ) y a d d a i e x > h a n d l e _ r e s u l t . ( { : e r r o r } ) b a d d a
  19. |> OPERATOR

  20. The pipe operator |> passes the result of an expression

    as the first parameter of another expression SOME NESTED FUNCTIONS f o o ( b a r ( 
 l o l ( 
 b a z ( ) 
 ) 
 ) 
 ) THE PIPE SYNTAX b a z ( ) | > l o l ( ) | > b a r ( ) | > f o o ( )
  21. WAIT!

  22. OTP OPEN TELECOM PLATFORM

  23. OTP is actually a bundle that includes Erlang, a database

    (Mnesia), and an innumerable number of libraries It also defines a structure for your applications THERE IS A LOT TO LEARN
  24. SOME OTP DEFINITIONS OTP defines systems in terms of hierarchies

    of applications An application consists of one or more processes These processes follow one of a small number of OTP conventions, called behaviors
  25. THE SERVER BEHAVIOR

  26. GENSERVER When we write an OTP server, we write a

    module containing one or more callback functions with standard names init(start_arguments) handle_call(request, from, state) handle_cast(request, state) handle_info(info, state) terminate(reason, state) code_change(from_version, state, extra) format_status(reason, [pdict, state])
  27. CREATE A NEW PROJECT $ m i x n e

    w s t a c k * c r e a t i n g R E A D M E . m d * c r e a t i n g . g i t i g n o r e * c r e a t i n g m i x . e x s * c r e a t i n g l i b * c r e a t i n g l i b / s t a c k . e x * c r e a t i n g l i b / s t a c k * c r e a t i n g t e s t * c r e a t i n g t e s t / t e s t _ h e l p e r . e x s * c r e a t i n g t e s t / s t a c k _ t e s t . e x s
  28. lib/stack/server.ex d e f m o d u l e

    S t a c k . S e r v e r d o u s e G e n S e r v e r # P u b l i c A P I d e f s t a r t _ l i n k ( s t a c k ) d o G e n S e r v e r . s t a r t _ l i n k ( _ _ M O D U L E _ _ , s t a c k , n a m e : _ _ M O D U L E _ _ ) e n d d e f p o p d o G e n S e r v e r . c a l l ( _ _ M O D U L E _ _ , : p o p ) e n d d e f p u s h ( v a l u e ) d o G e n S e r v e r . c a s t ( _ _ M O D U L E _ _ , { : p u s h , v a l u e } ) e n d . . .
  29. . . . # G e n S e r

    v e r i m p l e m e n t a t i o n d e f h a n d l e _ c a l l ( : p o p , _ f r o m , [ h e a d | t a i l ] ) d o { : r e p l y , h e a d , t a i l } e n d d e f h a n d l e _ c a s t ( { : p u s h , v a l u e } , s t a c k ) d o { : n o r e p l y , [ v a l u e | s t a c k ] } e n d e n d
  30. An OTP GenServer is just a regular Elixir process The

    GenServer behavior defines a message loop internally and maintains a state variable. That message loop then calls out to various functions that we define in our server module
  31. THE SUPERVISOR BEHAVIOR

  32. the Elixir way says not to worry much about code

    that crashes; instead, make sure the overall application keeps running
  33. SUPERVISORS AND WORKERS An Elixir supervisor has just one purpose:

    it manages one or more worker processes
  34. NEW PROJECT! let's create a new project with a supervisor

    $ m i x n e w - - s u p s t a c k _ s u p * c r e a t i n g R E A D M E . m d * c r e a t i n g . g i t i g n o r e * c r e a t i n g m i x . e x s * c r e a t i n g c o n f i g * c r e a t i n g c o n f i g / c o n f i g . e x s * c r e a t i n g l i b * c r e a t i n g l i b / s t a c k _ s u p . e x * c r e a t i n g t e s t * c r e a t i n g t e s t / t e s t _ h e l p e r . e x s * c r e a t i n g t e s t / s t a c k _ s u p _ t e s t . e x s
  35. stack_sup/lib/stack_sup.ex d e f m o d u l e

    S t a c k S u p d o u s e A p p l i c a t i o n d e f s t a r t ( _ t y p e , _ a r g s ) d o i m p o r t S u p e r v i s o r . S p e c , w a r n : f a l s e c h i l d r e n = [ # W o r k e r s a n d c h i l d s u p e r v i s o r s t o b e s u p e r v i s e d w o r k e r ( S t a c k S u p . S e r v e r , [ [ 1 , 2 , 3 ] ] ) , ] o p t s = [ s t r a t e g y : : o n e _ f o r _ o n e , n a m e : S t a c k S u p . S u p e r v i s o r ] S u p e r v i s o r . s t a r t _ l i n k ( c h i l d r e n , o p t s ) e n d e n d
  36. SUPERVISION TREE

  37. lib/stack_sup/supervisor.ex . . . d e f s t a

    r t _ l i n k ( i n i t i a l ) d o r e s u l t = { : o k , p i d } = S u p e r v i s o r . s t a r t _ l i n k ( _ _ M O D U L E _ _ , i n i t i a l ) s t a r t _ w o r k e r s ( p i d , i n i t i a l ) r e s u l t e n d d e f s t a r t _ w o r k e r s ( s u p , i n i t i a l ) d o { : o k , s t a s h } = S u p e r v i s o r . s t a r t _ c h i l d ( s u p , w o r k e r ( S t a c k S u p . S t a s h , [ i n i t i a l ] ) ) S u p e r v i s o r . s t a r t _ c h i l d ( s u p , s u p e r v i s o r ( S t a c k S u p . S u b S u p e r v i s o r , [ s t a s h ] ) ) e n d d e f i n i t ( _ ) d o s u p e r v i s e [ ] , s t r a t e g y : : o n e _ f o r _ o n e e n d e n d
  38. lib/stack_sup/subsupervisor.ex d e f m o d u l e

    S t a c k S u p . S u b S u p e r v i s o r d o u s e S u p e r v i s o r d e f s t a r t _ l i n k ( s t a s h _ p i d ) d o { : o k , _ p i d } = S u p e r v i s o r . s t a r t _ l i n k ( _ _ M O D U L E _ _ , s t a s h _ p i d ) e n d d e f i n i t ( s t a s h _ p i d ) d o c h i l d _ p r o c e s s e s = [ w o r k e r ( S t a c k S u p . S e r v e r , [ s t a s h _ p i d ] ) ] s u p e r v i s e c h i l d _ p r o c e s s e s , s t r a t e g y : : o n e _ f o r _ o n e e n d e n d
  39. SUPERVISORS ARE THE HEART OF RELIABILITY

  40. THAT'S ALL!