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

Code as data

Code as data

Given at RUG::B’s July 2018 edition (http://www.rug-b.de/topics/code-as-data-606).

Denis Defreyne

July 05, 2018
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

  1. CODE AS DATA
    DENIS DEFREYNE / RUG-.B / 2018-07-05

    View Slide

  2. View Slide

  3. $$$

    View Slide


  4. View Slide

  5. $$$

    View Slide

  6. def total_price
    200 + volume * distance
    end

    View Slide

  7. def total_price
    200 + volume * distance
    end
    sum

    View Slide

  8. def total_price
    200 + volume * distance
    end
    sum
    product

    View Slide

  9. def total_price
    200 + volume * distance
    end
    sum
    product
    variable

    View Slide

  10. def total_price
    200 + volume * distance
    end
    sum
    product
    constant
    variable

    View Slide

  11. View Slide

  12. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    end

    View Slide

  13. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    end
    class Product
    def initialize(left, right)
    @left = left
    @right = right
    end
    end

    View Slide

  14. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    end
    class Product
    def initialize(left, right)
    @left = left
    @right = right
    end
    end
    class Constant
    def initialize(value)
    @value = value
    end
    end

    View Slide

  15. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    end
    class Product
    def initialize(left, right)
    @left = left
    @right = right
    end
    end
    class Constant
    def initialize(value)
    @value = value
    end
    end
    class Variable
    def initialize(name)
    @name = name
    end
    end

    View Slide

  16. def price_formula
    Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Fvolume),
    Variable.new(Fdistance),
    )
    )
    end

    View Slide

  17. input = {
    volume: 20,
    distance: 200,
    }
    price_formula.evaluate(input)

    View Slide

  18. class Variable
    def initialize(name)
    @name = name
    end
    def evaluate(input)
    input.fetch(@name)
    end
    end

    View Slide

  19. class Constant
    def initialize(value)
    @value = value
    end
    def evaluate(_input)
    @value
    end
    end

    View Slide

  20. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    def evaluate(input)
    @left.evaluate(input) + @right.evaluate(input)
    end
    end

    View Slide

  21. class Product
    def initialize(left, right)
    @left = left
    @right = right
    end
    def evaluate(input)
    @left.evaluate(input) * @right.evaluate(input)
    end
    end

    View Slide

  22. def price_formula
    Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Fvolume),
    Variable.new(Fdistance),
    ),
    )
    end



    View Slide

  23. def price_formula
    Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Fvolume),
    Variable.new(Fdistance),
    )
    )
    end
    def price_formula
    Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)
    end

    View Slide

  24. class AbstractExpr
    def +(other)
    Sum.new(self, other)
    end
    def *(other)
    Product.new(self, other)
    end
    end

    View Slide

  25. class Sum < AbstractExpr
    # …
    end
    class Product < AbstractExpr
    # …
    end
    class Constant < AbstractExpr
    # …
    end
    class Variable < AbstractExpr
    # …
    end

    View Slide

  26. def price_formula
    Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)
    end

    View Slide

  27. THE POINT

    View Slide

  28. Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)








    View Slide

  29. Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)




    + UV> 4200
    const UV> 200
    * UV> 4000
    var volume UV> 20
    var distance UV> 200

    View Slide

  30. class Node
    def initialize(name, value, children)
    @name = name
    @value = value
    @children = children
    end
    end

    View Slide

  31. + UV> 4200
    const UV> 200
    * UV> 4000
    var volume UV> 20
    var distance UV> 200

    View Slide

  32. + UV> 4200
    const UV> 200
    * UV> 4000
    var volume UV> 20
    var distance UV> 200
    Node.new("+", 4200, [const_node, product_node])

    View Slide

  33. + UV> 4200
    const UV> 200
    * UV> 4000
    var volume UV> 20
    var distance UV> 200
    Node.new("+", 4200, [const_node, product_node])
    Node.new("var volume", 20, [])

    View Slide

  34. class Variable < AbstractExpr
    def initialize(name)
    @name = name
    end
    def evaluate(input)
    Node.new(
    "var #{@name}",
    input.fetch(@name),
    [],
    )
    end
    end

    View Slide

  35. class Constant
    def initialize(value)
    @value = value
    end
    def evaluate(_input)
    Node.new(
    'const',
    @value,
    [],
    )
    end
    end

    View Slide

  36. class Sum
    def initialize(left, right)
    @left = left
    @right = right
    end
    def evaluate(input)
    left_node = @left.evaluate(input)
    right_node = @right.evaluate(input)
    Node.new(
    '+',
    left_node.value + right_node.value,
    [left_node, right_node],
    )
    end
    end

    View Slide

  37. class Product
    def initialize(left, right)
    @left = left
    @right = right
    end
    def evaluate(input)
    left_node = @left.evaluate(input)
    right_node = @right.evaluate(input)
    Node.new(
    '*',
    left_node.value * right_node.value,
    [left_node, right_node],
    )
    end
    end

    View Slide

  38. class Node
    def to_s
    "#{@name} UV> #{@value}\n" +
    @children.map { |c| indent(c.to_s) }.join('')
    end
    private
    def indent(s)
    s.lines.map { |l| ' ' + l }.join('')
    end
    end

    View Slide

  39. puts price_formula.evaluate(input)






    View Slide

  40. puts price_formula.evaluate(input)
    + ./> 4200
    const ./> 200
    * ./> 4000
    var volume ./> 20
    var distance ./> 200

    View Slide

  41. puts price_formula.evaluate(input).value


    View Slide

  42. puts price_formula.evaluate(input).value


    4200

    View Slide

  43. + UV> 4200
    const UV> 200
    * UV> 4000
    var volume UV> 20
    var distance UV> 200

    View Slide

  44. +
    (= 4200)
    const
    (= 200)
    *
    (= 4000)
    var distance
    (= 200)
    var volume
    (= 20)

    View Slide

  45. IDEA: translate to SQL

    View Slide

  46. IDEA: compile with LLVM

    View Slide

  47. What about input?

    View Slide

  48. BACKEND

    View Slide

  49. BACKEND formula

    View Slide

  50. BACKEND
    PARSE +
    SERIALIZE
    formula

    View Slide

  51. PARSING:

    parse("200 + volume * distance")










    View Slide

  52. PARSING:

    parse("200 + volume * distance")
    D> Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Kvolume),
    Variable.new(Kdistance),
    )
    )




    View Slide

  53. SERIALIZING:
    formula =
    Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Fvolume),
    Variable.new(Fdistance),
    )
    )
    serialize(formula)

    View Slide

  54. SERIALIZING:
    formula =
    Sum.new(
    Constant.new(200),
    Product.new(
    Variable.new(Fvolume),
    Variable.new(Fdistance),
    )
    )
    serialize(formula)
    D> ["sum", ["constant", 200], ["product",
    ["var", "volume"], ["var", "distance"]]

    View Slide

  55. BACKEND
    PARSE +
    SERIALIZE
    formula

    View Slide

  56. BACKEND
    PARSE +
    SERIALIZE
    DESERIALIZE
    + UNPARSE
    formula

    View Slide

  57. formula

    View Slide

  58. formula A (stable)
    formula B (testing)

    View Slide

  59. formula A (old)
    formula B (stable)

    View Slide

  60. Is this over-engineering?

    View Slide

  61. TAKE-AWAYS

    View Slide

  62. * It’s much easier to reason about data

    than to reason about code.


    View Slide

  63. * It’s much easier to reason about data

    than to reason about code.
    * Try novel approaches; they can

    reveal new opportunities.

    View Slide

  64. View Slide