Computer Science


Notes on computer science concepts.

Last Tended-
PlantedSep 2021
A triangle balancing a straight line on top of it.

Referential Equality

In JavaScript, if you compare primitive types (string, number, boolean) using the equality operator (===), the results is what you would except:


const bool1 = true
const bool2 = false
bool1 === bool1 // result: true
bool1 === bool2 // result: false
const num1 = 1
const num2 = 2
num1 === num1 // result: true
num1 === num2 // result: false
const letter1 = `a`
const letter2 = `b`
letter1 === letter1 // result: true
letter1 === letter2 // result: false

However, if you compare structural types (object, array, function), the result isn't as intuitive:


const person1 = {
name: `Deckard`
const person2 = {
name: `Deckard`
person1 === person2 // result: false
const letters1 = [`a`, `b`]
const letters2 = [`a`, `b`]
letters1 === letters2 // result: false
const function1 = () => null
const function2 = () => null
function1 === function2 // result: false

Take a look at person1 & person2. They are both the same type (object) & have the same properties & values. It would makes sense if the equality operator returned true when comparing them, but it doesn't. This is because when you compare structural types, the operator is testing reference equality, not value equality. Testing whether they are the same instance, not whether they are the same value. person1 & person2 may have the same value, but they are 2 different object instances (if I change a property on 1, the other will remain the same). Thus, when compared using the equality operator, it returns false.

Multiple circles (hollow on the left, fill on the right). A line connecting them with a square in the middle.


In computer science, memoisation is an optimization technique. You can take any regular function and memoise it. When memoised, the 1st time the function is called, it performs its calculation and obtains the return value. But before returning that value, it writes down what arguments it was passed, the value it is returning & stores them in a cache.

The next time the function is called, it checks the cache to see if it has seen the new arguments before. If so, it won't perform its calculation, it will just return the value it has written down in the cache. If not, it will perform its calculation & add a new record to the cache. This way, the function never performs its calculation on the same inputs twice. Reducing CPU time (at a cost of more memory). This technique would be used it there was a computationally expensive function that was taking a long time to complete & impacting UX (User Experience).

Without Memoisation

Below is an example of a function that takes a number, multiples it by 2, then returns the result. It also logs everytime it performs the calculation. We are calling this function 3 times. The 3rd call has the same argument as the 1st. You can see in the console that the funciton is calculating each time it is called.



With Memoisation

Let memoise the function. We can add a log object that our function will check everytime its called. If it finds a value for the input in the log, it will return that without needing to perform the calculation. If it doesn't, it performs the calculation, adds the result to the log, then returns the value. You can see in the console, the 3rd time we called the function (with the same input as the 1st call), no calculation was logged. Instead, the function just returned the value from the log.