Correctness through simplicity

  • 208 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
208
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
3
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Correctness through simplicity
    Ulvi K. Guliyev
  • 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.”
    Prof. Joseph Kiniry (Software Development Group)
  • 3. How do we think about computation?
  • 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
  • 7.
  • 8. Step 1. Procedural decomposition
  • 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);
    }
    }
  • 11. Step 2. Single responsibility
  • 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;
    }
  • 14. Step 3. Semantic regression
  • 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);
    }
    }
  • 18. Step 4. Controlled side-effects
  • 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);
    }
    }
  • 21. Step 6. Functional composition
  • 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
  • 24. Step 7. Computational abstraction
  • 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);
    }
    }
  • 27. Step 8. Constrained state space
  • 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;
    }