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

Code as data (RubyConfBY 2019 edition)

Code as data (RubyConfBY 2019 edition)

Algorithms are typically encoded in code. Sometimes, however, letting non-developers modify algorithms can be beneficial — but for that, we'll have to move the implementation of the algorithm from code into data. Doing so yields a bunch of interesting advantages.

Imagine that you're implementing a complex algorithm that encapsulates some business process at your company. The business stakeholders are pleased, but sometimes come to you with questions, such as

Why is this calculation result so high?
Can you please tweak some factors in the algorithm?

One-off requests like these are probably fine, but occasionally they can be so numerous that you end up spending a significant amount of your time dealing with incoming requests. (You have more interesting stuff to do!) Ideally, business stakeholders themselves would be able to figure out why that calculation result is so high, and would be able to change the factors themselves.

The implementation of the algorithm is in code – and it is typically not feasible to let business stakeholders handle code. (They have more interesting stuff to do!) We can move the algorithm's implementation out of code and into data… and that yields us a bunch of interesting advantages.

Denis Defreyne

April 06, 2019
Tweet

More Decks by Denis Defreyne

Other Decks in Technology

Transcript

  1. $$$

  2. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour?

  3. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour? hard to calculate.

  4. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour? hard to calculate.
 * wait and see what the price turns out to be?
  5. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour? hard to calculate.
 * wait and see what the price turns out to be? risky.
  6. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour? hard to calculate. * wait and see what the price turns out to be? risky.
 * algorithm?
  7. Why do we need a pricing algorithm?
 
 * fixed

    price? unfair.
 * price per hour? hard to calculate. * wait and see what the price turns out to be? risky.
 * algorithm? yes!
  8. $$$

  9. $$$ * Business need to know
 why prices are the

    way they are
 
 
 
 
 

  10. $$$ * Business need to know
 why prices are the

    way they are
 * Developers need to be involved
 to implement new formulas
 
 

  11. $$$ * Business need to know
 why prices are the

    way they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 
 

  12. $$$ * Business need to know
 why prices are the

    way they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  13. class SumExpr def initialize(left, right) @left = left @right =

    right end end class ProductExpr def initialize(left, right) @left = left @right = right end end
  14. class SumExpr def initialize(left, right) @left = left @right =

    right end end class ProductExpr def initialize(left, right) @left = left @right = right end end class ConstantExpr def initialize(value) @value = value end end

  15. class SumExpr def initialize(left, right) @left = left @right =

    right end end class ProductExpr def initialize(left, right) @left = left @right = right end end class ConstantExpr def initialize(value) @value = value end end
 class VariableExpr def initialize(name) @name = name end end

  16. 
 
 params = { volume: 20, distance: 200, }

    price_formula.evaluate(params)
 
 4200
  17. class SumExpr def initialize(left, right) @left = left @right =

    right end def evaluate(params) @left.evaluate(params) + @right.evaluate(params) end end

  18. class ProductExpr def initialize(left, right) @left = left @right =

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

  19. 
 
 params = { volume: 20, distance: 200, }

    price_formula.evaluate(params)
 

  20. 
 
 params = { volume: 20, distance: 200, }

    price_formula.evaluate(params)
 
 4200
  21. + Z[> 4200 const Z[> 200 * Z[> 4000 var

    volume Z[> 20 var distance Z[> 200
  22. + Z[> 4200 const Z[> 200 * Z[> 4000 var

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

    volume Z[> 20 var distance Z[> 200 Node.new("+", 4200, [const_node, product_node]) Node.new("var volume", 20, [])
  24. class VariableExpr def initialize(name) @name = name end def evaluate(params)

    Node.new( "var #{@name}", params.fetch(@name), [], ) end end
  25. class SumExpr def initialize(left, right) @left = left @right =

    right end def evaluate(params) left_node = @left.evaluate(params) right_node = @right.evaluate(params) Node.new( '+', left_node.value + right_node.value, [left_node, right_node], ) end end
  26. class ProductExpr def initialize(left, right) @left = left @right =

    right end def evaluate(params) left_node = @left.evaluate(params) right_node = @right.evaluate(params) Node.new( '*', left_node.value * right_node.value, [left_node, right_node], ) end end
  27. puts price_formula.evaluate(params) + >?> 4200 const >?> 200 * >?>

    4000 var volume >?> 20 var distance >?> 200
  28. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  29. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  30. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  31. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  32. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  33. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  34. * Business need to know
 why prices are the way

    they are
 * Developers need to be involved
 to implement new formulas
 * Developers have no good way
 to verify new formulas
 * It is difficult
 to dry-run new formulas
  35. MORE BENEFITS: * Versioning & locking
 * Translate to Ruby

    * Translate to SQL
 * Compile with LLVM
  36. * It’s much easier to reason about data
 than to

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