So I'm working through Eloquent Javascript, and I'm supposed to compose a function out of other functions. Fine. The concept does make sense to me, and I think I'm a pretty dedicated study.
But then I run into this:
function countBy(items, groupName) {
let counts = [];
for (let item of items) {
let name = groupName(item);
let known = counts.findIndex(c => c.name == name);
if (known == -1) {
counts.push({name, count: 1});
} else {
counts[known].count++;
}
}
return counts;
}
This is frustrating, so I'm writing this post mostly as a way of unblocking myself and walking through the process of building an understanding of code.
I can tell that it's a function called countBy, with parameters "items" and "groupName". I can tell that it initializes an empty array called "counts".
Where I start having trouble is the for/of loop. "item" isn't defined anywhere in the code, and I haven't been introduced to it anywhere else in the text.
Well, that's fine. We're supposed to know how to google stuff, right? I'll start with searing for "for of loop js".
That lands us at MDN. Great, now I can figure out how the loop works and be on my way!
Let's look at what's on the page:
The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, Array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.
so the loop iterates over iterable objects. This begs a few questions:
- what do you mean by "iterates over"?
- what is an iterable object?
I'm guessing that the answer to question 1 is that it's similar to the way that we can access each item in an array by feeding it through this code:
for (let i = 0; i < array.length; i++){
array[i];
}
Okay, not bad so far. However, what I need are the specifics. I know how to get the current item out of an array, but where does this thing put the name of the thing we're iterating over? Where does it put the values associated with those names?
I'll look at the docs again to figure it out.
function* foo(){
yield 1;
yield 2;
}
for (let o of foo()) {
console.log(o);
// expected output: 1
break; // closes iterator, triggers return
}
Well, I can see (let o of foo()) and console.log(o), so it would seem to me that "o" is similar to the "i" in my earlier for loop. However, what does the "o" correspond to? is it the location/name or the value of whatever I'm looping through?
The expected output is 1. That seems to correspond to the first primitive value I see in the function. yield 1. But I don't know what "yield" actually does, so now I have to look that up. Luckily MDN has a page for that too.
The yield keyword is used to pause and resume a generator function (function* or legacy generator function).
Okay, what the fuck.
I don't know what a generator function is, or what a legacy generator function is.
Now my choices are to either dig into what a generator function is, or to pop back over to the for/of page and try to find a different example.
Let's do the latter, obviously. No need to keep digging myself deeper.
let iterable = [10, 20, 30];
for (let value of iterable) {
console.log(value);
}
// 10
// 20
// 30
Okay, that's much better. It looks like, in this for/of loop, we're not dealing with indexes or w/e. We just get the value of each item in the array via "value" during each loop. I'm pretty sure I can work with this.
But I do want to talk about one part of the way this documentation works. It's not explicitly stated that the bits that are commented out are what's expected to be logged to the console.
// 10
// 20
// 30
For me, that's not a problem. I've done enough JS that I guessed that that's probably what it was, and could test it myself in order to verify that I was correct, since I know how to use a js console/websites like replit that will give you a sandbox. However, if you had put me in front of this bit of documentation about a month ago, I might not have been able to intuit that bit of information, or known how to test it.
This is what I was talking about in my previous post. I don't know where you'd actually go as a total newbie in order to pick up that information, except to ask someone more experienced than you. There are a million little pain points like this, which feel completely arbitrary and unexpected as you're getting started. Simple things that could be solved in a matter of minutes if you knew where/who/how to ask, but can absolutely crush your momentum and motivation if you don't have that kind of access.
This is where "just google it" or "read the docs" is insufficient, or, if it is, it severely undersells the amount of time and effort it takes to google the answer to a problem, which can be discouraging.
What I find truly pleasurable about programming is a certain sense of consistency; given that you have an understanding of basic operations, you can logically build up any sort of functionality you need. It's the moments where this seems to fail, or to be blockaded by an arbitrary bit of knowledge or convention that I'm lacking that I'm most painfully frustrated by the process.
Now, after all of this, I still have to look up how the findIndex method works, and hope that my knowledge and skills are in the right place to be able to parse that documentation before I've spent all the focus I'm able to, and then I can finally do the work of actually figuring out how I'm going to feed countBy into or out of other functions (granted that I don't have to repeat this process too many times with the rest of the functions I'm trying to compose).
This is why I have bags under my eyes.
Top comments (2)
As I see in the last few years every bootcamp and training site created ads and tried to sell you "programming" as an easy-peasy activity paved by beanbags, craftbeer in the fridge and unicorns, and you can be a codemonkey in 4 months or so and get 100k$
Besides I think these struggles which you mentioned in your 2 posts remain the same but you will adapt to it (of course as your experience is growing you can build more complex solutions without any help)
I don't read Eloquent JS, but I checked the reviews on Amazon, maybe it's not the perfect for absolute beginners... at the same time as a beginner you should resist the temptation to dig deep every unknown topic instantly rather just follow the "flow" of the chosen book or course.
You are right that it's probably not an ideal book to start with, but my point isn't that programming is supposed to be easy. Rather, it's that there's some kind of set of knowledge that you need in order to even start, and that it's often not articulated very well for self-learners.
Navigating convention is different than building functionality, and it's a sort of "learning" that has nothing to do with your ability to reason, just your ability to have prerequisite knowledge, or to have someone tell you. I don't see a good reason that this should be the case.
Neither is it really that I'm even digging deeply into a topic. I have a function and I'm supposed to think about how to use it as part of a larger function. In order to do that, I need to actually understand what kinds of arguments I can pass into the function and what it will return/what side effects it will have. I am trying to illustrate some of the difficulties that arose for me when trying to work through that process.
Perhaps as I get better at this, it's something that I could take up or start to document. I just wanted to put it out into the world while I'm working through it.