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

  2. $$$

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

    right end end class Product def initialize(left, right) @left = left @right = right end end
  4. 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
  5. 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
  6. class Sum def initialize(left, right) @left = left @right =

    right end def evaluate(input) @left.evaluate(input) + @right.evaluate(input) end end
  7. class Product def initialize(left, right) @left = left @right =

    right end def evaluate(input) @left.evaluate(input) * @right.evaluate(input) end end
  8. 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
  9. class Sum < AbstractExpr # … end class Product <

    AbstractExpr # … end class Constant < AbstractExpr # … end class Variable < AbstractExpr # … end
  10. Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)
 
 
 
 + UV>

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

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

    volume UV> 20 var distance UV> 200 Node.new("+", 4200, [const_node, product_node])
  13. + 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, [])
  14. class Variable < AbstractExpr def initialize(name) @name = name end

    def evaluate(input) Node.new( "var #{@name}", input.fetch(@name), [], ) end end
  15. 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
  16. 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
  17. 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
  18. puts price_formula.evaluate(input) + ./> 4200 const ./> 200 * ./>

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

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

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

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

  22. 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"]]
  23. * It’s much easier to reason about data
 than to

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