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

Generating Power with Yield

Generating Power with Yield

My talk for the Nashville PHP Users Group August 2013 meeting.

Jason Myers

August 11, 2013
Tweet

More Decks by Jason Myers

Other Decks in Technology

Transcript

  1. Yield, a modern language love story Originally Proposed in 1995,

    the yield keyword became official via the RFP on June 20th 2013 with PHP 5.5. Generators Facebook said a Hip, Hop and Don't Stop, and did their own yield generators in HipHop PHP
  2. They are HEAVILY BASED off of Python, with a nod

    towards the Mozilla JS implementation and the await C# concept.
  3. PHP Iterator Interface I t e r a t o

    r e x t e n d s T r a v e r s a b l e { / * M e t h o d s * / a b s t r a c t p u b l i c m i x e d c u r r e n t ( v o i d ) a b s t r a c t p u b l i c s c a l a r k e y ( v o i d ) a b s t r a c t p u b l i c v o i d n e x t ( v o i d ) a b s t r a c t p u b l i c v o i d r e w i n d ( v o i d ) a b s t r a c t p u b l i c b o o l e a n v a l i d ( v o i d ) } For example checkout class ArrayIterator
  4. ArrayIterator Example $ f r u i t s =

    a r r a y ( " a p p l e " = > " y u m m y " , " o r a n g e " = > " a h y a , n i c e " , " g r a p e " = > " w o w , I l o v e i t ! " , " p l u m " = > " n a h , n o t m e " ) ; $ o b j = n e w A r r a y O b j e c t ( $ f r u i t s ) ; $ i t = $ o b j - > g e t I t e r a t o r ( ) ; e c h o " I t e r a t i n g o v e r : " . $ o b j - > c o u n t ( ) . " v a l u e s \ n " ; w h i l e ( $ i t - > v a l i d ( ) ) { e c h o $ i t - > k e y ( ) . " = " . $ i t - > c u r r e n t ( ) . " \ n " ; $ i t - > n e x t ( ) ; } I t e r a t i n g o v e r : 4 v a l u e s a p p l e = y u m m y o r a n g e = a h y a , n i c e g r a p e = w o w , I l o v e i t ! p l u m = n a h , n o t m e
  5. Generator a special routine that can be used to control

    the iteration behavior of a loop, and yields the values one at a time
  6. Performant? r a n g e ( 0 , 1

    0 0 0 0 0 0 ) Uses over 100MB of RAM
  7. Generator Version f u n c t i o n

    x r a n g e ( $ s t a r t , $ l i m i t , $ s t e p = 1 ) { i f ( $ s t a r t < $ l i m i t ) { i f ( $ s t e p < = 0 ) { t h r o w n e w L o g i c E x c e p t i o n ( ' S t e p m u s t b e + v e ' ) ; } f o r ( $ i = $ s t a r t ; $ i < = $ l i m i t ; $ i + = $ s t e p ) { y i e l d $ i ; } } e l s e { i f ( $ s t e p > = 0 ) { t h r o w n e w L o g i c E x c e p t i o n ( ' S t e p m u s t b e - v e ' ) ; } f o r ( $ i = $ s t a r t ; $ i > = $ l i m i t ; $ i + = $ s t e p ) { y i e l d $ i ; } } } uses less than 1KB!
  8. TL; DR f u n c t i o n

    x r a n g e ( $ m i n , $ m a x ) { f o r ( $ i = $ m i n ; $ i < $ m a x ; $ i + + ) { y i e l d $ i ; } }
  9. Sequences f u n c t i o n c

    o l l a t z ( $ v a l ) { y i e l d $ v a l ; w h i l e ( $ v a l ! = 1 ) { i f ( $ v a l % 2 = = 0 ) { $ v a l / = 2 ; } e l s e { $ v a l = 3 * $ v a l + 1 ; } y i e l d $ v a l ; } } f o r e a c h ( c o l l a t z ( 1 1 ) a s $ c ) { e c h o $ c , " " ; } 1 1 3 4 1 7 5 2 2 6 1 3 4 0 2 0 1 0 5 1 6 8 4 2 1
  10. Y U Only LOOPin? It will work for any function

    that takes an Iterator or a Traversable as argument $ a r r = i t e r a t o r _ t o _ a r r a y ( c o l l a t z ( 1 1 ) ) ;
  11. Transformations f u n c t i o n m

    u l t i p l y _ s e q u e n c e ( $ a , $ f a c ) { f o r e a c h ( $ a a s $ v a l ) { y i e l d $ v a l * $ f a c ; } } f u n c t i o n t o _ h t m l _ l i s t ( $ i n p u t ) { f o r e a c h ( $ i n p u t a s $ v a l ) { y i e l d " < l i > " . $ v a l . " < / l i > " ; } }
  12. Chaining f o r e a c h ( t

    o _ h t m l _ l i s t ( m u l t i p l y _ s e q u e n c e ( c o l l a t z ( 5 ) , 2 ) ) a s $ v a l ) { e c h o $ v a l , " \ n " ; } < l i > 1 0 < / l i > < l i > 3 2 < / l i > < l i > 1 6 < / l i > < l i > 8 < / l i > < l i > 4 < / l i > < l i > 2 < / l i >
  13. Selections f u n c t i o n s

    e l e c t _ p a t t e r n ( $ i n p u t , $ p a t t e r n ) { f o r e a c h ( $ i n p u t a s $ v a l ) { i f ( p r e g _ m a t c h ( $ p a t t e r n , $ v a l ) ) { y i e l d $ v a l ; } } }
  14. Breath In f u n c t i o n

    g e t L i n e s ( $ f i l e ) { $ f = f o p e n ( $ f i l e , ' r ' ) ; i f ( ! $ f ) { t h r o w n e w E x c e p t i o n ( ) ; } w h i l e ( $ l i n e = f g e t s ( $ f ) ) { y i e l d $ l i n e ; } f c l o s e ( $ f ) ; } f o r e a c h ( g e t L i n e s ( " s o m e F i l e " ) a s $ l i n e ) { d o S o m e t h i n g W i t h L i n e ( $ l i n e ) ; }
  15. Breath Out f u n c t i o n

    c r e a t e L o g ( $ f i l e ) { $ f = f o p e n ( $ f i l e , ' a ' ) ; w h i l e ( t r u e ) { $ l i n e = y i e l d ; f w r i t e ( $ f , $ l i n e ) ; } } $ l o g = c r e a t e L o g ( $ f i l e ) ; $ l o g - > s e n d ( " F i r s t " ) ; $ l o g - > s e n d ( " S e c o n d " ) ; $ l o g - > s e n d ( " T h i r d " ) ;
  16. Green Threads threads that are scheduled by a virtual machine

    (VM/interperter?) instead of natively by the underlying operating system
  17. f u n c t i o n s t

    e p 1 ( ) { $ f = f o p e n ( " f i l e . t x t " , ' r ' ) ; w h i l e ( $ l i n e = f g e t s ( $ f ) ) { p r o c e s s L i n e ( $ l i n e ) ; y i e l d t r u e ; } }
  18. f u n c t i o n s t

    e p 2 ( ) { $ f = f o p e n ( " f i l e 2 . t x t " , ' r ' ) ; w h i l e ( $ l i n e = f g e t s ( $ f ) ) { p r o c e s s L i n e ( $ l i n e ) ; y i e l d t r u e ; } }
  19. f u n c t i o n s t

    e p 3 ( ) { $ f = f s o c k o p e n ( " w w w . e x a m p l e . c o m " , 8 0 ) ; s t r e a m _ s e t _ b l o c k i n g ( $ f , f a l s e ) ; $ h e a d e r s = " G E T / H T T P / 1 . 1 \ r \ n " ; $ h e a d e r s . = " H o s t : w w w . e x a m p l e . c o m \ r \ n " ; $ h e a d e r s . = " C o n n e c t i o n : C l o s e \ r \ n \ r \ n " ; f w r i t e ( $ f , $ h e a d e r s ) ; $ b o d y = ' ' ; w h i l e ( ! f e o f ( $ f ) ) { $ b o d y . = f r e a d ( $ f , 8 1 9 2 ) ; y i e l d t r u e ; } p r o c e s s B o d y ( $ b o d y ) ; }
  20. f u n c t i o n r u

    n n e r ( a r r a y $ s t e p s ) { w h i l e ( t r u e ) { f o r e a c h ( $ s t e p s a s $ k e y = > $ s t e p ) { $ s t e p - > n e x t ( ) ; i f ( ! $ s t e p - > v a l i d ( ) ) { u n s e t ( $ s t e p s [ $ k e y ] ) ; } } i f ( e m p t y ( $ s t e p s ) ) r e t u r n ; } } r u n n e r ( a r r a y ( s t e p 1 ( ) , s t e p 2 ( ) , s t e p 3 ( ) ) ) ;
  21. c l a s s B u f f e

    r { p r o t e c t e d $ r e a d s , $ d a t a ; p u b l i c f u n c t i o n _ _ c o n s t r u c t ( ) { $ t h i s - > r e a d s = n e w S p l Q u e u e ( ) ; $ t h i s - > d a t a = n e w S p l Q u e u e ( ) ; } p u b l i c f u n c t i o n r e a d ( ) { i f ( $ t h i s - > d a t a - > i s E m p t y ( ) ) { $ d e f e r r e d = n e w \ R e a c t \ P r o m i s e \ D e f e r r e d ( ) ; $ t h i s - > r e a d s - > e n q u e u e ( $ d e f e r r e d - > r e s o l v e r ( ) ) ; r e t u r n $ d e f e r r e d - > p r o m i s e ( ) ; } e l s e { r e t u r n \ R e a c t \ P r o m i s e \ W h e n : : r e s o l v e ( $ t h i s - > d a t a - > d e q u e u e ( ) ) ; } } p u b l i c f u n c t i o n w r i t e ( $ s t r ) { i f ( $ t h i s - > r e a d s - > i s E m p t y ( ) ) { $ t h i s - > d a t a - > e n q u e u e ( $ s t r ) ; } e l s e { $ t h i s - > r e a d s - > d e q u e u e ( ) - > r e s o l v e ( $ s t r ) ; } } }
  22. f u n c t i o n p r

    i n t e r ( B u f f e r $ b u f f e r ) { w h i l e ( t r u e ) { $ v a l u e = ( y i e l d U t i l : : a s y n c ( $ b u f f e r - > r e a d ( ) ) ) ; e c h o " P r i n t e r : " , $ v a l u e , P H P _ E O L ; y i e l d U t i l : : a s y n c ( n e s t e d _ p r i n t e r ( $ b u f f e r ) ) ; } }
  23. f u n c t i o n n e

    s t e d _ p r i n t e r ( B u f f e r $ b u f f e r ) { f o r ( $ i = 0 ; $ i < 5 ; $ i + + ) { / / Y i e l d a p r o m i s e t a s k a n d w a i t f o r t h e r e s u l t - t h i s i s n o n - b l o c k i n g $ v a l u e = ( y i e l d U t i l : : a s y n c ( $ b u f f e r - > r e a d ( ) ) ) ; e c h o " N e s t e d p r i n t e r : " , $ v a l u e , P H P _ E O L ; } }
  24. $ b u f f e r = n e

    w B u f f e r ( ) ; $ s c h e d u l e r = n e w \ A s y n c \ S c h e d u l e r ( ) ; $ s c h e d u l e r - > a d d ( n e w \ A s y n c \ T a s k \ G e n e r a t o r T a s k ( p r i n t e r ( $ b u f f e r ) ) ) ; $ i = 0 ; $ s c h e d u l e r - > a d d ( n e w \ A s y n c \ T a s k \ R e c u r r i n g T a s k ( f u n c t i o n ( ) u s e ( $ b u f f e r , & $ i ) { $ b u f f e r - > w r i t e ( + + $ i ) ; } ) ) ; $ s c h e d u l e r - > r u n ( ) ; P r i n t e r : 1 N e s t e d p r i n t e r : 2 N e s t e d p r i n t e r : 3 N e s t e d p r i n t e r : 4 N e s t e d p r i n t e r : 5 N e s t e d p r i n t e r : 6 P r i n t e r : 7 N e s t e d p r i n t e r : 8 N e s t e d p r i n t e r : 9 N e s t e d p r i n t e r : 1 0 N e s t e d p r i n t e r : 1 1 N e s t e d p r i n t e r : 1 2 . . .
  25. $ l o o p = \ R e a

    c t \ E v e n t L o o p \ F a c t o r y : : c r e a t e ( ) ; $ s c h e d u l e r = n e w \ A s y n c \ S c h e d u l e r ( ) ; $ s c h e d u l e r - > a d d ( n e w \ A s y n c \ T a s k \ R e c u r r i n g T a s k ( [ $ l o o p , ' t i c k ' ] ) ) ; $ s c h e d u l e r - > r u n ( ) ;