Code as data

Code as data

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

Be732ee41fd3038aa98a0a7e7b7be081?s=128

Denis Defreyne

July 05, 2018
Tweet

Transcript

  1. 2.
  2. 3.

    $$$

  3. 5.

    $$$

  4. 11.
  5. 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
  6. 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
  7. 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
  8. 20.

    class Sum def initialize(left, right) @left = left @right =

    right end def evaluate(input) @left.evaluate(input) + @right.evaluate(input) end end
  9. 21.

    class Product def initialize(left, right) @left = left @right =

    right end def evaluate(input) @left.evaluate(input) * @right.evaluate(input) end end
  10. 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
  11. 25.

    class Sum < AbstractExpr # … end class Product <

    AbstractExpr # … end class Constant < AbstractExpr # … end class Variable < AbstractExpr # … end
  12. 27.
  13. 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
  14. 31.

    + UV> 4200 const UV> 200 * UV> 4000 var

    volume UV> 20 var distance UV> 200
  15. 32.

    + UV> 4200 const UV> 200 * UV> 4000 var

    volume UV> 20 var distance UV> 200 Node.new("+", 4200, [const_node, product_node])
  16. 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, [])
  17. 34.

    class Variable < AbstractExpr def initialize(name) @name = name end

    def evaluate(input) Node.new( "var #{@name}", input.fetch(@name), [], ) end end
  18. 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
  19. 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
  20. 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
  21. 40.

    puts price_formula.evaluate(input) + ./> 4200 const ./> 200 * ./>

    4000 var volume ./> 20 var distance ./> 200
  22. 43.

    + UV> 4200 const UV> 200 * UV> 4000 var

    volume UV> 20 var distance UV> 200
  23. 44.

    + (= 4200) const (= 200) * (= 4000) var

    distance (= 200) var volume (= 20)
  24. 48.
  25. 52.

    PARSING:
 parse("200 + volume * distance") D> Sum.new( Constant.new(200), Product.new(

    Variable.new(Kvolume), Variable.new(Kdistance), ) )
 
 
 

  26. 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"]]
  27. 57.
  28. 63.

    * It’s much easier to reason about data
 than to

    reason about code. * Try novel approaches; they can
 reveal new opportunities.
  29. 64.