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

JavaScript Behind the Scenes: Meta Programming (FluentConf 2017)

JavaScript Behind the Scenes: Meta Programming (FluentConf 2017)

This talk has been presented at FluentConf 2017.
Infinite sequences, lazy properties and changing your program’s structure in runtime. Yes, JavaScript is that powerful. In this talk, I demonstrate how to solve problems in a smarter way and with creativity and readability by redefining how the language’s features work behind the scenes.

5a3b0043a07f45bba968c22b7e7bf296?s=128

Lucas Fernandes da Costa

June 23, 2017
Tweet

Transcript

  1. 1 JavaScript Behind The Scenes M E T A P

    R O G R A M M I N G GitHub: lucasfcosta Twitter: lfernandescosta lucasfcosta.com
  2. 2 GitHub: lucasfcosta Twitter: lfernandescosta

  3. 3 Why? 01 L e a r n h o

    w t o d e a l w i t h t h i r d - p a r t y c o d e 02 U n d e r s t a n d h o w t h e l a n g u a g e w o r k s b e h i n d t h e s c e n e s 03 S o l v e p r o b l e m s e l e g a n t l y a n d c r e a t i v e l y 3 J A V A S C R I P T B E H I N D T H E S C E N E S
  4. 4 What is meta programming? J A V A S

    C R I P T B E H I N D T H E S C E N E S
  5. program program program J A V A S C R

    I P T B E H I N D T H E S C E N E S
  6. T H I S I S M E T A

    P R O G R A M M I N G If you’re not having fun with what you’re doing then you’re doing it Wrong. F O C U S O N T H E W H Y ? But this is not exactly what we will talk about
  7. T H I S I S M E T A

    P R O G R A M M I N G If you’re not having fun with what you’re doing then you’re doing it Wrong. F O C U S O N T H E W H Y ? But this is not exactly what we will talk about Java
  8. T H I S I S M E T A

    P R O G R A M M I N G If you’re not having fun with what you’re doing then you’re doing it Wrong. F O C U S O N T H E W H Y ? But this is not exactly what we will talk about JavaScript
  9. JavaScript Java Java Meta Level Base Level J A V

    A S C R I P T B E H I N D T H E S C E N E S
  10. 10 Reflective Meta Programming base level same as meta level

    J A V A S C R I P T B E H I N D T H E S C E N E S
  11. reflective meta programming I N T R O S P

    E C T I O N S E L F M O D I F I C AT I O N I N T E R C E S S I O N 11
  12. J A V A S C R I P T

    B E H I N D T H E S C E N E S 12 Defines the structure of objects Meta Object Protocol Defines the behavior of objects
  13. 13 YO U R T I T L E H

    E R E There are many variations of passages of Lorem. YO U R T I T L E H E R E There are many variations of passages of Lorem. YO U R T I T L E H E R E There are many variations of passages of Lorem. meta object protocol
  14. YO U R T I T L E H E

    R E There are many variations of passages of Lorem. YO U R T I T L E H E R E There are many variations of passages of Lorem. YO U R T I T L E H E R E There are many variations of passages of Lorem. meta object protocol J A V A S C R I P T B E H I N D T H E S C E N E S ecma-international.org/ecma-262 14
  15. J A V A S C R I P T

    B E H I N D T H E S C E N E S ecma-international.org/ecma-262
  16. 16 OBJECT.* METHODS

  17. O b j e c t . k e y

    s Object.* Methods O b j e c t . a s s i g n O b j e c t . h a s O w n P r o p e r t y O b j e c t . c r e a t e O B J E C T . * M E T H O D S 17 O b j e c t . g e t O w n P r o p e r t y N a m e s
  18. prevent Extensions O B J E C T . *

    M E T H O D S seal freeze 18 Restricting Object Manipulation
  19. isExtensible O B J E C T . * M

    E T H O D S isSealed isFrozen 19 Restricting Object Manipulation
  20. 20 PROPERTY DESCRIPTORS

  21. P R O P E R T Y D E

    S C R I P T O R S Objects that describe properties’ characteristics. Property Descriptors 21
  22. 22 Property Descriptors' Properties Describe properties’ characteristics P R O

    P E R T Y D E S C R I P T O R S Property
  23. 23 Property Descriptors' Properties Describe properties’ characteristics P R O

    P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  24. 24 value The real value of a property P R

    O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  25. 25 enumerable Indicates if this key shows up when enumerating

    properties P R O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  26. 26 writable Indicates if we can write to this property

    by using the assignment operator P R O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  27. 27 configurable Indicates if we can change this properties’ descriptor

    P R O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  28. 28 get A function to be called on property access

    P R O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  29. 29 set A function to be called when assigning a

    value to a property by using the assignment operator P R O P E R T Y D E S C R I P T O R S Property value enumerable get set configurable writable
  30. 30 Object.defineProperty P R O P E R T Y

    N A M E O B J E C T D E S C R I P T O R P R O P E R T Y D E S C R I P T O R S
  31. 31 P R O P E R T Y D

    E S C R I P T O R S O B J E C T P R O P E R T Y N A M E Object.getOwnPropertyDescriptor
  32. 32 P R O P E R T Y D

    E S C R I P T O R S O B J E C T getPrototypeOf P R O T O T Y P E P R O P E R T Y getOwnPropertyDescriptor Retrieving Property Descriptors
  33. 33 Properties calculated only when needed. LAZY PROPERTIES P R

    O P E R T Y D E S C R I P T O R S
  34. 34 bananas: 2
 apples: 3
 weight: 500 P R O

    P E R T Y D E S C R I P T O R S Lazy Properties basket
  35. 35 bananas: 3
 apples: 3
 weight: 600 P R O

    P E R T Y D E S C R I P T O R S Lazy Properties basket
  36. 36 bananas: 3
 apples: 4
 weight: 700 P R O

    P E R T Y D E S C R I P T O R S Lazy Properties too many assignments to the weight property basket
  37. 37 P R O P E R T Y D

    E S C R I P T O R S Lazy Properties basket
  38. 38 bananas: 3
 apples: 3
 weight: [getter] P R O

    P E R T Y D E S C R I P T O R S Lazy Properties basket
  39. 39 bananas: 3
 apples: 3
 weight: [getter] P R O

    P E R T Y D E S C R I P T O R S Lazy Properties 01 b a s k e t .w e i g h t basket
  40. 40 bananas: 3
 apples: 3
 weight: [getter] P R O

    P E R T Y D E S C R I P T O R S Lazy Properties 01 b a s k e t .w e i g h t 02 [ g e t t e r] i s c a l l e d basket
  41. 41 bananas: 3
 apples: 3
 weight: [getter] P R O

    P E R T Y D E S C R I P T O R S Lazy Properties 01 b a s k e t .w e i g h t 02 [ g e t t e r] i s c a l l e d 03 basket c a l c u l a t e s t h e w e i g h t a n d r e t u r n s 6 0 0
  42. 42 FLUID APIS Assertion Library for Node & Browsers P

    R O P E R T Y D E S C R I P T O R S
  43. 43 FLUID APIS expect('word').to.be.a('string'); expect([1, 2, 3]).to.have.length(3); P R O

    P E R T Y D E S C R I P T O R S
  44. 44 FLUID APIS expect('word').to.be.a('string'); expect([1, 2, 3]).to.have.length(3); P R O

    P E R T Y D E S C R I P T O R S the most obvious thing™
  45. 45 Assertion P R O P E R T Y

    D E S C R I P T O R S
  46. 46 instanceof above empty include equal property Assertion P R

    O P E R T Y D E S C R I P T O R S
  47. 47 P R O P E R T Y D

    E S C R I P T O R S expect(person).to.be.deep.equal({ name: ‘John’});
  48. 48 wrap personObj into an Assertion object P R O

    P E R T Y D E S C R I P T O R S expect(person) returns this
  49. 49 be to deep r e t u r n

    s t h i s s e t s t h e d e e p f l a g t o t r u e r e t u r n s t h i s P R O P E R T Y D E S C R I P T O R S r e t u r n s t h i s
  50. 50 equal({ name: ‘John’ }) c o m p a

    r e s t h e w r a p p e d o b j e c t t o t h e o b j e c t p a s s e d t o i t u s i n g d e e p e q u a l i t y c h e c k s i f t h e d e e p f l a g i s s e t i n t h e A s s e r t i o n o b j e c t P R O P E R T Y D E S C R I P T O R S
  51. 51 PROXIES

  52. P R O X I E S Object wrappers which

    allow us to intercept operations Proxies 52
  53. 53 A proxy’s composition handler [traps] target [wrappedObj] Proxies are

    transparent Handlers access the target so they won’t trigger their own traps P R O X I E S proxy
  54. 54 P R O X I E S

  55. P R O X I E S 55 01 A

    handler has traps A target is the object to be wrapped How Proxies work handler [get] target { name: ‘John’ }
  56. P R O X I E S 56 02 Wrap

    the target and handler into a Proxy 03 Access the propName property handler [get] target { name: ‘John’ } proxy const p = new Proxy(target, handler)
  57. P R O X I E S 57 04 Handler’s

    get trap gets called 05 handler [get] target { name: ‘John’ } proxy handler.get(target, propName) handler.get(target, propName) is the result of this access
  58. 58 Safety constraints Invariants Preserves universality P R O X

    I E S
  59. 59 handler [isExtensible] target [wrappedObj] P R O X I

    E S proxy Invariants Object.isExtensible(proxy) must return the same value as Object.isExtensible(target).
  60. 60 Emulating Haskell’s Infinite Arrays Lazy properties Property access traps

    P R O X I E S
  61. P R O X I E S 61 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[0] u n d e f i n e d
  62. P R O X I E S 62 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[0] u n d e f i n e d
  63. P R O X I E S 63 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[0] u n d e f i n e d
  64. P R O X I E S 64 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[0] u n d e f i n e d
  65. P R O X I E S 65 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[3] u n d e f i n e d
  66. P R O X I E S 66 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[3] u n d e f i n e d
  67. P R O X I E S 67 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[3] u n d e f i n e d
  68. P R O X I E S 68 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[3] c a l c u l a t e s t h e v a l u e f o r i n d e x 3 u n d e f i n e d
  69. P R O X I E S 69 Emulating Haskell’s

    Infinite Arrays 0 target 0 handler 1 2 2 4 3 [ g e t ] evens[3] 6 c a l c u l a t e s t h e v a l u e f o r i n d e x 3 6
  70. P R O X I E S 70 Emulating Haskell’s

    Infinite Arrays
  71. 71 Property Suggestions Help your users figure out how to

    use your API properly P R O X I E S
  72. 72 PROPERTY SUGGESTIONS expect(myVar).to.be.ture; P R O P E R

    T Y D E S C R I P T O R S typo!
  73. 73 expect(myVar).to.be.ture; P R O P E R T Y

    D E S C R I P T O R S typo! Returns undefined PROPERTY SUGGESTIONS
  74. 74 expect(myVar).to.be.ture; P R O P E R T Y

    D E S C R I P T O R S typo! Does not trigger [get] PROPERTY SUGGESTIONS
  75. 75 expect(myVar).to.be.ture; P R O P E R T Y

    D E S C R I P T O R S typo! No assertions run! PROPERTY SUGGESTIONS
  76. P R O X I E S 76 n a

    m e J o h n a g e h e i g h t 1 8 0 i s D e v [ g e t ] Property suggestions target handler 2 8 t r u e person['nsme']
  77. P R O X I E S 77 n a

    m e J o h n a g e h e i g h t 1 8 0 i s D e v [ g e t ] Property suggestions target handler 2 8 t r u e person['nsme']
  78. P R O X I E S 78 n a

    m e J o h n a g e h e i g h t 1 8 0 i s D e v [ g e t ] Property suggestions target handler 2 8 t r u e person['nsme']
  79. P R O X I E S 79 n a

    m e J o h n a g e h e i g h t 1 8 0 i s D e v [ g e t ] Property suggestions target handler 2 8 t r u e person['nsme'] levenshtein(propName, target)
  80. P R O X I E S 80 n a

    m e J o h n a g e h e i g h t 1 8 0 i s D e v [ g e t ] Property suggestions target handler 2 8 t r u e person['nsme'] levenshtein(propName, target) “Did you mean ‘name’?"
  81. J A V A S C R I P T

    B E H I N D T H E S C E N E S 81 A functional alternative to keywords Reflect More meaningful return values
  82. P R O X I E S 82 Reflecting Operations

    Reflect[[trapName]](…args) get set has ownKeys
  83. P R O X I E S 83 Reflecting Operations

    Same interfaces!
  84. 84 SYMBOLS

  85. S Y M B O L S A primitive type

    introduced in ES6. Symbols 85
  86. 86 S Y M B O L S Symbol symbol

    !== Primitive Global Function
  87. S Y M B O L S 87 new Symbol(‘description’)

    Symbol(‘description’) new denotes the creation of an object returns a symbol primitive
  88. S Y M B O L S Primitive symbols are

    unique. 88 Symbol('id') !== Symbol('id') Symbol.for('id') === Symbol.for(‘id') Global Registry Local
  89. 89 01 S Y M B O L S We

    need to add information to third party objects propName 'value' object Avoiding accidental assignments
  90. 90 S Y M B O L S 02 propName

    'value' timestamp object 1389398400 markTimestamp(object) adds a property indexed by timestamp to this object
  91. 91 03 S Y M B O L S Someone

    not aware of this can assign to the timestamp property accidentally and break our program propName 'value' object object.timestamp = 1494201600 timestamp 1494201600
  92. 92 S Y M B O L S propName 'value'

    object Symbol(timestamp) 1494201600 Avoiding accidental assignments Object.getOwnPropertySymbols
  93. Symbols are all about Reflection within implementation K E I

    T H C I R K E L S Y M B O L S 93
  94. 94 WELL
 KNOWN
 SYMBOLS Well known symbols are used to

    drive the language’s native implementations. S Y M B O L S
  95. 95 fluent instanceof AwesomeConf Symbol.hasInstance S Y M B O

    L S AwesomeConf[Symbol.instanceOf](fluent)
  96. 96 Well Known Symbols S Y M B O L

    S S y m b o l . i t e r a t o r S y m b o l . h a s I n s t a n c e S y m b o l .t o P r i m i t i v e
  97. S Y M B O L S 97

  98. 98 THANK YOU # F l u e n t

    C o n f 2 0 1 7 GitHub: lucasfcosta Twitter: lfernandescosta lucasfcosta.com