Discover millions of ebooks, audiobooks, and so much more with a free trial

From $11.99/month after trial. Cancel anytime.

The Recursive Book of Recursion: Ace the Coding Interview with Python and JavaScript
The Recursive Book of Recursion: Ace the Coding Interview with Python and JavaScript
The Recursive Book of Recursion: Ace the Coding Interview with Python and JavaScript
Ebook651 pages5 hours

The Recursive Book of Recursion: Ace the Coding Interview with Python and JavaScript

Rating: 0 out of 5 stars

()

Read preview

About this ebook

An accessible yet rigorous crash course on recursive programming using Python and JavaScript examples.

Recursion has an intimidating reputation: it’s considered to be an advanced computer science topic frequently brought up in coding interviews. But there’s nothing magical about recursion.
 
The Recursive Book of Recursion uses Python and JavaScript examples to teach the basics of recursion, exposing the ways that it’s often poorly taught and clarifying the fundamental principles of all recursive algorithms. You’ll learn when to use recursive functions (and, most importantly, when not to use them), how to implement the classic recursive algorithms often brought up in job interviews, and how recursive techniques can help solve countless problems involving tree traversal, combinatorics, and other tricky topics.
 
This project-based guide contains complete, runnable programs to help you learn:
 
  • How recursive functions make use of the call stack, a critical data structure almost never discussed in lessons on recursion
  • How the head-tail and “leap of faith” techniques can simplify writing recursive functions
  • How to use recursion to write custom search scripts for your filesystem, draw fractal art, create mazes, and more
  • How optimization and memoization make recursive algorithms more efficient
  •  
    Al Sweigart has built a career explaining programming concepts in a fun, approachable manner. If you’ve shied away from learning recursion but want to add this technique to your programming toolkit, or if you’re racing to prepare for your next job interview, this book is for you.
    LanguageEnglish
    Release dateAug 16, 2022
    ISBN9781718502031
    The Recursive Book of Recursion: Ace the Coding Interview with Python and JavaScript

    Read more from Al Sweigart

    Related to The Recursive Book of Recursion

    Related ebooks

    Programming For You

    View More

    Reviews for The Recursive Book of Recursion

    Rating: 0 out of 5 stars
    0 ratings

    0 ratings0 reviews

    What did you think?

    Tap to rate

    Review must be at least 10 words

      Book preview

      The Recursive Book of Recursion - Al Sweigart

      The Recursive Book of Recursion

      Ace the Coding Interview with Python and JavaScript

      by Al Sweigart

      nsp_logo_black_rk

      THE RECURSIVE BOOK OF RECURSION. Copyright © 2022 by Al Sweigart.

      Some rights reserved. This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

      First printing

      26 25 24 23 22 1 2 3 4 5

      ISBN-13: 978-1-71850-202-4 (print)

      ISBN-13: 978-1-71850-203-1 (ebook)

      Publisher: William Pollock

      Production Manager: Rachel Monaghan

      Production Editor: Miles Bond

      Developmental Editor: Frances Saux

      Cover Illustrator: James L. Barry

      Interior Design: Octopod Studios

      Technical Reviewer: Sarah Kuchinsky

      Copyeditor: Sharon Wilkey

      Compositor: Maureen Forys, Happenstance Type-O-Rama

      Proofreader: Audrey Doyle

      For information on distribution, bulk sales, corporate sales, or translations, please contact No Starch Press, Inc. directly at [email protected] or:

      No Starch Press, Inc.

      245 8th Street, San Francisco, CA 94103

      phone: 1.415.863.9900

      www.nostarch.com

      Library of Congress Cataloging-in-Publication Data

      Library of Congress Control Number: 2022932456

      No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. Other product and company names mentioned herein may be the trademarks of their respective owners. Rather than use a trademark symbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.

      The information in this book is distributed on an As Is basis, without warranty. While every precaution has been taken in the preparation of this work, neither the author nor No Starch Press, Inc. shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in it.

      To Jack, who held up a mirror in front of my mirror

      About the Author

      Al Sweigart is a software developer, fellow of the Python Software Foundation, and author of several programming books with No Starch Press, including the worldwide bestseller Automate the Boring Stuff with Python. His Creative Commons licensed works are available at https://www.inventwithpython.com.

      About the Technical Reviewer

      Sarah Kuchinsky, MS, is a corporate trainer and consultant. She uses Python for a variety of applications, including health systems modeling, game development, and task automation. Sarah is a co-founder of the North Bay Python conference, tutorials chair for PyCon US, and lead organizer for PyLadies Silicon Valley. She holds degrees in management science as well as in engineering and mathematics.

      Foreword

      When I was approached by Al to write the foreword to this book, I was pretty excited about the prospect. A book on recursion! Now, that’s something you just don’t see every day. Considered by many to be one of the more mysterious topics in programming, recursion is often discouraged. Oddly, this stands in stark contrast to its storied use in weird job interview questions.

      However, there are all sorts of practical reasons to learn about recursion. Recursive thinking is very much a mindset about problem-solving. At its core, larger problems get broken into smaller problems. And sometimes along the way, hard problems are rewritten into equivalent but easier-to-solve simple problems. This sort of thinking can be a useful tool when applied to software design—even when recursion is not being used. Thus, it’s a worthy topic of study for programmers of all skill levels.

      In my unbridled excitement to say more about recursion, I originally wrote this foreword in the form of a few short stories involving friends who’d applied recursive thinking in different ways but achieved a similar result. First there was the story of Ben, who learned about recursion, took it too far, and somehow managed to disappear off the face of the earth under mysterious circumstances after committing the following Python code into production:

      result = [(lambda r: lambda n: 1 if n < 2 else r(r)(n-1) + r(r)(n-2))(

                (lambda r: lambda n: 1 if n < 2 else r(r)(n-1) + r(r)(n-2)))(n)

                for n in range(37)]

      Then there was the story of Chelsea, who became so effective at real-world problem-solving that she was promptly fired! Oh, you wouldn’t believe how much all the fine editors at No Starch (bless their hearts) hated these stories. You can’t start a book by telling people stories like that. It’s just going to scare everyone away! To be fair, they probably have a point. In fact, they even made me move a more reassuring paragraph about recursion from later in this foreword up to the second paragraph just so you wouldn’t first read about the stories of Ben and Chelsea and run away in a screaming horror to read a book about design patterns instead.

      Clearly, writing the foreword to a book is serious business. So, regrettably, I’ll have to share the true stories of Ben and Chelsea with you another time. But, getting back to the book, it’s true that recursion is not a technique that gets applied to the vast majority of problems in day-to-day programming. As such, it often carries an aura of magic about it. This book hopes to dispel much of that. This is a good thing.

      Finally, as you set off on your recursion journey, be prepared to have your brain bent in new directions. Not to worry—this is normal! However, it’s also important to stress that recursion is supposed to be a bit of fun. Well, at least a little bit. So, enjoy the ride!

      —David Beazley

      Author of Python Cookbook and Python Distilled

      Teacher of aspiring problem solvers

      https://www.dabeaz.com

      Acknowledgments

      It’s misleading to have only my name on the cover. I’d like to thank my publisher, Bill Pollock; my editor, Frances Saux; my technical reviewer, Sarah Kuchinsky; my production editor, Miles Bond; the production manager, Rachel Monaghan; and the rest of the staff at No Starch Press for their invaluable help.

      Finally, I would like to thank my family, friends, and readers for all their suggestions and support.

      Introduction

      The programming technique of recursion can produce elegant code solutions. More often, however, it produces confused programmers. This doesn’t mean programmers can (or should) ignore recursion. Despite its reputation for being challenging, recursion is an important computer science topic and can yield keen insights into programming itself. At the very least, knowing recursion can help you nail a coding job interview.

      If you’re a student with an interest in computer science, recursion is a necessary hurdle you’ll have to overcome to understand many popular algorithms. If you’re a programming bootcamp graduate or self-taught programmer who managed to bypass the more theoretical computer science topics, recursion problems are still sure to come up during whiteboard coding interviews. And if you’re an experienced software engineer who has never touched a recursive algorithm before, you might find recursion to be an embarrassing gap in your knowledge.

      There’s no need to worry. Recursion isn’t as hard to understand as it is to teach. As I’ll explain in Chapter 1, I attribute the widespread misunderstanding of recursion to poor instruction rather than any inherent difficulty. And since recursive functions aren’t commonly used in day-to-day programming, many folks get along just fine without them.

      But a certain conceptual beauty lies behind recursive algorithms that can aid your understanding of programming even if you don’t often apply them. Recursion has a visual beauty as well. The technique is behind the amazing mathematical art of fractals, the self-similar shapes shown in Figure 1.

      Figure 1: These examples of fractals include a Sierpiński triangle (left), a Hilbert curve (center), and a Koch snowflake (right).

      However, this book is not entirely in praise of recursion. I include some sharp criticisms of this technique. Recursion is overused in cases where a simpler solution exists. Recursive algorithms can be hard to understand, have worse performance, and are susceptible to crash-causing stack overflow errors. And a certain kind of programmer may use recursion not because it’s the right technique for a given problem, but simply because they feel smarter when they write code that other programmers struggle to understand. Computer scientist Dr. John Wilander once said, When you finish a PhD in computer science, they take you to a special room and explain that you must never use recursion in real life. Its only purpose is to make programming hard for undergrads.

      So, whether you want to get an edge in coding interviews, you want to create beautiful mathematical art, or you stubbornly seek to finally understand the intriguing properties of this concept, this book will be your guide down the rabbit hole that is recursion (and the rabbit holes within that rabbit hole). Recursion is one of the computer science topics that separates the professionals from the beginners. By reading this book, you’ll master a great skill and learn its dark secret: recursion isn’t as complicated as people think it is.

      Who Is This Book For?

      This book is for those who are intimidated or intrigued by recursive algorithms. Recursion is one of those topics that seems like black magic to beginner programmers or freshman computer science students. Most recursion lessons are hard to follow and make the subject seem frustrating, even fearsome. For these readers, I hope this book’s direct explanations and ample examples can help make the topic finally click.

      The only prerequisite for this book is basic programming experience with either the Python or JavaScript programming languages, which the chapters’ code examples use. The book’s programs have been stripped down to their essences; if you know how to call and create functions and the difference between global and local variables, you know enough to work through the programming examples.

      About This Book

      This book has 14 chapters:

      Part I: Understanding Recursion

      Chapter 1: What Is Recursion? Explains recursion and how it is the natural result of the way programming languages implement functions and function calls. This chapter also argues that recursion isn’t nearly the elegant, mystical concept many claim it is.

      Chapter 2: Recursion vs. Iteration Dives into the differences (and many similarities) between recursive and iterative techniques.

      Chapter 3: Classic Recursion Algorithms Covers famous recursive programs such as the Tower of Hanoi, the flood fill algorithm, and others.

      Chapter 4: Backtracking and Tree Traversal Algorithms Discusses a problem for which recursion is particularly suited: traversing tree data structures, such as when solving mazes and navigating a directory.

      Chapter 5: Divide-and-Conquer Algorithms Discusses how recursion is useful for splitting large problems into smaller subproblems and covers several common divide-and-conquer algorithms.

      Chapter 6: Permutations and Combinations Covers recursive algorithms involving ordering and matching, as well as the common programming problems to which these techniques are applied.

      Chapter 7: Memoization and Dynamic Programming Explains some simple tricks to improve code efficiency when applying recursion in the real world.

      Chapter 8: Tail Call Optimization Covers tail call optimization, a common technique used to improve the performance of recursive algorithms, and how it works.

      Chapter 9: Drawing Fractals Tours the intriguing art that can be programmatically produced by recursive algorithms. This chapter makes use of turtle graphics for generating its images.

      Part II: Projects

      Chapter 10: File Finder Covers a project that searches through the files on your computer according to custom search parameters you provide.

      Chapter 11: Maze Generator Covers a project that automatically generates mazes of any size using the recursive backtracker algorithm.

      Chapter 12: Sliding-Tile Solver Covers a project that solves sliding-tile puzzles, also called 15-puzzles.

      Chapter 13: Fractal Art Maker Explores a project that can produce custom fractal art of your own design.

      Chapter 14: Droste Maker Explores a project that produces recursive, picture-in-picture images using the Pillow image-manipulation module.

      Hands-On, Experimental Computer Science

      Reading about recursion won’t teach you how to implement it on its own. This book includes many recursive code examples in both the Python and JavaScript programming languages for you to experiment with. If you’re new to programming, you can read my book Automate the Boring Stuff with Python, 2nd edition (No Starch Press, 2019), or Python Crash Course, 2nd edition, by Eric Matthes (No Starch Press, 2019) for an introduction to both programming and the Python programming language.

      I recommend stepping through these programs with a debugger. A debugger lets you execute programs one line at a time and inspect the state of the program along the way, allowing you to pinpoint where bugs occur. Chapter 11 of Automate the Boring Stuff with Python, 2nd edition, covers how to use the Python debugger and is free to read online at https://automatetheboringstuff.com/2e/chapter11.

      The chapters in this book display the Python and JavaScript code examples together. The Python code is saved in a .py file, and the JavaScript code in an .html file (not a .js file). For example, take the following hello.py file:

      print('Hello, world!')

      And the following hello.html file:

      document.write(Hello, world!
      );

      The two code listings act as a Rosetta stone, describing programs that produce the same results in two different languages.

      Note

      The
      HTML tag in
      hello.html is a break return, also called a newline, which prevents all the output from appearing on a single line. Python’s print() function automatically adds break returns to the end of the text, while JavaScript’s document.write() function doesn’t.

      I encourage you to manually copy these programs by using your keyboard, rather than simply copying and pasting their source code into a new file. This helps your muscle memory of the programs and forces you to consider each line as you type it.

      The .html files are technically not valid because they’re missing several necessary HTML tags, such as and , but your browser will still be able to display the output. These tags have been left out on purpose. The programs in this book are written for simplicity and readability, not to demonstrate web development best practices.

      Installing Python

      While every computer has a web browser that can view the .html files in this book, you must install Python separately if you wish to run the book’s Python code. You can download Python for Microsoft Windows, Apple macOS, and Ubuntu Linux for free from https://python.org/downloads. Be sure to download a version of Python 3 (such as 3.10) and not Python 2. Python 3 made a few backward-incompatible changes to the language, and the programs in this book may not run correctly, if at all, on Python 2.

      Running IDLE and the Python Code Examples

      You can use the IDLE editor that comes with Python to write your Python code or install a free editor, such as the Mu Editor from https://codewith.mu, PyCharm Community Edition from https://www.jetbrains.com/pycharm/download, or Microsoft Visual Studio Code from https://code.visualstudio.com/Download.

      To open IDLE on Windows, open the Start menu in the lower-left corner of your screen, enter IDLE in the search box, and select IDLE (Python 3.10 64-bit).

      On macOS, open the Finder window and click ApplicationsPython 3.10, and then the IDLE icon.

      On Ubuntu, select ApplicationsAccessoriesTerminal and then enter IDLE 3. You may also be able to click Applications at the top of the screen, select Programming, and then click IDLE 3.

      IDLE has two types of windows. The interactive shell window has the >>> prompt and is used for running Python instructions one at a time. This is useful when you want to experiment with bits of Python code. The file editor window is where you can enter full Python programs and save them as .py files. This is how you’ll enter the source code for the Python programs in this book. To open a new file editor window, click FileNew File. You can run the programs by clicking RunRun Module or pressing F5.

      Running the JavaScript Code Examples in the Browser

      Your computer’s web browser can run the JavaScript programs and display their output, but to write JavaScript code, you’ll need a text editor. A simple program like Notepad or TextMate will do, but you can also install text editors specifically for writing code, such as IDLE or Sublime Text from https://www.sublimetext.com.

      After typing the code for your JavaScript programs, save the files as .html files, not .js files. Open them in a web browser to view the results. Any modern web browser works for this purpose.

      Part I

      UNDERSTANDING RECURSION

      1

      What Is Recursion?

      Recursion has an intimidating reputation. It’s considered hard to understand, but at its core, it depends on only two things: function calls and stack data structures.

      Most new programmers trace through what a program does by following the execution. It’s an easy way to read code: you just put your finger on the line of code at the top of the program and move down. Sometimes your finger will loop back; other times, it will jump into a function and later return. This makes it easy to visualize what a program does and in what order.

      But to understand recursion, you need to become familiar with a less obvious data structure, called the call stack, that controls the program’s flow of execution. Most programming beginners don’t know about stacks, because programming tutorials often don’t even mention them when discussing function calls. Furthermore, the call stack that automatically manages function calls doesn’t appear anywhere in the source code.

      It’s hard to understand something when you can’t see it and don’t know it exists! In this chapter, we’ll pull back the curtain to dispel the overblown notion that recursion is hard, and you’ll be able to appreciate the elegance underneath.

      The Definition of Recursion

      Before we begin, let’s get the clichéd recursion jokes out of the way, starting with this: To understand recursion, you must first understand recursion.

      During the months I’ve spent writing this book, I can assure you that this joke gets funnier the more you hear it.

      Another joke is that if you search Google for recursion, the results page asks if you mean recursion. Following the link, as shown in Figure 1-1, takes you to . . . the search results for recursion.

      Screenshot of a Google search for the term “recursion.” Below the search bar is a banner that reads, “Did you mean: recursion.”

      Figure 1-1: The Google search results for recursion link to the Google search results for recursion.

      Figure 1-2 shows a recursion joke from the webcomic xkcd.

      A one-panel comic of someone reading the text “I’m so meta, even this acronym.”

      Figure 1-2: I’m So Meta, Even This Acronym (I.S. M.E.T.A.) (xkcd.com/917 by Randall Munroe)

      Most jokes about the 2010 science fiction action movie Inception are recursion jokes. The film features characters having dreams within dreams within dreams.

      And finally, what computer scientist could forget that monster from Greek mythology, the recursive centaur? As you can see in Figure 1-3, it is half horse, half recursive centaur.

      Image of a statue with a horse’s body whose front legs and torso repeat, decreasing in size, in a spiral pattern.

      Figure 1-3: The recursive centaur. Image by Joseph Parker.

      Based on these jokes, you might conclude that recursion is a sort of meta, self-referencing, dream-within-a-dream, infinite mirror-into-mirror sort of thing. Let’s establish a concrete definition: a recursive thing is something whose definition includes itself. That is, it has a self-referential definition.

      The Sierpiński triangle in Figure 1-4 is defined as an equilateral triangle with an upside-down triangle in the middle that forms three new equilateral triangles, each of which contains a Sierpiński triangle. The definition of Sierpiński triangles includes Sierpiński triangles.

      Graphic depicting three triangles. The first triangle has a smaller upside-down triangle in the center that divides the original into smaller triangles. The next triangle shows those three smaller outer triangles, each divided into still smaller triangles. The third triangle shows those smaller triangles further divided into triangles.

      Figure 1-4: Sierpiński triangles are fractals (recursive shapes) that include Sierpiński triangles.

      In a programming context, a recursive function is a function that calls itself. Before we explore recursive functions, let’s take a step back and understand how regular functions work. Programmers tend to take function calls for granted, but even experienced programmers will find it worthwhile to review functions in the next section.

      What Are Functions?

      Functions can be described as mini-programs inside your program. They’re a feature of nearly every programming language. If you need to run identical instructions at three different places in a program, instead of copying and pasting the source code three times you can write the code in a function once and call the function three times. The beneficial result is a shorter and more readable program. The program is also easier to change: if you need to fix a bug or add features, you need to change your program in only one place instead of three.

      All programming languages implement four features in their functions:

      Functions have code that is run when the function is called.

      Arguments (that is, values) are passed to the function when it’s called. This is the input to the function, and functions can have zero or more arguments.

      Functions return a return value. This is the output of the function, though some programming languages allow functions not to return anything or to return null values like undefined or None.

      The program remembers which line of code called the function and returns to it when the function finishes its execution.

      Different programming languages might have additional features, or different options for how to call functions, but they all have these four general elements. You can visually see the first three of these elements because you write them in the source code, but how does a program keep track of where the execution should return to when the function returns?

      To get a better sense of the problem, create a functionCalls.py program that has three functions: a(), which calls b(), which calls c():

      Python

      def a():

          print('a() was called.')

          b()

          print('a() is returning.')

       

      def b():

          print('b() was called.')

          c()

          print('b() is returning.')

       

      def c():

          print('c() was called.')

          print('c() is returning.')

       

      a()

      This code is equivalent to the following functionCalls.html program:

      JavaScript

      function a() {

          document.write(a() was called.
      );

          b();

          document.write(a() is returning.
      );

      }

       

      function b() {

          document.write(b() was called.
      );

          c();

          document.write(b() is returning.
      );

      }

       

      function c() {

          document.write(c() was called.
      );

          document.write(c() is returning.
      );

      }

       

      a();

      When you run this code, the output looks like this:

      a() was called.

      b() was called.

      c() was called.

      c() is returning.

      b() is returning.

      a() is returning.

      The output shows the start of functions a(), b(), and c(). Then, when the functions return, the output appears in reverse order: c(), b(), and then a(). Notice the pattern to the text output: each time a function returns, it remembers which line of code originally called it. When the c() function call ends, the program returns to the b() function and displays b() is returning. Then the b() function call ends, and the program returns to the a() function and displays a() is returning. Finally, the program returns to the original a() function call at the end of the program. In other words, function calls don’t send the execution of the program on a one-way trip.

      But how does the program remember if it was a() or b() that called c()? This detail is handled by the program implicitly with a call stack. To understand how call stacks remember where the execution returns at the end of a function call, we need to first understand what a stack is.

      What Are Stacks?

      Earlier I mentioned the clichéd wisecrack, To understand recursion, you must first understand recursion. But this is actually wrong: to really understand recursion, you must first understand stacks.

      A stack is one of the simplest data structures in computer science. It stores multiple values like a list does—but unlike lists, it limits you to adding to or removing values from the top of the stack only. For stacks implemented with lists or arrays, the top is the last item, at the right end of the list or array. Adding values is called pushing values onto the stack, while removing values is called popping values off the stack.

      Imagine that you’re engaged in a meandering conversation with someone. You’re talking about your friend Alice, which then reminds you of a story about your co-worker Bob, but for that story to make sense, you first have to explain something about your cousin Carol. You finish your story about Carol and go back to talking about Bob, and when you finish your story about Bob, you go back to talking about Alice. Then you are reminded about your brother David, so you tell a story about him. Eventually, you get around to finishing your original story about Alice.

      Your conversation follows a stack-like structure, as in Figure 1-5. The conversation is stack-like because the current topic is always at the top of the stack.

      A timeline that shows names stacked one on top of the other at various points in time. It begins with no names, then shows Alice, then Bob on top of Alice, then Carol on top of Bob on top of Alice, then Bob on top of Alice, then just Alice, then David on top of Alice, then Just Alice once more, then no names.

      Figure 1-5: Your meandering conversation stack

      In our conversation stack, the new topics are added to the top of the stack and taken off as they are completed. The previous topics are remembered underneath the current topic in the stack.

      We can use Python lists as stacks if, to amend the list’s contents, we limit ourselves to the append() and pop() methods to perform pushing and popping. JavaScript arrays can also be used as stacks through their push() and pop() methods.

      Note

      Python uses the terms list and item, while JavaScript uses the terms array and element, but they are respectively identical for our purposes. In this book, I use the terms list and item for both languages.

      For example, consider this cardStack.py program, which pushes and pops string values of playing cards to the end of a list named cardStack:

      Python

      cardStack = ❶ [] ❷

      cardStack.append('5 of diamonds')

      print(','.join(cardStack))

      cardStack.append('3 of clubs')

      print(','.join(cardStack))

      cardStack.append('ace of hearts')

      print(','.join(cardStack))

      cardStack.pop()

      print(','.join(cardStack))

      The following cardStack.html program contains the equivalent code in JavaScript:

      JavaScript

      let cardStack =

      ❶ []; ❷

      cardStack.push(5 of diamonds);

      document.write(cardStack +
      );

      cardStack.push(3 of clubs);

      document.write(cardStack +
      );

      cardStack.push(ace of hearts);

      document.write(cardStack +
      );

      cardStack.pop()

      document.write(cardStack +
      );

      When you run this code, the output looks like this:

      5 of diamonds

      5 of diamonds,3 of clubs

      5 of diamonds,3 of clubs,ace of hearts

      5 of diamonds,3 of clubs

      The stack starts off as empty ❶. Three strings representing cards are pushed onto the stack ❷. Then the stack is popped ❸, which removes the ace of hearts and leaves the three of clubs at the top of the stack again. The state of the cardStack stack is tracked in Figure 1-6, going from left to right.

      Timeline showing playing cards stacked on top of each other at various points in time. Begins with no cards, then the five of diamonds, then the three of clubs on top of the five of diamonds, then the ace of hearts on top of the three of clubs, and finally the ace of hearts removed to reveal the three of clubs.

      Figure 1-6: The stack starts empty. Cards are then pushed onto and popped off the stack.

      You can see only the topmost card in the card stack, or, in our program’s stacks, the topmost value. In the simplest stack implementations, you can’t see how many cards (or values) are in the stack. You can see only whether the stack is empty or not.

      Stacks are a LIFO data structure, which stands for last in, first out, since the last value pushed onto the stack is the first value popped out of it. This behavior is similar to your web browser’s Back button. Your browser tab’s history functions like a stack that contains all the pages you’ve visited in the order that you visited them. The browser is always displaying the web page at the top of the history’s stack. Clicking a link pushes a new web page onto the history stack, while clicking the Back button pops the top web page off and reveals the one underneath.

      What Is the Call Stack?

      Programs use stacks too. The program’s call stack, also simply called the stack, is a stack of frame objects. Frame objects, also simply called frames, contain information about a single function call, including which line of code called the function, so the execution can move back there when the function returns.

      Frame objects are created and pushed onto the stack when a function is called. When the function returns, that frame object is popped off the stack. If we call a function that calls a function that calls a function, the call stack will have three frame objects on the stack. When all these functions return, the call stack will have zero frame objects on the stack.

      Programmers don’t have to write code dealing with frame objects, since the programming language handles them automatically. Different programming languages have different ways of implementing frame objects, but in general they contain the following:

      The return address, or the spot in the program where the execution should move when the function returns

      The arguments passed to the function call

      A set of local variables created during the function call

      For example, take a look at the following localVariables.py program, which has three functions, just as our previous functionCalls.py and functionCalls.html programs did:

      Python

      def a():

       

      spam = 'Ant'

       

      print('spam is ' + spam)

       

      b()

          print('spam is ' + spam)

       

      def b():

       

      spam = 'Bobcat'

          print('spam is ' + spam)

       

      c()

          print('spam is ' + spam)

       

      def c():

       

      spam = 'Coyote'

          print('spam is ' + spam)

       

      ❼ a()

      This localVariables.html is the equivalent JavaScript program:

      JavaScript

      function a() {

       

      let

      Enjoying the preview?
      Page 1 of 1