From Programming to Engineering

If all else fails, read the instructions!

@salman_arfat

process of designing and building an executable computer program to accomplish a specific computing result or to perform a specific task.

Programming

[...] encompasses not just the act of writing code, but all of the tools and processes an organization uses to build and maintain that code over time. [...] can be thought of as 'programming integrated over time.'

Engineering

—Software Engineering at Google

Programmer

Engineer

🔄

Tools

if all you have is a hammer, everything looks like a nail

Identify Yourself

If you know C++, you can learn Java in a day / week / month

If you know X, you can learn Y very quickly.

Language X / Framework Y is the best

I know Java, I'll learn C# now.

Expressing Programs

The Language Equivalence Fallacy

Example: Doubling a list

def createDoubleList(ls):
  i = 0
  doubledList = []
  while i < len(ls):
    doubledList.append(2 * ls[i])
    i += 1
  
  return doubledList
def createDoubleList(ls):
  doubledList = []
  for el in ls:
    doubledList.append(2 * el)
  return doubledList
def createDoubleList(ls):
  return [ 2 * el for el in ls ]

Example: range

returns a sequence of numbers, starting from 0 by default, and increments by 1

function range(lower, upper) {
  let result = [];
  for (let i = lower; i < upper; i++) {
    result.push(i);
  }
  return result;
}

for (let el of range(1, 1_000_000_000)) {
  console.log(el);
}
function* range(lower, upper) {
  for (let i = lower; i < upper; i++) {
    yield i;
  }
}

for (const el of range(1, 1_000_000_000)) {
  console.log(el);
}
factorial 0 = 1
factorial n = 
    n * factorial (n-1)
function factorial(num) {
  function loop(acc, _num) {
    if (_num === 1) {
      return acc;
    }
    return loop(acc * _num, _num - 1);
  }
  return loop(1, num)
}

Example: factorial

Why is everyone in such a rush? (by Peter Norvig)

Felleisen et al. give a nod to this trend in thier book How to Design Programs, when they says 

"Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies."

Alan Perlis once said: "A language that doesn't affect the way you think about programming, is not worth knowing".

Syntax

Semantics

Language Philosophy

Design Principles

May look similar to other langauges
Behavior of this language
How is the language modelling the problem domain? AKA Idiomatic.
Language-agnostic and language-specific techniques such as Modularization, code reuse etc

Languages

  • A powerful programming language is more than just a means for instructing a computer to perform tasks.
     
  • The language also serves as a framework within which we organize our ideas about processes.
     
  • Thus, when we describe a language, we should pay particular attention to the means that the language provides for combining simple ideas to form more complex ideas.

Example: Summation

class Main {
  static int getSum(int lb, int ub) {
    if (lb > ub) {
      return 0;
    }
    return lb + getSum(lb + 1, ub);
  }
}
class Main {
  static int square(int el) {
    return el * el;
  }
  static int getSum(int lb, int ub) {
    if (lb > ub) {
      return 0;
    }
    return square(lb) + getSum(lb + 1, ub);
  }
}

Testing

All code is guilty until proven innocent

Identifying Yourselves

I am paid to write code, not tests!

I am a developer, not tester - so I’m not responsible for writing tests!

We already have tests - why do we need unit tests?

We are working on a tight deadline - where do I have time for writing unit tests?

I don’t know how to write unit tests

Ours is legacy code - can’t write unit tests for them

If I touch the code, it breaks!

What is Science?

Theory + Experiments = Science 🎉

*Not an exact formulation

Model of the world

Testability of the model

Science (mainly) work by proving statements false, rather than by proving statements true.

What is Software?

Code + Tests

*Not an exact formulation

Model of the world

Testability of the model

= Software 🎉

Linting

Linting is the process of running a program that will analyze code for potential errors.

Prevents these kinds of errors

  • unused and undefined variables
  • Anti-patterns in feature usage
  • Maintaining Standards such as nomenclature, spacing etc
  • Lots more ...

Static type checking

Using statically-typed languages like Typescript

Does this function throw an exception or return 0 / -1 / null?

NullPointerException / cannot find X of undefined

Wait ... this function was supposed to return an object.
Wait ... this function was NOT supposed to return an object.

Unit Testing

Unit testing is the process of testing the smallest individual components of an application.

Why am I getting the wrong value?

This function is too hard to test.

Integration Testing

Unit testing is good.

BUT

Integration Testing

It is the process in which individual components of an application are combined and tested as a group.

I changed file X and now Y doesn't work. I didn't even touch Y.

End To End Testing

End-to-end testing is a technique used to test whether the flow of an application right from start to finish is behaving as expected.

describe('Amazon home page', () => {
  beforeEach(() => {
    cy.visit('https://amazon.com/');
  });

  it('contains "Amazon" in the title', () => {
    cy.title().should('contain', 'Amazon');
  });
});

When I hit my API from Postman / curl, it works. But it doesn't work when the user submits the form.

Product Engineering

you start coding, I'll ask what the customer wants...

Identifying Yourself

I'll think of the solution design later

I'll get more clarity as I start coding

My goal is to just make it work

Being a Tech Zealot

I'll document it later

I'll plan how to proceed later

but then how will the software be modified/updated later on?

High Standards

Why do we care about high standards?

  • If something is worth doing, it is worth doing well

 

  • Doing things well is really enjoyable (and doing things poorly is not)

 

  • Building something that goes unused is really discouraging (and building useful things is rewarding)

How to Develop High Standards

  • High standards are domain specific

 

  • Learn from exposure

 

  • Be realistic about how hard it is

 

  • You don't need the skills yourself to be able to recognize high standards

Set your standards at a global level

Learn From The Best

Attention To Details

Fewer Features

(but do them right)

Make It A Habit

Make The Extra Effort

The Cost of Change

Phase that Change Occurs Resulting Cost
Product Design $1,000
Product Testing $10,000
Process Design $100,000
Low-Rate Initial Production $1,000,000
Final Production/Distribution $10,000,000

Error Cost Escalation

Through the Project Life Cycle

Type of errors

  • Code bugs
  • Misunderstood requirements
  • Building something that no one cares about
  • Bad user experience
  • Bad schema design

Some tips on how to catch errors early

  • Automated Tests

    • Test Driven Development
  •  Whiteboarding

Wire Framing

Balsamiq

Pen and Paper

Talking to Customers

  • Read App Store reviews
  • Ask a friend for feedback
  • Help with customer support

User Studies

The important question is not

"Can I build it?"

It is

"Should I build it?"

Remote Communication

Traditional Office

=

Default Seen

Remote Office

=

Default Unseen

If they can't see it, you didn't do it

The Solution:

 

Over-Communicate

Make it easy for your team to stay up to date

Share Early and Often

  • Lots of small commits / PRs
  • Work in progress PRs
  • At least one PR per day
  • Share cool articles
  • Share a funny story?
  1. Search Your Mind

  2. Search Google

  3. Search Github Issues

  4. Post to Stack Overflow

  5. Ask a Co-worker

If you always ask your co-worker first, you will only ever become an expert as asking for help.

Asking for help!

Thanks

Please feel free to contact me.

@salman_arfat

From Programming to Engineering

By Arfat Salman

From Programming to Engineering

  • 509