Upon learning the syntax to a few different languages I came across the concept of truthy and falsey values. Boolean values themselves were familiar enough, but I could not wrap my head around how or why one would employ the use of truthy and falsey values. The appended 'y' didn't help in finding the concept ambiguous - and moreover, silly. After reading a variety of explanations and reaching out to fellow programmers, I felt like my list of grievances only grew. Eventually, I packed it away and accepted the fact that it would be lost on me. However, once I stepped away from the explanations and started programming, everything finally clicked.
My biggest hurdle in understanding truthy and falsey values was finding the distinction between a plain boolean expression. I couldn't suss out why I couldn't just use "true" or "false" as opposed to evaluating something to get the same result - especially since there is such a short list of things that evaluate to
false anyway. But, like many features of a programming language, truthy and falsey values are a tool like any other. There are a multitude of uses, but their power revolves around a common driving force in programming: dynamics.
Different languages have different definitions of truthy and falsey values. For the purposes of this post, I'll focus on Ruby.
In Ruby, there are only two falsey values:
nil. Everything else is truthy. In their boolean context, falsey and truthy values will evaluate to
true respectively. So, employing the double bang operator (which returns the boolean value of an object), we will get these results:
!!false ⇒false !!nil ⇒false !!0 ⇒true !!"I'm a string!" ⇒true
This is around where the explanations of truthy and falsey would end. To their defense, it's about as far as the technicalities go; it's the "what" in "What is truthy and falsey?". But, I yearned for the "why."
To begin my answer, I'll return to the statement I made earlier regarding dynamics in programming. As programmers, we constantly work with values that change. We also try to build programs around this assumption; flexibility is part of what makes code so powerful. Although I understood that
nil would evaluate to false in a condition statement, I didn't understand that they could be the value of something else - a variable, the return value of a method, or simply the result of another condition.
This will come through a little more in practice. After all, only after applying it to my own code did I understand its power. I'm going to use the example of a login method that I implemented in a simple Rails application.
Note: I won't go into the Rails-specific helper methods. Resort to documentation if you'd like to know more about the methods I'm using.
Let's take a look at what's going on in that first line after the method definition. Based on the parameters that are received from a login form that ask for a username and password, I'm employing the ActiveRecord method
.find_by() to retrieve the instance of the user that matches the inputed username. If you're wondering what may happen if no username matches the input, you're on the right track. When there is no match,
.find_by() will return
nil, a falsey value. If there is one, it will return that instance of the user object — a truthy value. Ah-ha! The lightbulb is starting to flicker. We could stop here, but let's go a little further to satisfy the entirety of the if statement below.
There are two conditions that need to evaluate to true - a user needs to be found that matches the username inputted, and secondly that username needs to be authenticated with the right password. In this context, as per the docs,
.authenticate() will return self (the user instance, in this case) if the passwords match, and simply
false if they don't. In the case that there is a user with the inputted username, and the inputted password matches the one stored for said user, the return value of user and
user.authenticate() will both be truthy values. It's important to note that explicitly, the values aren't equal to "true" themselves. If I were to
puts or use a debugger session to see what the return value of
user is, I'd get the object instance. But, look what happens when I use the double bang operator:
!!user ⇒ true
So, this satisfies both of the requirements in the
if condition, successfully logging the user in. In the case that one or both of them returned a falsey value, it would move onto the block inside the
This is only one example of how to practically employ truthy and falsey values in an application. To my surprise, I use them frequently. More than just gaining an understanding of the use cases, there are two primary takeaways I got from this: programming languages and their features as a toolbelt, and how programming shines through the "learn by doing" approach.
Features of languages - and by extension, languages themselves - are really just a set of tools that developers can use at their disposal. Despite restrictions on certain features, there is a multitude of use cases for each tool; they can be used responsibly or irresponsibly. Either way, they exist to aid us in problem-solving and controlling the behavior and flow of our programs. We have the power to use these tools as creatively as we see fit.
But, we will never know what tools are best for the job until we use them. A textbook definition only tells us so much - generally, only the behavior. It's up to us as developers to get to know our tools to their full extent, and the best way to accomplish this is through application. Learn to program by programming to learn.
Top comments (0)