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

    View Slide

  2. 2
    GitHub: lucasfcosta Twitter: lfernandescosta

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  16. 16
    OBJECT.* METHODS

    View Slide

  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

    View Slide

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

    View Slide

  19. isExtensible
    O B J E C T . * M E T H O D S
    isSealed
    isFrozen
    19
    Restricting
    Object
    Manipulation

    View Slide

  20. 20
    PROPERTY DESCRIPTORS

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  37. 37
    P R O P E R T Y D E S C R I P T O R S
    Lazy
    Properties basket

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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™

    View Slide

  45. 45
    Assertion
    P R O P E R T Y D E S C R I P T O R S

    View Slide

  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

    View Slide

  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’});

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  51. 51
    PROXIES

    View Slide

  52. P R O X I E S
    Object wrappers which allow
    us to intercept operations
    Proxies
    52

    View Slide

  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

    View Slide

  54. 54
    P R O X I E S

    View Slide

  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’ }

    View Slide

  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)

    View Slide

  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

    View Slide

  58. 58
    Safety constraints
    Invariants
    Preserves universality
    P R O X I E S

    View Slide

  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).

    View Slide

  60. 60
    Emulating Haskell’s
    Infinite Arrays
    Lazy properties
    Property access traps
    P R O X I E S

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  70. P R O X I E S
    70
    Emulating Haskell’s Infinite Arrays

    View Slide

  71. 71
    Property
    Suggestions
    Help your users figure out how
    to use your API properly
    P R O X I E S

    View Slide

  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!

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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']

    View Slide

  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']

    View Slide

  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']

    View Slide

  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)

    View Slide

  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’?"

    View Slide

  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

    View Slide

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

    View Slide

  83. P R O X I E S
    83
    Reflecting Operations
    Same interfaces!

    View Slide

  84. 84
    SYMBOLS

    View Slide

  85. S Y M B O L S
    A primitive type
    introduced in ES6.
    Symbols
    85

    View Slide

  86. 86
    S Y M B O L S
    Symbol symbol
    !==
    Primitive
    Global Function

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  92. 92
    S Y M B O L S
    propName
    'value'
    object
    Symbol(timestamp)
    1494201600
    Avoiding accidental
    assignments
    Object.getOwnPropertySymbols

    View Slide

  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

    View Slide

  94. 94
    WELL

    KNOWN

    SYMBOLS
    Well known symbols
    are used to drive the
    language’s native
    implementations.
    S Y M B O L S

    View Slide

  95. 95
    fluent instanceof AwesomeConf
    Symbol.hasInstance
    S Y M B O L S
    AwesomeConf[Symbol.instanceOf](fluent)

    View Slide

  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

    View Slide

  97. S Y M B O L S
    97

    View Slide

  98. 98
    THANK YOU
    # F l u e n t C o n f 2 0 1 7
    GitHub: lucasfcosta Twitter: lfernandescosta
    lucasfcosta.com

    View Slide