Denis Defreyne
July 05, 2018
130

# Code as data

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

July 05, 2018

## Transcript

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

constant variable
10. ### class Sum def initialize(left, right) @left = left @right =

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

right end end class Product def initialize(left, right) @left = left @right = right end end
12. ### 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
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 class Constant def initialize(value) @value = value end end class Variable def initialize(name) @name = name end end

16. ### class Variable def initialize(name) @name = name end def evaluate(input)

input.fetch(@name) end end
17. ### class Constant def initialize(value) @value = value end def evaluate(_input)

@value end end
18. ### class Sum def initialize(left, right) @left = left @right =

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

right end def evaluate(input) @left.evaluate(input) * @right.evaluate(input) end end

21. ### 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
22. ### class AbstractExpr def +(other) Sum.new(self, other) end def *(other) Product.new(self,

other) end end
23. ### class Sum < AbstractExpr # … end class Product <

AbstractExpr # … end class Constant < AbstractExpr # … end class Variable < AbstractExpr # … end

27. ### Constant.new(200) + Variable.new(Fvolume) * Variable.new(Fdistance)        + UV>

4200 const UV> 200 * UV> 4000 var volume UV> 20 var distance UV> 200
28. ### class Node def initialize(name, value, children) @name = name @value

= value @children = children end end
29. ### + UV> 4200 const UV> 200 * UV> 4000 var

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

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

def evaluate(input) Node.new( "var #{@name}", input.fetch(@name), [], ) end end
33. ### class Constant def initialize(value) @value = value end def evaluate(_input)

Node.new( 'const', @value, [], ) end end
34. ### 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
35. ### 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
36. ### 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

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

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

41. ### + UV> 4200 const UV> 200 * UV> 4000 var

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

distance (= 200) var volume (= 20)

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

Variable.new(Kvolume), Variable.new(Kdistance), ) )
51. ### SERIALIZING: formula = Sum.new( Constant.new(200), Product.new( Variable.new(Fvolume), Variable.new(Fdistance), ) )

serialize(formula)
52. ### 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"]]