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 full-size slide

  2. 2
    GitHub: lucasfcosta Twitter: lfernandescosta

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

  16. 16
    OBJECT.* METHODS

    View full-size 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  20. 20
    PROPERTY DESCRIPTORS

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide

  52. 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 full-size slide

  53. 54
    P R O X I E S

    View full-size slide

  54. 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 full-size slide

  55. 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 full-size slide

  56. 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 full-size slide

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

    View full-size slide

  58. 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 full-size slide

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

    View full-size slide

  60. 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 full-size slide

  61. 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 full-size slide

  62. 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 full-size slide

  63. 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 full-size slide

  64. 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 full-size slide

  65. 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 full-size slide

  66. 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 full-size slide

  67. 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 full-size slide

  68. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  71. 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 full-size slide

  72. 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 full-size slide

  73. 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 full-size slide

  74. 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 full-size slide

  75. 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 full-size slide

  76. 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 full-size slide

  77. 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 full-size slide

  78. 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 full-size slide

  79. 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 full-size slide

  80. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  85. 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 full-size slide

  86. 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 full-size slide

  87. 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 full-size slide

  88. 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 full-size slide

  89. 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 full-size slide

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

    View full-size slide

  91. 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 full-size slide

  92. 94
    WELL

    KNOWN

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

    View full-size slide

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

    View full-size slide

  94. 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 full-size slide

  95. S Y M B O L S
    97

    View full-size slide

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

    View full-size slide