I often find myself frustrated and overwhelmed when people try to explain things to me. It's similar to the guy in this Software engineer interns on their first day be like... video, but with me it's more like "Software engineer after 12 years be like...".
At a high level, the conversations I'm referring to look something like this:
Eric: Here is how A works.
Eric: Here is how B works.
Eric: Here is how C works.
Adam: Um —
Eric: Here is how D works.
Adam: But —
Eric: Here is how E works.
Adam: I —
Eric: Here is how F works...
In this example, B depends on A. In order to understand B, you have to first understand A.
When Eric tried to explain B to me, I didn't understand A yet. Without understanding A, I wasn't ready to hear an explanation of how B works.
Ideally, before explaining B, Eric would have checked in to see if I understand A. Only once I understand A do we have the green light to proceed.
JavaScript
A thought occurred to me the other day: this situation seems analogous to software dependencies. Consider the following JavaScript code:[1]
// b.js
import { a } from 'a';
const result = a + 2;
export { result };
b.js depends on a. Without a, b.js isn't able to run. In order for b.js to run, there needs to be a node_modules directory with an a package. Something like this:
b.js node_modules/ a/ package.json index.js
Suppose you want to run b.js but see that node_modules is missing a. You can run npm install a to download the dependency.
Returning to the analogy with Eric:
In explaining B to me, it's like Eric is trying to run b.js.
Because I didn't yet understand A, it's as if my node_modules didn't have an a package.
Ideally, before running b.js, Eric would have "checked my node_modules", seen that my "a package" was missing, and "ran npm install a".
Complex
In a more complicated situation, Eric might want to utilize something like package.json and npm install. For example, consider the following:
In order to understand F, you need to understand D and E. But to understand D, you need B and C. And to understand B, you need A.
Eric doesn't want to think about all of that though. He just wants to declaratively say something like:
Listen, I want to explain F to you. However, to know F you'll need to know D and E. I'm not sure what you'll need to do to learn D and E. Figure it out yourself. Go out, get D and E, and come back to me when you're done.
The "you'll need to know D and E" part is like f.js's package.json. The "go out and get them" part is like npm install.
Built in
In JavaScript, something like Math is built in. There's no package you need to install if you want to do something like Math.abs(n).
I think the real-life parallel here is that sometimes, yes, there's a dependency, but you don't need to worry about whether the thing "exists in node_modules". You could safely assume that it is just part of the "standard library".
Different people have different "standard libraries". Something like "EC2 instance" might be part of a DevOps engineer's standard library — no need to check node_modules. However, if you're talking to a front end engineer and want to reference "EC2 instance", it might require an npm install.
Debugging
Sometimes a dependency might not give you the output you are expecting, especially when it was written by someone else. When this happens, you might need to open up the hood, get your hands dirty, and explore how the library works.
This happened to me the other day. I had an MRI scheduled for Monday 10/26 and a follow-up appointment with the doctor on Monday 11/2. The receptionist explained to me that it takes up to five days to get the MRI results and that they will be ready in time for my follow-up appointment.
Then on 10/26 they called me to let me know they had to cancel the MRI. We rescheduled it for Wednesday 10/28. I then gave the doctor's office a ring to check in on my appointment.
I explained the situation: given that my MRI was pushed back, I was wondering whether we needed to push back my doctor's appointment as well. The receptionist responded by saying something like "no, the doctor should have the results in time".
To me, in this context, the word "should" has a connotation of uncertainty. When you know something will happen, you usually don't say that it should happen, you say that it will. You wouldn't say that the sun should rise tomorrow, you say that it will. So then, I explained that by saying "should" it sounded to me like she might not be sure whether the doctor will have the results in time, and I want to clarify whether she's sure or whether it'd make sense to investigate further. She responded by saying something like "no, I think he should have it in time".[2]
It didn't seem worth harping on so I dropped it, but it's interesting to think about what "debugging" would look like here though.
I'd need to investigate this should function. Where is it coming from? Is it built in to the runtime? What runtime is she using? Where is the source code? What happens when I call should with different values? What results do I get? Maybe it's in node_modules? Did it come from the NPM registry? Some weird private registry? Is the GitHub repo sketchy?
Context
JavaScript runtimes are dumb. Consider again the following:
// b.js
import { a } from 'a';
const result = a + 40;
export { result };
If a doesn't exist you won't be able to run b.js. You'll get an error.
With humans, I think the runtime is a lot more capable. Consider a related example:
// hitchhikers-guide-to-the-galaxy.js
import { a } from 'a';
const answerToTheUltimateQuestionOfLifeTheUniverseAndEverything = a + 2;
Yes, it looks like a is a dependency, but imagine that a isn't found. To a human, that's no problem. The human can infer what a is by looking at the context.
The file's name is hitchhikers-guide-to-the-galaxy.js.
The constant is named answerToTheUltimateQuestionOfLifeTheUniverseAndEverything.
Clearly we want a value of 42 for the constant. a must be 40.
Now let's return to the example with Eric. In practice, if you're missing a dependency, you may not want to panic just yet. Like, when Eric starts saying, "Here is how B works", you may not want to be like:
WAIT!!! Eric, stop! I don't understand A yet! You must discontinue your explanation!
Instead, you may want to hear him out and see if things make sense once you have more context.
Soft
JavaScript runtimes are dumb. Consider the following:
// sentence.js
import { adjectiveOne } from "adjective-one"; import { adjectiveTwo } from "adjective-two"; import { adjectiveThree } from "adjective-three"; import { noun } from "noun"; import { verb } from "verb";
Again, if a dependency is missing, you'll get an error if you try to run sentence.js. The dependencies are hard.
On the other hand, for humans, dependencies aren't always hard. Some are softer than others.
I think that for a human, the adjectives are softer than the noun and verb. If the adjectives are missing but the noun and verb are found, you could still get something workable like "The dog ran".[3] If one adjective is present, it's better: "The cute dog ran". But if, say, the noun went missing, you'd get "The cute ran". That doesn't work.
Memory hierarchy
Programmers need to keep something called the memory hierarchy in mind when they write their code. We mainly talk about stuff being "on disk" and stuff being "in memory". Stuff that is on disk is slow to access; stuff that is in memory is fast to access; there's not a lot of capacity to store stuff in memory; there is a lot of capacity to store stuff on disk.
I think this is relevant to the dependency analogy. Here's an example. For me, the concept of database partitioning is something that is "stored", but not in a way that is fast to access. It's on disk, it's not in memory. So then, if someone explains X to me in a way that references a dependency on database partitioning, things could get a little hairy.
One possibility is that we pause and wait for my high latency lookup on disk to complete. Another possibility is that we march ahead before the lookup completes.
In the latter case, the "Context" and "Soft" sections of this post become relevant. Maybe we take a few steps forward in the conversation. Maybe with that added context I am able to fill in the gaps. Maybe the dependency was soft and didn't get in the way too much. Maybe the lookup runs in the background and deepens my understanding when it eventually completes. Or maybe the lookup stalls and proves to be a blocker that I'm not able to recover from.
Yes, in order to understand this post you might need to understand how dependencies in JavaScript work. Then again, you might be able to get by without that knowledge, especially if you understand how dependencies work in other programming languages.
Humans are often able to apply context to "fill in" missing dependencies. They're also often able to treat dependencies as "soft" rather than "hard". See the corresponding sections in the post for further discussion of these ideas.
I don't mean to be condescending here. Maybe you could argue that good semantics is cooperative and bad semantics is defect-y, and that she's being defect-y here. I suppose I'd make that argument, but a) no one's perfect and b) I think the magnitude of the defect is quite small.
I don't mean to be condescending here. Maybe you could argue that good semantics is cooperative and bad semantics is defect-y, and that she's being defect-y here. I suppose I'd make that argument, but I think the magnitude of the defect is quite small.
I often find myself frustrated and overwhelmed when people try to explain things to me. It's similar to the guy in this Software engineer interns on their first day be like... video, but with me it's more like "Software engineer after 12 years be like...".
At a high level, the conversations I'm referring to look something like this:
In this example, B depends on A. In order to understand B, you have to first understand A.
When Eric tried to explain B to me, I didn't understand A yet. Without understanding A, I wasn't ready to hear an explanation of how B works.
Ideally, before explaining B, Eric would have checked in to see if I understand A. Only once I understand A do we have the green light to proceed.
JavaScript
A thought occurred to me the other day: this situation seems analogous to software dependencies. Consider the following JavaScript code:[1]
// b.js
import { a } from 'a';
const result = a + 2;
export { result };
b.jsdepends ona. Withouta,b.jsisn't able to run. In order forb.jsto run, there needs to be anode_modulesdirectory with anapackage. Something like this:b.jsnode_modules/
a/
package.json
index.js
Suppose you want to run
b.jsbut see thatnode_modulesis missinga. You can runnpm install ato download the dependency.Returning to the analogy with Eric:
b.js.node_modulesdidn't have anapackage.b.js, Eric would have "checked mynode_modules", seen that my "apackage" was missing, and "rannpm install a".Complex
In a more complicated situation, Eric might want to utilize something like
package.jsonandnpm install. For example, consider the following:In order to understand F, you need to understand D and E. But to understand D, you need B and C. And to understand B, you need A.
Eric doesn't want to think about all of that though. He just wants to declaratively say something like:
The "you'll need to know D and E" part is like
f.js'spackage.json. The "go out and get them" part is likenpm install.Built in
In JavaScript, something like
Mathis built in. There's no package you need to install if you want to do something likeMath.abs(n).I think the real-life parallel here is that sometimes, yes, there's a dependency, but you don't need to worry about whether the thing "exists in
node_modules". You could safely assume that it is just part of the "standard library".Different people have different "standard libraries". Something like "EC2 instance" might be part of a DevOps engineer's standard library — no need to check
node_modules. However, if you're talking to a front end engineer and want to reference "EC2 instance", it might require annpm install.Debugging
Sometimes a dependency might not give you the output you are expecting, especially when it was written by someone else. When this happens, you might need to open up the hood, get your hands dirty, and explore how the library works.
This happened to me the other day. I had an MRI scheduled for Monday 10/26 and a follow-up appointment with the doctor on Monday 11/2. The receptionist explained to me that it takes up to five days to get the MRI results and that they will be ready in time for my follow-up appointment.
Then on 10/26 they called me to let me know they had to cancel the MRI. We rescheduled it for Wednesday 10/28. I then gave the doctor's office a ring to check in on my appointment.
I explained the situation: given that my MRI was pushed back, I was wondering whether we needed to push back my doctor's appointment as well. The receptionist responded by saying something like "no, the doctor should have the results in time".
To me, in this context, the word "should" has a connotation of uncertainty. When you know something will happen, you usually don't say that it should happen, you say that it will. You wouldn't say that the sun should rise tomorrow, you say that it will. So then, I explained that by saying "should" it sounded to me like she might not be sure whether the doctor will have the results in time, and I want to clarify whether she's sure or whether it'd make sense to investigate further. She responded by saying something like "no, I think he should have it in time".[2]
It didn't seem worth harping on so I dropped it, but it's interesting to think about what "debugging" would look like here though.
I'd need to investigate this
shouldfunction. Where is it coming from? Is it built in to the runtime? What runtime is she using? Where is the source code? What happens when I callshouldwith different values? What results do I get? Maybe it's innode_modules? Did it come from the NPM registry? Some weird private registry? Is the GitHub repo sketchy?Context
JavaScript runtimes are dumb. Consider again the following:
// b.js
import { a } from 'a';
const result = a + 40;
export { result };
If
adoesn't exist you won't be able to runb.js. You'll get an error.With humans, I think the runtime is a lot more capable. Consider a related example:
// hitchhikers-guide-to-the-galaxy.js
import { a } from 'a';
const answerToTheUltimateQuestionOfLifeTheUniverseAndEverything = a + 2;
export { answerToTheUltimateQuestionOfLifeTheUniverseAndEverything };
Yes, it looks like
ais a dependency, but imagine thataisn't found. To a human, that's no problem. The human can infer whatais by looking at the context.hitchhikers-guide-to-the-galaxy.js.answerToTheUltimateQuestionOfLifeTheUniverseAndEverything.Clearly we want a value of
42for the constant.amust be40.Now let's return to the example with Eric. In practice, if you're missing a dependency, you may not want to panic just yet. Like, when Eric starts saying, "Here is how B works", you may not want to be like:
Instead, you may want to hear him out and see if things make sense once you have more context.
Soft
JavaScript runtimes are dumb. Consider the following:
// sentence.js
import { adjectiveOne } from "adjective-one";
import { adjectiveTwo } from "adjective-two";
import { adjectiveThree } from "adjective-three";
import { noun } from "noun";
import { verb } from "verb";
const sentence = `The ${adjectiveOne} ${adjectiveTwo} ${adjectiveThree} ${noun} ${verb}`;
export { sentence };
Again, if a dependency is missing, you'll get an error if you try to run
sentence.js. The dependencies are hard.On the other hand, for humans, dependencies aren't always hard. Some are softer than others.
I think that for a human, the adjectives are softer than the noun and verb. If the adjectives are missing but the noun and verb are found, you could still get something workable like "The dog ran".[3] If one adjective is present, it's better: "The cute dog ran". But if, say, the noun went missing, you'd get "The cute ran". That doesn't work.
Memory hierarchy
Programmers need to keep something called the memory hierarchy in mind when they write their code. We mainly talk about stuff being "on disk" and stuff being "in memory". Stuff that is on disk is slow to access; stuff that is in memory is fast to access; there's not a lot of capacity to store stuff in memory; there is a lot of capacity to store stuff on disk.
I think this is relevant to the dependency analogy. Here's an example. For me, the concept of database partitioning is something that is "stored", but not in a way that is fast to access. It's on disk, it's not in memory. So then, if someone explains X to me in a way that references a dependency on database partitioning, things could get a little hairy.
One possibility is that we pause and wait for my high latency lookup on disk to complete. Another possibility is that we march ahead before the lookup completes.
In the latter case, the "Context" and "Soft" sections of this post become relevant. Maybe we take a few steps forward in the conversation. Maybe with that added context I am able to fill in the gaps. Maybe the dependency was soft and didn't get in the way too much. Maybe the lookup runs in the background and deepens my understanding when it eventually completes. Or maybe the lookup stalls and proves to be a blocker that I'm not able to recover from.
Yes, in order to understand this post you might need to understand how dependencies in JavaScript work. Then again, you might be able to get by without that knowledge, especially if you understand how dependencies work in other programming languages.
Humans are often able to apply context to "fill in" missing dependencies. They're also often able to treat dependencies as "soft" rather than "hard". See the corresponding sections in the post for further discussion of these ideas.
I don't mean to be condescending here. Maybe you could argue that good semantics is cooperative and bad semantics is defect-y, and that she's being defect-y here. I suppose I'd make that argument, but a) no one's perfect and b) I think the magnitude of the defect is quite small.
Is "past tense verb" like "ran" still a verb? Probably not, but meh.
I don't mean to be condescending here. Maybe you could argue that good semantics is cooperative and bad semantics is defect-y, and that she's being defect-y here. I suppose I'd make that argument, but I think the magnitude of the defect is quite small.