Correctness through simplicity2. “…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.” Prof. Joseph Kiniry (Software Development Group) 4. ∞ ∞ void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps = new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp; switch(foodItem.Kind){ caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } if(burp != null) _burps.Add(burp); } else{ Environment.Spit(foodItem, bob); } } } foreach(var burp in _burps){ Environment.Release(burp); } } Branch Loop Loop Branch Side-effect Branch Branch Jump Branch Side-effect Branch Side-effect Meet accidental complexity Meet imperative Bob Loop Side-effect 5. How do we change thinking modality? We are computers Technology is secondary Intuition and ingenuity Structured roadmap 6. Roadmap to dependable software Targeted at imperative programmers Focus on reducing code complexity Step by step discovery Meant to alter the way we reason about computation 9. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps= new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp; switch(foodItem.Kind){ caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } if(burp != null) _burps.Add(burp); } else Environment.Spit(foodItem, bob); } } foreach(var burp in_burps){ Environment.Release(burp); } } Operational demarcation 10. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps= new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp; switch(foodItem.Kind){ caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } if(burp != null) burps.Add(burp); } else Environment.Spit(foodItem, bob); } } Burp(); } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } 12. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps= new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp; switch(foodItem.Kind){ caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } if(burp != null) _burps.Add(burp); } else{ Environment.Spit(foodItem, bob); } } } } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } Responsibility demarcation 13. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps= new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp = ProcessFoodItem(foodItem, bob); if(burp != null) _burps.Add(burp); else Environment.Spit(foodItem, bob); } } } Burp(); } Burp ProcessFoodItem(FoodItemfoodItem, ImperativeGeekbob) { Burpburp = null; switch(foodItem.Kind) { caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } return burp; } 15. Code beacons Patterns in code Sequences of imperative instructions Describe how to compute and not computation itself Denote hidden semantic intent 16. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps= new List<Burp>(); foreach(vardish in dishes){ foreach(varfoodItemindish.Items){ if(foodItem.IsTasty(bob)){ Burpburp = ProcessFoodItem(foodItem, bob); if(burp != null) _burps.Add(burp); else Environment.Spit(foodItem, bob); } } } Burp(); } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } Beacon Beacon Beacon 17. void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps = ProcessFood(dishes, bob); Burp(); } List<Burp>ProcessFood(List<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } void Burp() { foreach(var burp in _burps){ Environment.Release(burp); } } 19. Mutable type void InsertNutritionalSubstance(List<Dish> dishes, ImperativeGeek bob) { _burps = ProcessFood(dishes, bob); Burp(); } List<Burp>ProcessFood(List<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } Mutable type Mutable type 20. void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob) { _burps = ProcessFood(dishes, bob); Burp(); } IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } 22. Non-compositional void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob) { _burps = ProcessFood(dishes, bob); Burp(); } IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } void Burp() { foreach(var burp in_burps){ Environment.Release(burp); } } 23. void InsertNutritionalSubstance(IEnumerable<Dish> dishes, ImperativeGeek bob) { Burp(ProcessFood(dishes, bob)); } IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } void Burp(IEnumerable<Burp> burps) { foreach(var burp inburps){ Environment.Release(burp); } } Composition 25. IEnumerable<Burp>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } Burp ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob) { Burpburp = null; switch(foodItem.Kind) { caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } return burp; } void Burp(IEnumerable<Burp> burps) { foreach(var burp inburps){ Environment.Release(burp); } } Could be null 26. IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob) { Burpburp = null; switch(foodItem.Kind) { caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; } void Burp(IEnumerable<<Maybe<Burp>> burps) { foreach(var burp inburps.Where(b => b.HasValue)){ Environment.Release(burp); } } 28. ∞ ∞ IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob) { Burpburp = null; switch(foodItem.Kind) { caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; } ∞ ∞ 29. IEnumerable<Maybe<Burp>>ProcessFood(IEnumerable<Dish> dishes, ImperativeGeek bob) { Contract.Requires(dishes.Any()); Contract.Requires(bob.IsHungry); Contract.Ensures(bob.IsFull); return dishes.SelectMany(d => d.Items) .Where(i => i.IsTasty(bob)) .Select(i => ProcessFoodItem(i, bob)); } Maybe<Burp>ProcessFoodItem(FoodItemfoodItem, ImperativeGeek bob) { Contract.Requires(foodItem.ExpiryDate < DateTime.Now); Contract.Requires(foodItem.IsWarm); Contract.Requires(bob.IsHungry); Burpburp = null; switch(foodItem.Kind) { caseFoodKind.Yummy: bob.ConsumeItem(foodItem, out burp); break; caseFoodKind.Chewy: var timeout = TimeSpan.FromSeconds(10); bob.Chew(foodItem, timeout); break; default: throw new Exception(“Yuk!”); } return burp != null ? burp.ToMaybe() : Maybe<Burp>.Nothing; }