Until it isn’t.
It’s super easy to use.
Until it isn’t.
Plugging this into a console, we find that what is shown holds true. But I’m not here to talk bad about JS. My goal with this post is to propose that (some of) the problems we face with programming languages aren’t in fact problems with the language itself, but how we as programmers are approaching the task at hand.
for loop, and more specifically the
When I discovered the
for…of loop, it was like the world had been hidden from me. “Surely this is the pinnacle of human innovation” I thought. Being able to iterate over an array with such little syntax was a miracle.
And of course JS, like almost all other common languages has a
while loop, which does something as long as a given expression is true (or crashes your computer if you’re not careful).
So if a common for loop iterates over a collection of data
This was a question that bothered me more and more as I continued to learn JS. I could in theory manipulate one of the aforementioned iterators to act in such a manner, but the function almost always ended up being more intricate than I felt was necessary. Then one day during a code session, I was doing some googling unrelated to the problem statement and I saw recursion being used, and it all clicked.
I’m sure that many of you reading this are familiar with the concept of recursion, but I’m going to define it anyway for my own peace of mind.
Recursion is defined as a repeated application of recursive procedures. (Long form for ‘something is being repeated’.)
“Yeah okay, that’s awesome, but how does that help me?”
Let’s look at a sandbox example.
This measly six lines of code will return a factorial of any number given to the function. This function is a common sandbox problem, with many different ways to solve it, however with recursion implemented, the function can be as short as possible. Let’s break it down.
As an example, say we plugged in
8 to the function. In the first line, the function checks to see if the
n is less than or equal to
1. Since it is not, we continue, and return the value of whatever the product of
n-1 is. Because of recursion, we can call this function ONCE with the desired number as
n, and it will loop through, decreasing by
n is equal to or less than
1. Thats a lot to take in, especially if you’re not familiar with recursion. Here is this function in action:
(For reference, a factorial is the product of a number times every number less than it, greater than 0.)
This function takes the number 8, multiplies it by 7, multiplies THAT product by 6, then THAT product by 5… etc. all the way down to 1, all in 6 lines of code. This would be irresponsibly complicated without recursion.
Recursion along with an
But honestly, that example was a bit too esoteric to really get a grasp on how awesome recursion really is. Let’s see a practical use.
Recently, I built a black jack simulator. In the game of black jack, each player including the dealer is initially dealt two playing cards.
dealFirstTwo() function, the variable
index will create a random number between
0 and (initially)
51. It will find a
card inside of an array of objects I created called
wholeDeck containing all
52 playing cards whose index in the array corresponds to the
index variable. It will then set the
dealt property of that found
card object to true. The
sortDeck() function sets the variable
sortedDeck equal to all the objects inside the
wholeDeck array whose
dealt property equals
false, which on the first pass is every card except the first
card ‘dealt’. Then, the function will push the found
card into the
hand that is passed in as a parameter to the function (either
dealerHand, both just empty arrays initially). Finally, the function checks the length of the
hand passed in as a parameter, and if the length is not equal to or greater than
2, it will repeat the function.
TL;DR: Give me a random number, find a card inside of a deck based on that number, tell that card its been dealt, tell the deck that card has been dealt, tell the player that the card belongs to it, and if the player doesn’t have two cards in his hand, give it another card.
Calling this function twice, with
dealerHand passed into the function as parameters respectively, we can efficiently deal two cards to a player and a dealer (and in theory, and as many players as needed).
And for one last example, another function in my blackjack simulator that handles the initial players turn uses recursion as well.
This function is a bit longer, but accomplishes the same idea. UNTIL a player either busts or chooses to stay, keep giving the player a card.
Here we have an
if…else statement, with another
if…else statement nested inside the else branch of the initial.
Line by line we have this:
playerTotal (a variable set as the total of all values of the cards in a given hand) is greater than
21, tell the player ‘you’ve busted’, show the hidden dealer card, and then
playerTotal is not greater than
21, send a confirmation window telling the player their
total, and asking the player if they want another card (this returns a boolean value). If the player wants to hit, the
dealOne() function deals one card (this function is the same as the function
dealFirstTwo() above, without the recursive
if statement). The
playerTotal will be updated,
showTertiaryPlayerCards() will show the card dealt on the screen, and after 500 milliseconds, the function will repeat. If the player does not want to hit, we pass the turn to the dealer, which is a similar function with a few more specifications for my very (very) simple ‘A.I.’.
TL;DR: Check to see if player has busted. If not, ask if they want a card. If they do, give them one, and repeat. If they don’t, its the dealers turn. If they busted, the dealer doesn’t get a turn, because the dealer wins automatically.
Hopefully this has cleared up the idea of recursion for some, and if not maybe it was able to show you the utility behind the idea.