edicted Blog Banner

edicted

Literals vs Pointers

literally-programming-javascript-literal.jpg

Looks like I can't turn it off!

Been doing a lot of coding lately which is good but now all my blog posts are about coding. Go figure.

In this post I'll be discussing the "basic" concept of literals.

At the core, programming is shockingly simple. I mean let's be honest it has to be. Everything gets encoded into 1's and 0's in the end. This is paradoxically extremely simple and complex at the same time. What could be more simple than 1's and 0's; on and off; true or false? There are only two options! Easy, right? Well the real complexity is how we organize these bits so that they actually do something useful rather than just sit there taking up space.

The most powerful tool in programming is a list.

It's weird to admit, but pretty much everything in programming is just a list. All of the coding that gets done is just another way to manipulate or organize those lists to our benefit. Databases are a scaled up example of this concept, with the entire thing just being one gigantic list repository that's extremely organized and "easy" to access. Even blocks in the blockchain are linked-lists by definition. The previous block points to the next block; the previous node points to the next node in the chain. This is quite literally the definition of a linked-list.

learn-block-link-signature-chain-blockchain.png binary search tree.png

But what is INSIDE the list?

If we think of programming as a tree that branches outwards, pretty much everything we find at the very end of the branches (leaves) is going to be what's called a literal. A literal is hard constant data that can't be changed. This sounds like a simple concept but it's actually quite counterintuitive. The fact remains that literals are constants and constants can't be changed, ever. They can only be thrown away.

The cause of confusion here is that any newbie programmer knows that the ability to manipulate strings and numbers is a necessary core feature of any language. How can 2 + 2 = 4 if all numbers are constant and we can't change them? The answer is that the compiler creates a new literal to represent the manipulation of the old ones, and the old ones get thrown away. This may seem like trivial semantics, but for those who don't know how this stuff actually works: it can create very hard to solve bugs in the code we write. More importantly, baseline knowledge such as this can prevent such bugs from ever existing in the first place. A little underlying knowledge can save countless hours of debugging.

image.png

This is pretty much standard for most languages.

Numbers and strings of letters cannot be changed. True or false also can't be changed. If we want to change something we have to create a variable. A variable is the next level of abstraction above literals.

var a = 2 + 2

In JavaScript the naming conventions are quite nice and we just declare a variable as var. This is a lot different than more strict languages like C, C++, and Java where we would need to specifically tell the complier that actually variable a is an integer (int) and then the compiler would know exactly how much memory (four bytes) it needed to carve out for this variable. In less strict scripting languages like JavaScript and Python we declare variables generically and they can contain anything.

var could be a number or a string or an array or a dictionary or a map or... and then once we have assigned var to something we can easily assign it to a completely different class if we wanted. In the more efficient (faster by x20) languages like C++ this is not allowed because it would bog it down. Scripting languages don't care about being inefficient because computers are so fast these days it's better to just get the job done and worry about optimization after the fact. Usually optimization never has to occur because displaying a website is not normally a computationally expensive operation. Of course in turn this type of laziness creates situations like Chrome browser gobbling up 100MB of RAM on a completely empty window so there is that.

pointer-programmer.jpg

And this is where pointers come into play.

While variable a might look like it contains the literal 4 (which can't be changed), it doesn't. Rather, a just points to a place in memory that happens to be storing a 4 at this time. If our next move was to a += 7 then 7 would get added to 4 creating 11. a would now point to an 11 and the 7 and 4 literals would immediately get thrown away into the abyss to be repurposed for some other task.

But what if we want a variable that doesn't change?

Why would we want a variable that doesn't change? There are a few reasons, but the main one is that we know in advance that it's not supposed to change, and if it does change this would almost certainly create a bug that may or may not be easy to diagnose. Rather than deal with that we can just declare it const in advance.

const pi = 3.14159265359

Now if we try to change pi it will throw an error immediately and all bugs of that nature are avoided. We know for a fact that π should always be 3.14 so it makes sense that a program would never allow this number to change.

const list = []

This is where things get weird.

Say I create a constant array (which is a type of list) that's empty. What good is that? If the list is constant and the list is empty... what's the point? If the list is constant we can't change the list... right? We're just stuck with an empty list forever... right?

Wrong...

Because list isn't literally the array. list is just the POINTER to the array. This means we can add, subtract, and manipulate the object as much as we want. It will look like list is changing when we access it, but the pointer never changes because that array is still sitting in the exact same spot in memory; even though it's been manipulated many times over.

This is why abstraction can be confusing.

Because we can accidentally assume that the pointer to an object is literally the object itself. It is not.

image.png

https://linangdata.com/javascript-tester/

So even though our list was declared as a constant we could still add items to the list and also change those items to something else. Why? Because not only is list just a pointer to the array, but the array itself is just a list of variables that can also be modified. The only thing that can't be changed is the top-level pointer, so the command list = will never be allowed but all the functions of the list object itself are totally allowed.

Conclusion

These subtle details don't matter most of the time and we can just hack away at code until we get the desired result and not worry about what's going on in the background. However there are certain hidden advantages to knowing how it all secretly goes down. Sometimes a much simpler, elegant, or robust solution will present itself within the light of new knowledge.

The main takeaway from all of this is that the vast majority of programming and computing can always be reduced down to basic literals being stored in memory and variable pointers used to access them. Everything else is just more of this abstraction stacked on top of itself until something actually useful gets built. It's crazy to think that ones and zeros can be organized to create something as complex as a video game.

"Any sufficiently advanced technology is indistinguishable from magic"


Return from Literals vs Pointers to edicted's Web3 Blog

Literals vs Pointers was published on and last updated on 15 May 2024.