Asking for help as an O(1) lookup

Main idea: When you have a question and are googling around for an answer, you’re basically searching through a space of information, and seeking an answer to your question in this space. Sometimes you’re able to find your answer quickly. Sometimes you aren’t. But if you are able to ask someone for help, they’ll often be able to just tell you the answer right away. This is helpful and is analogous to an O(1) lookup in programming.

In elaborating on this, I will start by discussing what Big-O notation is, and then I will talk about how it applies to asking for help.

  • If you’re already familiar with Big-O notation, you’ll probably want to skip to the “Asking For Help” section.

  • If you aren’t too familiar with Big-O notation, I tried to write this in such a way that non-programmers (who are at least a little bit mathematically inclined and/​or have some vague sense of what programming looks like) would be able to understand. I’m not sure how successful I was though.

Big-O

Math

In programming, Big-O notation is a thing.

Actually, no. It’s not a programming thing. It’s a math thing.

Imagine you have the function f(x) = 2x^2 + 7x + 22. I’m not sure exactly how to phrase this… but approximately how fast does f(x) grow? Well, we could just squint and look the highest order term, which is x^2 here, and say that it has quadratic growth.

And then we can say that g(x) = 7x^3 + 4x^2 + 9x + 88 has x^3 as it’s highest order term, which we call polynomial growth.

And for h(x) = 6x + 2, it’s linear growth.

Saying that h(x) grows linearly isn’t as precise as saying that it grows according to the expression 6x + 2. However, it is easier to say when chatting casually. We can use phrases like “this grows linearly” and “this grows quadratically”.

Programming

In programming[1], we apply Big-O notation to something called time complexity. Basically, we want to know how long it will take for a function to run.[2] Is it going to take linear time? Exponential time? Etc.

For example, the following function[3] will take linear time to run. We’re iterating through the list, item by item.

function getSummation(list) {
  var summation = 0;
  
  for (var i = 0; i < list.length; i++) {
    sum += list[i];
  }
  
  return summation;
}

On the other hand, the following function will take quadratic time to run. We’re iterating through the list… but for each element in the list, we iterate through the list again.

function getResult(list) {
  var result = 0;
  var temp;
  
  for (var i = 0; i < list.length; i++) {
    temp = 0;
  
    for (var j = 0; j < list.length; j++) {
      temp += list[i] * list[j];
    }
    
    result += temp;
  }
  
  return result;
}

Here’s a different example. You know that game where someone asks you to guess a number between 1 and 100 and will tell you if your guess is too high or too low? The strategy[4] is to start by guessing 50, then maybe they tell you it’s too low, so you guess 75. Then they tell you it’s also too low, so you guess 87. So on and so forth.

The idea is that, for each of our guesses, we want to reduce the search space by as much as possible. Initially the search space has a size of 100. Imagine that we guessed 10 and were told that we’re too low. Now we know that the answer is between 11 and 100. This only reduced the search space by 10 though. Instead, if we guess 50, we can cut it in half.

And by cutting it in half with each of our guesses, we can arrive at our answer in logarithmic time. Which is much faster than linear time (ie. performing an exhaustive search by going one-by-one).

There’s something cool though. It’s called constant time. Let’s go back to math for a second here. How fast does the following function grow?

f(x) = 5

Well, um, it doesn’t.

Ok, now let’s jump back to programming. How long does the following function take to run?

function getLastElement(list) {
  return list[list.length - 1];
}

I won’t describe why it is the case since I think that’d be too much of a tangent, but just take my word for it: the code is able to grab and return the last element ~immediately.

So for example, if list is [1,2,3], it’ll grab 3 just as quickly as it would grab 100 in a list of 1-100. As an imperfect analogy, imagine that you have 10 apples in front of you. You can grab the third apple just as quickly as you can grab the 10th.[5]

Asking For Help

When you have a question and are googling around for an answer, you’re basically searching through a space of information, and seeking an answer to your question in this space.

<thead>

For example, earlier today I was seeking an answer to the question of what the purpose of the <thead> HTML element is.

The space of possible information includes things like, oh, I don’t know:

  • Wikipedia

  • StackOverflow

  • Surely You’re Joking, Mr. Feynman

Given that I’m not a rock, I can use my judgement and infer that walking over to my bookcase and opening up Surely You’re Joking Mr. Feynman is unlikely to lead to me figuring out what the purpose of the <thead> HTML element is. Similarly, I’m 100-ε% confident that opening my refrigerator is not going to yield the answer I’m looking for. By not being a rock, you can narrow down the search space by a massive, massive, massive amount.

As seen in the diagram above, there are a bunch of places I can look where it’s plausible that I find an answer to my question:

  • MDN

  • Stack Overflow

  • Google search results

  • YouTube

  • Intellisense

  • Claude

Still, exploring this space isn’t always fruitful. It wasn’t for me.

  • I started off looking at the MDN page for <thead>, but to my surprise, it didn’t have an answer to my question.

  • Then I looked at the MDN page for <table>, and it too didn’t have what I was looking for.

  • Next I looked around on Stack Overflow. I wasn’t really finding good answers there though. They didn’t seem authoritative or thorough (1, 2, 3).[6]

  • From there I googled duckduckgoed[7] around. Still no success.

  • Then I went back to Stack Overflow. I looked through the highest voted questions that were tagged html-table. Still no success.

At this point, a lesser[8] web developer would have given up. But being the stallion that I am, I grit my teeth and continued my stackoverflowing.

Soon after, my efforts were rewarded. My curiosity was satiated as I discovered that aside from accessibility and semantics, there are in fact concrete reasons to use <thead>:

  1. To allow the body to be scrolled independently of the header and/​or footer

  2. To make it easier to apply different style rules to the different sections of the table.

Anyway, this post isn’t actually supposed to be about <thead>. The bigger point is that there was actually a decent amount of friction in finding an answer to my question. And, relatedly, if I was able to just ask someone, it’d be much easier. An O(1) lookup instead of an O(?) lookup.

Of course, this doesn’t mean that asking for help immediately is always what you should do. I’m just pointing out an advantage.

In practice, most people recommend spending N minutes looking into it yourself before asking for help. My impression is that N ranges from, say, 10 minutes to 120 minutes in most contexts. And I usually endorse this recommendation. Seek to overcome the obstacle of trivial inconveniences, a good hacker must.[9]

Quinoa

Let me tell you about what drove me to think about this.[10]

I had this startup idea to let people pay to video chat with chefs. Like, suppose your chicken always comes out dry and you want to do better. Wouldn’t it be cool if you could pay $20 or so to hop on a quick call and talk it through with a real chef?

In discussing this with people, I was told (universally) that there’s no need: you could just google it or go on YouTube.

Which got me thinking. I think there’s a lot of truth to that. However, sometimes it’s just kinda difficult to do so. For cooking chicken breasts, it’s relatively easy to find good guidance.

But what about, I don’t know, using a meat thermometer? I actually ran into difficult with a meat thermometer myself. And despite my well above average google-fu, I just wasn’t really getting the clarity I wanted. So maybe there’s demand here? I’m skeptical and gave up on the idea, but it’s possible that the opportunity is real.

One of the people I spoke with is a popular food YouTuber, Helen Rennie. As a benefit for her Patreons, she offers to respond to emails about cooking questions. I took advantage of this, and it was pretty awesome.

I watched this video of hers on quinoa and sent the following email:

Hey Helen, some Quinoa questions:

1) My rice cooker has a “White Rice” button and a “Brown Rice” button. Which would you recommend? (And what are the differences between them?)

2) What should you do to scale this recipe up? Down?

3) I remember learning (from Cooks Illustrated I think) that the question of how much water to use is ultimately a matter of having enough water such it doesn’t all evaporate. So for a wide pot you’ll need more water than you would for a narrow pot. And, along the lines of what you said in your quinoa video, the lid on a rice cooker is tighter than the lid on a normal pot, meaning less evaporation, meaning you need less water. And, I think somehow it follows from all of this that instead of measuring, you can just fill it up so that the water reaches your first knuckle. Anyway: is this all true for quinoa as well?

4) Any thoughts on freezing it? I find it really convenient to be able to freeze things and warm them up.

And I got a response addressing all of my questions! Awesome!

I’ll spare you the details, but they’re just things I wouldn’t really have been able to easily figure out on my own. So then, the O(1) lookup, in addition to being a really awesome experience, yielded me a resolution to my question in a situation where the O(?) alternative would have been intractable.

  1. ^

    Note that this is further down the ladder of abstraction (I think?) from what we were talking about before (how fast an abstract mathematical function grows).

  2. ^

    In proportion to it’s input. In the worst case scenario. Although best case time complexity and average case time complexity are also things that people care about.

  3. ^

    Note to my fellow JavaScript programmers out there: I’m using function and var in an attempt to make this more easily understood by non-programmers and non-JavaScript programmers.

  4. ^

    Well, at least that’s the strategy if you assume the number between 1 and 100 is chosen at random. That isn’t always the case though.

    Imagine you guess 50, then 75, and then 87. You might anticipate that the person who chose the number wants to mess with you. So instead of guessing 94, then 97, then 99, and then 100, you might just want to guess 100.

    And this is why computers will never be smarter than humans.

    Just kidding.

  5. ^

    Now, if there were 100, the length might be kinda long and so the 100th might take you longer since you have to take a few steps to your right, but if we imagine that you have really long arms, which metaphorically, the computer does have, it’d be just as easy to grab the 100th.

  6. ^

    I didn’t think to do it at the time, but in retrospect, I probably should have checked out the W3C spec. But funnily enough, I just checked it out, and to my surprise again, it didn’t really give me what I was looking for.

  7. ^

    Y’all need a better marketing department.

  8. ^

    Or, alternatively, someone with better things to do on a beautiful Saturday afternoon.

  9. ^

    I don’t actually endorse that post I link to: How To Ask Questions The Smart Way. Well I endorse a lot of what it says, just not all of it. In particular, I think a) the bar for asking a question should be lower (in most contexts) and b) it is too unfriendly.

  10. ^

    Maybe it would have been better if I started the post off with this. It probably would have.