How to use built-in, high-quality code written by others
One of the core reasons humans thrive on Earth is our unique ability
to communicate with each other using language. We use language to
share knowledge and build on our predecessors' work to create
progress.
Libraries are the programming equivalent of passing essential
knowledge down. They store important previously-written code that
most programmers are bound to use at some point. However, in terms
of how they are used, a programming library is less like a
brick-and-mortar library and more like a car. When people sit in a
car, they assume the brake pedal will slow the vehicle down, the gas
pedal will speed it up, and the wheel will turn it. However, most
people do not understand the underlying mechanisms that make those
actions possible. This lack of understanding doesn’t hinder the
driver. In fact, it helps the driver because they don’t need to know
how each of the tens of thousands of moving parts in the car affects
its motion. Instead, they just need to understand how two pedals, a
lever, and a wheel affect the car’s motion. Drivers can assume the
underlying parts work and focus on their primary goal of getting
from point A to point B. Soon, self-driving cars could reduce the
level of understanding necessary to drive a car even further into
just identifying the destination.
Programming libraries are very similar. They package and hide away
the complex moving parts so the programmer can focus on “driving.”
Libraries enable programmers to focus on big picture ideas while
assuming the small details will be executed flawlessly.
Libraries must be imported first before being used. This is because
hundreds of libraries cover thousands of use cases that programmers
do not want to worry about (e.g., random number generation, reading
files, advanced math, app development, etc.). All of these libraries
can be useful yet include a ridiculous amount of code, and forcing
your computer to load all of them every time you run a program is
resource and memory-intensive. Therefore, most programming languages
simply package important code into libraries that can be imported
when you need them instead of all the time.
Note: Important libraries such as the String library are imported
automatically because they are used in the vast majority of
applications.
Let’s take a look at an example. The “String” library is used to
store and manipulate text. You can perform many useful operations
with it. First, we need to import the string library:
The String library is imported by default in all Python programs
The String library is imported by default in all Java programs
Code:
#include <string>
C++ is a lower-level language and doesn’t import the String
library by default.
We can do a variety of things using the String library:
Add strings together:
Code:
a = "Hello "
b = "World!"
c = a + b
print(c)
Output:
> Hello World!
Code:
String a = "Hello ";
String b = "World!";
String c = a+b;
System.out.println(c);
Output:
> Hello World!
Code:
string a = "Hello ";
string b = "World!";
string c = a+b;
cout << c;
Output:
> Hello World!
Turn all the characters lowercase:
Code:
a = "Hello World!"
b = a.lower()
print(b)
Output:
> hello world!
Code:
String a = "Hello World!";
String b = a.toLowerCase();
System.out.println(b);
Find a specific character (in this case the 5th character
because strings, like arrays, are 0-indexed):
Code:
a = "Hello World!"
b = a[4]
print(b)
Output:
> o
Code:
String a = "Hello World!";
char b = a.charAt(4);
System.out.println(b);
Output:
> o
Code:
string a = "Hello World!";
char b = a[4];
cout << b;
Output:
> o
These operations would usually take tens or hundreds of lines of
code to perform. However, because previous developers wrote the code
for these operations and packaged it into the String library, modern
programmers can perform these complex operations with a single line
of code. So instead of worrying about whether their string-adding
algorithm works, programmers today can focus on addressing far more
complicated problems and leave the finer details to their
predecessors’ code. See the “Functions” article for how you can
build libraries that future programmers will rely on.
It’s clear libraries have many pros. However, there is one major con
that every programmer should be aware of (but in most careers will
not need to worry about): Libraries are not flexible. Using the
earlier car analogy, hiding the tiny moving parts can help the
programmer focus on the overall goal. But what if the overall goal
requires the programmer to focus on the tiny moving parts? You can
think of this as fine-tuning a car for speed. Ideally, a driver
should remove unnecessary parts from the vehicle (e.g., air
conditioning, cd player) to maximize speed. Restricting a driver to
only using the pedals, wheel, and stick will bottleneck it.
Similarly, programmers who use libraries lose the flexibility of
removing unnecessary code or fine-tuning the code because the
library hides it away. Programmers who need ultra-fast code need to
delve deeper than surface-level libraries (which are generally
designed to be fast but not ultra-fast) in search of performance
gains.
You can play with all the code we've used in this article on Replit: