James - Algebraic Refactoring Flashcards

1
Q

Meanwhile, when you are choosing the best implementation of a design, you are picking from a space of possible programs that all do the same thing. Where do these possibilities come from?

A

They come from simple rules for turning one program into an equivalent one. And the best part is you learned most of them in high school.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

When you are choosing the best implementation of a design, you are picking from a space of possible programs that all do the same thing. Where do these possibilities come from?

A

They come from simple rules for turning one program into an equivalent one.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

We can roughly split software design into three levels, what are these?

A

Design -> At a high level, what should it do -> A spec saying that I need a positive integer

Behavior -> At a low level -> what does it do -> A low-level spec saying it returns the number five

Implementation -> How does it do it? -> Choosing from possible implementations how the low-level spec should be met.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is a reduction?

A

Is a single step of computation

1 + 5 -> 6
69 -> 54
(1+5)
(72) -> 6(72)
(1+5)
(72) -> (1+5)9

For refactoring, we allow reduction in different orders and that gives us a graph of all the ways we can reduce an expression.

        (1+5)*(7*2)  6*(7*2)                  (1+5)*9
             6*9
             54

Since we can reduce in any order, we can also go backward and unreduce expressions.
(1+5)(72) -> (1+10/2)(72)

Reducing and unreducing give us an infinite space of possible expressions that all give us the same answer.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is equivalence?

A

If A can be rewritten to B by a series of reductions and backwards reductions, then A and B are equivalent.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is a substitution?

A

In an expression with variables, we can substitute all instances of the same variable for a value.

1/z
x^2 + xy + 1

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is equality?

A

You can say that a + b = b + a, because no matter what concrete values I choose for a and b they reduce to the same result. In a sense, we can derive equality from equivalence.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What ability equality give us?

A

We can use substitution and unsubstitution along with reduction and unreduction to explore the infinite space of all possible expressions that give us the same answer.

unsubstitution is the beginning of an add parameter refactoring and also a case of the extract method refactoring.

1+sqrt((x1-x2)(x1-x2)+(y1-y2)(y1-y2)))

1+[x1-x2/x, y1-y2/y]sqrt(xx+yy)
1+(fn (x, y) -> sqrt(x
x+yy) (x1-x2, y1-y2))
1+(fn (x, y) -> sqrt(xx+yy*))/mag

mag = (x, y) -> sqrt(xx+yy*)
1+mag (x1-x2, y1-y2)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What are the three fundamental constructs for data structures?

A

Products, Sums and Exponentials

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is a product?

A

|A x B| = |A| * |B|

Product is an and.

C structs, python tuples, python dictionaries are products. They only differ in how their elements are indexed. Classes are also like structs.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What are the laws associated with products?

A

We have commutativity (you can reorder):
A x B = B x A

We have associativity:
(A x B) x C = A x (B x C)

((1, 2), 3) = (1, (2, 3))

class Employee 
    int id
class Engineer extends Employee
    String name
    int deskno

is equivalent to

class Employee 
    int id
    String name
class Engineer extends Employee
    int deskno
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is a Sum?

A

Sum is an OR.

Sum = Left | Right
case sum of
Left -> do something
Right -> do otherstuf

In C we have unions, in Java we can use subclasses, in Python everything is a sum because of dynamic typing.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Does Int + Int = Int?

A

No, because in a Sum we have knowledge of which value is each, it can be either the first one or the second one.

Int + Int = Int * 2 = Int * Bool

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is the unit type?

A

Its the type that only contains one thing.
In C/Java is called void. If we have a void function, is not that it never returns, it just doesn’t return anything interesting, like returning the same thing everytime.
Or enum Unit { UNIT } is also a unit in C.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is a boolean?

A

bool = 1 + 1 = 2

It’s either the left of nothing interesting (unit type) or it’s right of nothing interesting.

boolean is also called two, it’s the type with two values. And is equivalent to any other type with two values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How would you express a nullable object in Java?

A

Nullable object = 1 + (Non Nullable Object)

It’s a non nullable thing or nothing and you know which one is each.

17
Q

Which law is this?

datatype Animal
= Dog String Breed
| Cat String int

To

datatype Animal =
Animal String OtherInf

datatype OtherInf
= DogInf Breed
| CatInf int

A

Distributive law

18
Q

What are exponentials?

A

A function that assigns 10 people to 3 colors can have 3^10 possible results.
So a function from People -> Color codifies Color^People functions.

Because of that functions are exponentials.
A->B codifies B^A functions
B^A is how many functions there are.

19
Q

Use exponential laws to refactor this code:

public int addTimeOrTemp(int x, boolean isTime)

A

(1)
int addTimeOrTemp(int x, boolean isTime) == int^(int * 2)
(2)
datatype TimeOrTemp = Time int | Temp int
int addTimeOrTemp(TimeOrTemp x) == int^(int + int)
(3)
int addTimeOrTemp(int x)
int addTimeOrTemp(int x)
== int^int * int^int

20
Q

List each fundamental data structure constructors and destructors.

A

Constructor | Destructor
(1, 2) | x, y = foo
inl 42 | case foo of
Left x => x + 1
Right y => len(y)
(x,y) -> (x+y) | foo(1, 2, 3)

21
Q

Why the datastructures we choose have inescapable consequences in the shape of our code?

A

Every value is useless unless destructed.

Implications:

  • Every sum type will be cased over (Nullable objects)
  • Every boolean will be used in an if/else
  • Every recursive type will be recursed over
  • Every list will be mapped over
  • In Python, if a variable can be of multiple types, you will need to case over it

The shape of your code follows the shape of your data. That is another instance of the data over code principle.

22
Q

What is defunctionalizations and refunctionalization?

A

Defunctionalization occurs when we exchange a high order function to a sum type like an enum.
Refunctionalization occurs when we exchange a sum type to a high order function.
It’s an instance of the open closed principle when we replace cases with function calls.
Another example would be putting either a function or a message in a queue to be processed latter.

The defunctionalized version is more inspectable, we can print it, send it over the wire.
The refunctionalized version is more open, it is easier to add new alternatives.

For more read: https://en.wikipedia.org/wiki/Defunctionalization

23
Q

Refactor:

def intersect((low1, hi1), (low2, hi2)):
  if low1 > low2:
    if hi1 < hi2:
      return (low1, hi1)
    else:
      return (low1, hi2)
  else:
    if hi1 < hi2:
      return (low2, hi1)
    else:
      return (low2, hi2)
A

AC+AD+BC+BD=(A+B)(C+D)

def intersect((low1, hi1), (low2, hi2)):
  return (max(low1, low2), min(hi1, hi2))
24
Q

Just like in the algebra of numbers, a law will assert the equality of two objects - in our case, the objects will be types. What does it mean for two objects to be equal in the algebra of types?

A

When two types a and b are equal, you could write two functions:

from :: a -> b
to :: b -> a

that pair up values of a with values of b, so that the following equations always hold (here the == is genuine, Haskell-flavored equality):

to (from a) == a
from (to b) == b

For example, I contend that the types Bool and Add () () are equivalent. I can demonstrate the equivalence with the following functions:

to :: Bool -> Add () ()
to False = AddL ()
to True = AddR ()

from :: Add () () -> Bool
from (AddL _) = False
from (AddR _) = True

25
Q

Just like in the algebra of numbers, a law will assert the equality of two objects - in our case, the objects will be types. What does it mean for two objects to be equal in the algebra of types?

A

When two types a and b are equal, you could write two functions:

from :: a -> b
to :: b -> a

that pair up values of a with values of b, so that the following equations always hold (here the == is genuine, Haskell-flavored equality):

to (from a) == a
from (to b) == b

For example, I contend that the types Bool and Add () () are equivalent. I can demonstrate the equivalence with the following functions:

to :: Bool -> Add () ()
to False = AddL ()
to True = AddR ()

from :: Add () () -> Bool
from (AddL _) = False
from (AddR _) = True

26
Q

List simple laws for sum types

A

there are as many values of type Add Void a as there are of type a
Add Void a === a

it doesn’t matter which order you add things in
Add a b === Add b a

In math:

0+x=x
x+y=y+x

27
Q

List simple laws for product types

A

if you multiply anything by Void, you get Void back
Mul Void a === Void

if you multiply by () you don’t change anything
Mul () a === a

it doesn’t matter which order you multiply in
Mul a b === Mul b a

distributive law
Mul a (Add b c) === Add (Mul a b) (Mul a c)
in math:
0⋅x=0
1⋅x=x
x⋅y=y⋅x
a⋅(b+c)=a⋅b+a⋅c
28
Q

List all functions Bool -> Bool

A

f1 :: Bool -> Bool – equivalent to ‘id’
f1 True = True
f1 False = False

f2 :: Bool -> Bool – equivalent to ‘const False’
f2 _ = False

f3 :: Bool -> Bool – equivalent to ‘const True’
f3 _ = True

f4 :: Bool -> Bool – equivalent to ‘not’
f4 True = False
f4 False = True

That’s why when we have a function a->b, b^a enumerates literaly all possible functions.

29
Q

List simple laws for exponentials types

A

there are as many functions () -> a as there are values of type a:
() -> a === a

there is only one function a -> () – in particular, it is const ():
a -> () === ()

factoring out of common arguments:
(a -> b, a -> c) === a -> (b,c)

we can curry and uncurry functions:
a -> (b -> c) === (b,a) -> c
or:
a -> b -> c === (a,b) -> c

In math:
a^1=a
1^a=1
b^a⋅c^a = (bc)^a
(c^b)^a=c^(b⋅a)