Correctness through simplicity<br />Ulvi K. Guliyev<br />
“…domain of dependable software engineering boils down less to money and more to ethics. Its about your duty as a software...
How do we think about computation?<br />
∞<br />∞<br />void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps = new List<Burp>()...
How do we change thinking modality?<br />We are computers<br />Technology is secondary<br />Intuition and ingenuity<br />S...
Roadmap to dependable software<br />Targeted at imperative programmers<br />Focus on reducing code complexity<br />Step by...
Step 1. Procedural decomposition<br />
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(...
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(...
Step 2. Single responsibility<br />
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(...
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(...
Step 3. Semantic regression<br />
Code beacons<br />Patterns in code<br />Sequences of imperative instructions<br />Describe how to compute and not computat...
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(...
void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />	_burps = ProcessFood(dishes, bob);<br ...
Step 4. Controlled side-effects<br />
Mutable type<br />void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />	_burps = ProcessFood...
void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />	_burps = ProcessFood(dishes, bo...
Step 6. Functional composition<br />
Non-compositional<br />void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />	_burps =...
void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />Burp(ProcessFood(dishes, bob));<...
Step 7. Computational abstraction<br />
IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Ite...
IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d =...
Step 8. Constrained state space<br />
∞<br />∞<br />IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes....
IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />Contract.Requires(dishes.Any...
Upcoming SlideShare
Loading in …5
×

Correctness through simplicity

319 views
287 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
319
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Correctness through simplicity

  1. 1. Correctness through simplicity<br />Ulvi K. Guliyev<br />
  2. 2. “…domain of dependable software engineering boils down less to money and more to ethics. Its about your duty as a software engineer to ensure that system is of as higher quality as possible.” <br />Prof. Joseph Kiniry (Software Development Group) <br />
  3. 3. How do we think about computation?<br />
  4. 4. ∞<br />∞<br />void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps = new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp;<br />switch(foodItem.Kind){<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />if(burp != null)<br /> _burps.Add(burp); <br /> }<br />else{<br />Environment.Spit(foodItem, bob);<br />}<br /> }<br />}<br />foreach(var burp in _burps){<br />Environment.Release(burp);<br />}<br />}<br />Branch<br />Loop<br />Loop<br />Branch<br />Side-effect<br />Branch<br />Branch<br />Jump<br />Branch<br />Side-effect<br />Branch<br />Side-effect<br />Meet accidental complexity<br />Meet imperative Bob<br />Loop<br />Side-effect<br />
  5. 5. How do we change thinking modality?<br />We are computers<br />Technology is secondary<br />Intuition and ingenuity<br />Structured roadmap<br />
  6. 6. Roadmap to dependable software<br />Targeted at imperative programmers<br />Focus on reducing code complexity<br />Step by step discovery<br />Meant to alter the way we reason about computation<br />
  7. 7.
  8. 8. Step 1. Procedural decomposition<br />
  9. 9. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp;<br />switch(foodItem.Kind){<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />if(burp != null)<br />_burps.Add(burp); <br /> }<br />else<br />Environment.Spit(foodItem, bob);<br /> }<br /> }<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />Operational demarcation<br />
  10. 10. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp;<br />switch(foodItem.Kind){<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />if(burp != null)<br />burps.Add(burp); <br /> }<br />else<br />Environment.Spit(foodItem, bob);<br /> }<br />}<br />Burp();<br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />
  11. 11. Step 2. Single responsibility<br />
  12. 12. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp;<br />switch(foodItem.Kind){<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />if(burp != null)<br />_burps.Add(burp); <br /> }<br />else{<br />Environment.Spit(foodItem, bob);<br />}<br /> }<br />}<br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />Responsibility demarcation<br />
  13. 13. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp = ProcessFoodItem(foodItem, bob);<br />if(burp != null)<br />_burps.Add(burp); <br />else<br />Environment.Spit(foodItem, bob);<br /> }<br />}<br />}<br /> Burp();<br />}<br />Burp ProcessFoodItem(FoodItemfoodItem, ImperativeGeekbob)<br />{<br /> Burpburp = null;<br /> switch(foodItem.Kind)<br />{<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br />caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br />}<br />return burp; <br />}<br />
  14. 14. Step 3. Semantic regression<br />
  15. 15. Code beacons<br />Patterns in code<br />Sequences of imperative instructions<br />Describe how to compute and not computation itself<br />Denote hidden semantic intent<br />
  16. 16. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br />_burps= new List<Burp>();<br />foreach(vardish in dishes){<br />foreach(varfoodItemindish.Items){<br />if(foodItem.IsTasty(bob)){<br />Burpburp = ProcessFoodItem(foodItem, bob);<br />if(burp != null)<br />_burps.Add(burp); <br />else<br />Environment.Spit(foodItem, bob);<br /> }<br />}<br />}<br />Burp();<br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />Beacon<br />Beacon<br />Beacon<br />
  17. 17. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br /> _burps = ProcessFood(dishes, bob);<br />Burp();<br />}<br />List<Burp>ProcessFood(List<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />void Burp()<br />{<br />foreach(var burp in _burps){<br />Environment.Release(burp);<br /> }<br />}<br />
  18. 18. Step 4. Controlled side-effects<br />
  19. 19. Mutable type<br />void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob)<br />{<br /> _burps = ProcessFood(dishes, bob);<br /> Burp();<br />}<br />List<Burp>ProcessFood(List<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />Mutable type<br />Mutable type<br />
  20. 20. void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br /> _burps = ProcessFood(dishes, bob);<br /> Burp();<br />}<br />IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />
  21. 21. Step 6. Functional composition<br />
  22. 22. Non-compositional<br />void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br /> _burps = ProcessFood(dishes, bob);<br /> Burp();<br />}<br />IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />void Burp()<br />{<br />foreach(var burp in_burps){<br />Environment.Release(burp);<br /> }<br />}<br />
  23. 23. void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />Burp(ProcessFood(dishes, bob));<br />}<br />IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />void Burp(IEnumerable<Burp> burps)<br />{<br />foreach(var burp inburps){<br />Environment.Release(burp);<br /> }<br />}<br />Composition<br />
  24. 24. Step 7. Computational abstraction<br />
  25. 25. IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />Burp ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob)<br />{<br /> Burpburp = null;<br /> switch(foodItem.Kind)<br /> {<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />return burp; <br />}<br />void Burp(IEnumerable<Burp> burps)<br />{<br />foreach(var burp inburps){<br />Environment.Release(burp);<br /> }<br />}<br />Could be null<br />
  26. 26. IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob)<br />{<br /> Burpburp = null;<br /> switch(foodItem.Kind)<br /> {<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; <br />}<br />void Burp(IEnumerable<<Maybe<Burp>> burps)<br />{<br />foreach(var burp inburps.Where(b => b.HasValue)){<br />Environment.Release(burp);<br /> }<br />}<br />
  27. 27. Step 8. Constrained state space<br />
  28. 28. ∞<br />∞<br />IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob)<br />{<br /> Burpburp = null;<br /> switch(foodItem.Kind)<br /> {<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; <br />}<br />∞<br />∞<br />
  29. 29. IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob)<br />{<br />Contract.Requires(dishes.Any());<br />Contract.Requires(bob.IsHungry);<br />Contract.Ensures(bob.IsFull);<br />return dishes.SelectMany(d => d.Items)<br /> .Where(i => i.IsTasty(bob))<br /> .Select(i => ProcessFoodItem(i, bob)); <br />}<br />Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob)<br />{<br />Contract.Requires(foodItem.ExpiryDate < DateTime.Now);<br />Contract.Requires(foodItem.IsWarm);<br />Contract.Requires(bob.IsHungry);<br /> Burpburp = null;<br /> switch(foodItem.Kind)<br /> {<br />caseFoodKind.Yummy:<br />bob.ConsumeItem(foodItem, out burp);<br />break;<br /> caseFoodKind.Chewy:<br />var timeout = TimeSpan.FromSeconds(10);<br />bob.Chew(foodItem, timeout);<br />break;<br />default:<br />throw new Exception(“Yuk!”);<br /> }<br />return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; <br />}<br />

×