Affordances in Programming Languages

Affordances in Programming Languages

From Mountain West Ruby Conference 2014.

A good design communicates the intended use of an object. In the physical world, this communication is accomplished by “affordances”, as discussed by Donald Norman in “The Psychology of Everyday Things”.

Programming languages also have affordances, and they influence the kinds of solutions we develop. The more languages we know, the more we “expand our design space” so that we can come up with better solutions to the problems we face every day.

27204e228cc521c6cafed3c92b95184c?s=128

Randy Coulman

March 21, 2014
Tweet

Transcript

  1. 3/20/2014 Affordances http://localhost:9090/onepage 1/67 Affordances in Programming Languages Randy Coulman

    Principal Software Engineer http://randycoulman.com @randycoulman randycoulman
  2. 3/20/2014 Affordances http://localhost:9090/onepage 2/67 Satu Kyröläinen ­ http://www.satukyrolainen.com/affordances/

  3. 3/20/2014 Affordances http://localhost:9090/onepage 3/67 Satu Kyröläinen ­ http://www.satukyrolainen.com/affordances/

  4. 3/20/2014 Affordances http://localhost:9090/onepage 4/67 Affordance A quality of an object

    or environment that allows someone to perform an action.
  5. 3/20/2014 Affordances http://localhost:9090/onepage 5/67 Nicolas Nova ­ http://www.flickr.com/photos/nnova/2252222949/

  6. 3/20/2014 Affordances http://localhost:9090/onepage 6/67 William Lindeke ­ http://tcsidewalks.blogspot.com/2009/06/signs­of­times­14.html

  7. 3/20/2014 Affordances http://localhost:9090/onepage 7/67 Yoni Alter ­ http://www.yoniishappy.com/Tube­escalators

  8. 3/20/2014 Affordances http://localhost:9090/onepage 8/67 Affordances and Software

  9. 3/20/2014 Affordances http://localhost:9090/onepage 9/67 Amir Rajan (@amirrajan) Coding Out Loud

    ­ REST APIs series http://vimeo.com/channels/659338
  10. 3/20/2014 Affordances http://localhost:9090/onepage 10/67 Example Points Smalltalk ­> Ruby

  11. 3/20/2014 Affordances http://localhost:9090/onepage 11/67 c l a s s P

    o i n t d e f i n i t i a l i z e ( x , y ) @ x = x @ y = y e n d e n d P o i n t . n e w ( 3 , 4 )
  12. 3/20/2014 Affordances http://localhost:9090/onepage 12/67 http://images.cryhavok.org/d/25562­2/Polar+and+Cartesian+Bears.jpg

  13. 3/20/2014 Affordances http://localhost:9090/onepage 13/67 θ r sinθ r cosθ r

    x y http://upload.wikimedia.org/wikipedia/commons/7/78/Polar_to_cartesian.svg
  14. 3/20/2014 Affordances http://localhost:9090/onepage 14/67 c l a s s P

    o i n t d e f i n i t i a l i z e ( x , y ) @ x = x @ y = y e n d e n d P o i n t . n e w ( 3 , 4 )
  15. 3/20/2014 Affordances http://localhost:9090/onepage 15/67 P o i n t c

    l a s s > > x : a n X y : a Y ^ s e l f n e w i n i t i a l i z e X : a n X y : a Y P o i n t > > i n i t i a l i z e X : a n X y : a Y x : = a n X . y : = a Y P o i n t x : 3 y : 4
  16. 3/20/2014 Affordances http://localhost:9090/onepage 16/67 P o i n t c

    l a s s > > r : r a d i u s t h e t a : a n g l e I n R a d i a n s ^ s e l f x : r a d i u s * a n g l e I n R a d i a n s c o s y : r a d i u s * a n g l e I n R a d i a n s s i n P o i n t r : 5 t h e t a : 0 . 9 2 7 2 9 5
  17. 3/20/2014 Affordances http://localhost:9090/onepage 17/67 Affordance Named Constructors

  18. 3/20/2014 Affordances http://localhost:9090/onepage 18/67 c l a s s P

    o i n t d e f s e l f . x y ( x , y ) n e w ( x , y ) e n d d e f s e l f . p o l a r ( r , t h e t a ) x y ( r * M a t h . c o s ( t h e t a ) , r * M a t h . s i n ( t h e t a ) ) e n d p r i v a t e _ c l a s s _ m e t h o d : n e w # . . . r e s t s a m e a s b e f o r e e n d P o i n t . x y ( 3 , 4 ) P o i n t . p o l a r ( 5 , 0 . 9 2 7 2 9 5 )
  19. 3/20/2014 Affordances http://localhost:9090/onepage 19/67 Example Find/Detect Smalltalk ­> Ruby

  20. 3/20/2014 Affordances http://localhost:9090/onepage 20/67 # ( 2 4 6 8

    ) d e t e c t : [ : e a c h | e a c h o d d ] " U n h a n d l e d e x c e p t i o n : E l e m e n t N o t F o u n d "
  21. 3/20/2014 Affordances http://localhost:9090/onepage 21/67 [ 2 , 4 , 6

    , 8 ] . f i n d { | n | n . o d d ? } # = > n i l
  22. 3/20/2014 Affordances http://localhost:9090/onepage 22/67 # ( 2 4 6 8

    ) d e t e c t : [ : e a c h | e a c h o d d ] i f N o n e : [ # n o n e ] " # n o n e "
  23. 3/20/2014 Affordances http://localhost:9090/onepage 23/67 Affordance Multiple Blocks

  24. 3/20/2014 Affordances http://localhost:9090/onepage 24/67 [ 2 , 4 , 6

    , 8 ] . f i n d ( - > { : n o n e } ) { | n | n . o d d ? } # = > : n o n e
  25. 3/20/2014 Affordances http://localhost:9090/onepage 25/67 Linguistic Relativity a.k.a. The Sapir­Whorf Hypothesis

    "[T]he structure of a language affects the ways in which its respective speakers conceptualize their world ... or otherwise influences their cognitive processes." ­­ http://en.wikipedia.org/wiki/Linguistic_relativity
  26. 3/20/2014 Affordances http://localhost:9090/onepage 26/67 When Code Cries Cory Foy at

    SCNA 2012 http://vimeo.com/53986875 What does a language allow you to say? What does a language force you to say?
  27. 3/20/2014 Affordances http://localhost:9090/onepage 27/67 The Power and Philsophy of Ruby

    Matz at OSCON 2003 http://www.rubyist.net/~matz/slides/oscon2003/mgp00001.html "Languages are not only tools to communicate, but also tools to think."
  28. 3/20/2014 Affordances http://localhost:9090/onepage 28/67 Example Cleaning Up After Yourself C++

    ­> Ruby
  29. 3/20/2014 Affordances http://localhost:9090/onepage 29/67 i f ( ( e r

    r = S S L F r e e B u f f e r ( & h a s h C t x ) ) ! = 0 ) g o t o f a i l ; i f ( ( e r r = R e a d y H a s h ( & S S L H a s h S H A 1 , & h a s h C t x ) ) ! = 0 ) g o t o f a i l ; i f ( ( e r r = S S L H a s h S H A 1 . u p d a t e ( & h a s h C t x , & c l i e n t R a n d o m ) ) ! = g o t o f a i l ; i f ( ( e r r = S S L H a s h S H A 1 . u p d a t e ( & h a s h C t x , & s e r v e r R a n d o m ) ) ! = g o t o f a i l ; i f ( ( e r r = S S L H a s h S H A 1 . u p d a t e ( & h a s h C t x , & s i g n e d P a r a m s ) ) ! = g o t o f a i l ; g o t o f a i l ; i f ( ( e r r = S S L H a s h S H A 1 . f i n a l ( & h a s h C t x , & h a s h O u t ) ) ! = 0 ) g o t o f a i l ; / / . . . f a i l : S S L F r e e B u f f e r ( & s i g n e d H a s h e s ) ; S S L F r e e B u f f e r ( & h a s h C t x ) ; r e t u r n e r r ;
  30. 3/20/2014 Affordances http://localhost:9090/onepage 30/67 # i n c l u

    d e " s u p p o r t . h " # i n c l u d e < i o s t r e a m > v o i d f o o ( ) { R e s o u r c e * r e s o u r c e = a c q u i r e R e s o u r c e ( ) ; b a r ( r e s o u r c e ) ; i f ( b a z ( r e s o u r c e ) ! = 4 2 ) r e t u r n ; s t d : : c o u t < < " C o m p l e t e d s u c c e s s f u l l y ! " < < s t d : : e n d l ; r e l e a s e R e s o u r c e ( r e s o u r c e ) ; }
  31. 3/20/2014 Affordances http://localhost:9090/onepage 31/67 $ . / b r o

    k e n A c q u i r i n g r e s o u r c e C a u g h t e x c e p t i o n : o o p s !
  32. 3/20/2014 Affordances http://localhost:9090/onepage 32/67 # i n c l u

    d e " s u p p o r t . h " # i n c l u d e < i o s t r e a m > v o i d f o o ( ) { R e s o u r c e * r e s o u r c e = a c q u i r e R e s o u r c e ( ) ; t r y { b a r ( r e s o u r c e ) ; i f ( b a z ( r e s o u r c e ) = = 4 2 ) { s t d : : c o u t < < " C o m p l e t e d s u c c e s s f u l l y ! " < < s t d : : e n d l ; } } c a t c h ( s t d : : e x c e p t i o n & e ) { r e l e a s e R e s o u r c e ( r e s o u r c e ) ; t h r o w ; } r e l e a s e R e s o u r c e ( r e s o u r c e ) ; }
  33. 3/20/2014 Affordances http://localhost:9090/onepage 33/67 $ . / w o r

    d y A c q u i r i n g r e s o u r c e R e l e a s i n g r e s o u r c e C a u g h t e x c e p t i o n : o o p s !
  34. 3/20/2014 Affordances http://localhost:9090/onepage 34/67 # i n c l u

    d e " s u p p o r t . h " # i n c l u d e < i o s t r e a m > v o i d f o o ( ) { R e s o u r c e * r e s o u r c e = a c q u i r e R e s o u r c e ( ) ; t r y { b a r ( r e s o u r c e ) ; i f ( b a z ( r e s o u r c e ) = = 4 2 ) { s t d : : c o u t < < " C o m p l e t e d s u c c e s s f u l l y ! " < < s t d : : e n d l ; } } c a t c h ( s t d : : e x c e p t i o n & e ) { r e l e a s e R e s o u r c e ( r e s o u r c e ) ; t h r o w ; } r e l e a s e R e s o u r c e ( r e s o u r c e ) ; }
  35. 3/20/2014 Affordances http://localhost:9090/onepage 35/67

  36. 3/20/2014 Affordances http://localhost:9090/onepage 36/67 RAII Resource Acquisition Is Initialization Acquire

    resources in the constructor Release them in the destructor
  37. 3/20/2014 Affordances http://localhost:9090/onepage 37/67 # i n c l u

    d e " S a f e R e s o u r c e . h " # i n c l u d e " s u p p o r t . h " S a f e R e s o u r c e : : S a f e R e s o u r c e ( ) : r e s o u r c e ( a c q u i r e R e s o u r c e ( ) ) { } S a f e R e s o u r c e : : ~ S a f e R e s o u r c e ( ) { r e l e a s e R e s o u r c e ( r e s o u r c e ) ; } R e s o u r c e * S a f e R e s o u r c e : : g e t ( ) { r e t u r n r e s o u r c e ; }
  38. 3/20/2014 Affordances http://localhost:9090/onepage 38/67 # i n c l u

    d e " S a f e R e s o u r c e . h " # i n c l u d e " s u p p o r t . h " # i n c l u d e < i o s t r e a m > v o i d f o o ( ) { S a f e R e s o u r c e r e s o u r c e ; b a r ( r e s o u r c e . g e t ( ) ) ; i f ( b a z ( r e s o u r c e . g e t ( ) ) ! = 4 2 ) r e t u r n s t d : : c o u t < < " C o m p l e t e d s u c c e s s f u l l y ! " < < s t d : : e n d l ; }
  39. 3/20/2014 Affordances http://localhost:9090/onepage 39/67 $ . / r a i

    i A c q u i r i n g r e s o u r c e R e l e a s i n g r e s o u r c e C a u g h t e x c e p t i o n : o o p s !
  40. 3/20/2014 Affordances http://localhost:9090/onepage 40/67 Affordance Deterministic Destructors

  41. 3/20/2014 Affordances http://localhost:9090/onepage 41/67 Ruby doesn't have deterministic destructors. So

    what can we do instead?
  42. 3/20/2014 Affordances http://localhost:9090/onepage 42/67 Blocks!

  43. 3/20/2014 Affordances http://localhost:9090/onepage 43/67 c l a s s S

    a f e R e s o u r c e d e f s e l f . a c q u i r e r e s o u r c e = s e l f . n e w y i e l d r e s o u r c e e n s u r e r e s o u r c e . r e l e a s e e n d d e f i n i t i a l i z e p u t s " A c q u i r i n g r e s o u r c e " @ r e s o u r c e = O b j e c t . n e w e n d d e f r e l e a s e p u t s " R e l e a s i n g r e s o u r c e " @ r e s o u r c e = n i l e n d
  44. 3/20/2014 Affordances http://localhost:9090/onepage 44/67 r e q u i r

    e _ r e l a t i v e " s u p p o r t " r e q u i r e _ r e l a t i v e " s a f e _ r e s o u r c e " d e f f o o S a f e R e s o u r c e . a c q u i r e d o | r e s o u r c e | b a r ( r e s o u r c e ) r e t u r n u n l e s s b a z ( r e s o u r c e ) = = 4 2 p u t s " C o m p l e t e d s u c c e s s f u l l y ! " e n d e n d
  45. 3/20/2014 Affordances http://localhost:9090/onepage 45/67 $ r u b y d

    r i v e r . r b A c q u i r i n g r e s o u r c e R e l e a s i n g r e s o u r c e C a u g h t e x c e p t i o n : o o p s !
  46. 3/20/2014 Affordances http://localhost:9090/onepage 46/67 Example ImageReader Smalltalk ­> Ruby

  47. 3/20/2014 Affordances http://localhost:9090/onepage 47/67 I m a g e R

    e a d e r c l a s s > > f r o m F i l e : a F i l e n a m e | r e a d e r C l a s s i m a g e S t r e a m r e a d e r | i m a g e S t r e a m : = a F i l e n a m e r e a d S t r e a m b i n a r y . [ r e a d e r C l a s s : = s e l f r e a d e r C l a s s F o r : i m a g e S t r e a m . r e a d e r C l a s s i f N i l : [ ^ s e l f e r r o r : ' U n k n o w n i m a g e t y p e : ' , a F i l e n a m e a s S t r i n g ] . r e a d e r : = r e a d e r C l a s s o n : i m a g e S t r e a m ] e n s u r e : [ i m a g e S t r e a m c l o s e ] . ^ r e a d e r
  48. 3/20/2014 Affordances http://localhost:9090/onepage 48/67 I m a g e R

    e a d e r c l a s s > > r e a d e r C l a s s F o r : i m a g e S t r e a m ^ s e l f s u b c l a s s e s d e t e c t : [ : e a c h C l a s s | i m a g e S t r e a m r e s e t . [ e a c h C l a s s c a n R e a d : i m a g e S t r e a m ] e n s u r e : [ i m a g e S t r e a m r e s e t ] ] i f N o n e : [ n i l ]
  49. 3/20/2014 Affordances http://localhost:9090/onepage 49/67 Affordance Subclass Iteration

  50. 3/20/2014 Affordances http://localhost:9090/onepage 50/67 c l a s s I

    m a g e R e a d e r d e f s e l f . r e a d ( f i l e n a m e ) F i l e . o p e n ( f i l e n a m e , " r b " ) d o | i o | r e a d e r _ c l a s s = f i n d _ r e a d e r _ c l a s s ( i o ) r a i s e " U n k n o w n i m a g e t y p e : # { f i l e n a m e } " u n l e s s r e a d e r _ c l a s s r e a d e r _ c l a s s . n e w ( i o ) e n d e n d # . . . e n d
  51. 3/20/2014 Affordances http://localhost:9090/onepage 51/67 c l a s s I

    m a g e R e a d e r # . . . d e f s e l f . f i n d _ r e a d e r _ c l a s s ( i o ) s u b c l a s s e s . f i n d { | r e a d e r | b e g i n i o . r e w i n d r e a d e r . c a n _ r e a d ? ( i o ) e n s u r e i o . r e w i n d e n d } e n d # . . . e n d
  52. 3/20/2014 Affordances http://localhost:9090/onepage 52/67 c l a s s I

    m a g e R e a d e r # . . . d e f s e l f . i n h e r i t e d ( s u b c l a s s ) s u b c l a s s e s < < s u b c l a s s e n d d e f s e l f . s u b c l a s s e s @ s u b c l a s s e s | | = [ ] e n d # . . . e n d
  53. 3/20/2014 Affordances http://localhost:9090/onepage 53/67 c l a s s B

    M P I m a g e R e a d e r < I m a g e R e a d e r d e f s e l f . c a n _ r e a d ? ( i o ) i o . r e a d ( 2 ) = = " B M " e n d d e f r e a d _ i m a g e p u t s " R e a d i n g B M P " e n d e n d
  54. 3/20/2014 Affordances http://localhost:9090/onepage 54/67 c l a s s J

    P G I m a g e R e a d e r < I m a g e R e a d e r d e f s e l f . c a n _ r e a d ? ( i o ) i o . r e a d ( 2 ) = = " \ x F F \ x D 8 " . b e n d d e f r e a d _ i m a g e p u t s " R e a d i n g J P G " e n d e n d
  55. 3/20/2014 Affordances http://localhost:9090/onepage 55/67 c l a s s P

    N G I m a g e R e a d e r < I m a g e R e a d e r d e f s e l f . c a n _ r e a d ? ( i o ) i o . r e a d ( 8 ) = = " \ x 8 9 P N G \ r \ n \ x 1 A \ n " . b e n d d e f r e a d _ i m a g e p u t s " R e a d i n g P N G " e n d e n d
  56. 3/20/2014 Affordances http://localhost:9090/onepage 56/67 r e q u i r

    e _ r e l a t i v e " i m a g e _ r e a d e r s " % w { b m p j p g p n g } . e a c h d o | e x t | I m a g e R e a d e r . r e a d ( " e x a m p l e . # { e x t } " ) e n d
  57. 3/20/2014 Affordances http://localhost:9090/onepage 57/67 $ r u b y s

    u b c l a s s e s . r b R e a d i n g B M P R e a d i n g J P G R e a d i n g P N G
  58. 3/20/2014 Affordances http://localhost:9090/onepage 58/67 Takeaways

  59. 3/20/2014 Affordances http://localhost:9090/onepage 59/67 Languages afford certain designs and inhibit

    others
  60. 3/20/2014 Affordances http://localhost:9090/onepage 60/67 Languages influence thought

  61. 3/20/2014 Affordances http://localhost:9090/onepage 61/67 Learning new languages will increase your

    "solution space"
  62. 3/20/2014 Affordances http://localhost:9090/onepage 62/67 Don't go too far

  63. 3/20/2014 Affordances http://localhost:9090/onepage 63/67 Want More? http://randycoulman.com/blog/categories/affordances/

  64. 3/20/2014 Affordances http://localhost:9090/onepage 64/67 Acknowledgements Key Technology (http://www.key.net/) Rogue.rb (@roguerb)

    Jen Myers (@antiheroine)
  65. 3/20/2014 Affordances http://localhost:9090/onepage 65/67 References The Design of Every Day

    Things ­ Donald Norman Coding Out Loud ­ Amir Rajan Linguistic Relativity ­ Wikipedia article When Code Cries ­ Cory Foy at SCNA 2012 The Power and Philosophy of Ruby ­ Matz at OSCON 2003
  66. 3/20/2014 Affordances http://localhost:9090/onepage 66/67 Questions?

  67. 3/20/2014 Affordances http://localhost:9090/onepage 67/67 Randy Coulman http://speakerrate.com/randycoulman http://www.slideshare.net/randycoulman http://randycoulman.com @randycoulman

    randycoulman