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.

Lucas Fernandes da Costa

June 23, 2017
Tweet

More Decks by Lucas Fernandes da Costa

Other Decks in Programming

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. 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
  3. 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
  4. 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
  5. 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
  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 Java
  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 JavaScript
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  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 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
  14. 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
  15. 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
  16. prevent Extensions O B J E C T . *

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

    E T H O D S isSealed isFrozen 19 Restricting Object Manipulation
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 37 P R O P E R T Y D

    E S C R I P T O R S Lazy Properties basket
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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™
  39. 45 Assertion P R O P E R T Y

    D E S C R I P T O R S
  40. 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’});
  41. 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
  42. 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
  43. 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
  44. P R O X I E S Object wrappers which

    allow us to intercept operations Proxies 52
  45. 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
  46. 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’ }
  47. 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)
  48. 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
  49. 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).
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 71 Property Suggestions Help your users figure out how to

    use your API properly P R O X I E S
  60. 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
  61. 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
  62. 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
  63. 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']
  64. 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']
  65. 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']
  66. 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)
  67. 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’?"
  68. 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
  69. P R O X I E S 82 Reflecting Operations

    Reflect[[trapName]](…args) get set has ownKeys
  70. S Y M B O L S A primitive type

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

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

    Symbol(‘description’) new denotes the creation of an object returns a symbol primitive
  73. 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
  74. 89 01 S Y M B O L S We

    need to add information to third party objects propName 'value' object Avoiding accidental assignments
  75. 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
  76. 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
  77. 92 S Y M B O L S propName 'value'

    object Symbol(timestamp) 1494201600 Avoiding accidental assignments Object.getOwnPropertySymbols
  78. 94 WELL
 KNOWN
 SYMBOLS Well known symbols are used to

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

    L S AwesomeConf[Symbol.instanceOf](fluent)
  80. 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
  81. 98 THANK YOU # F l u e n t

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