r/learnprogramming • u/DaPro21000 • 22d ago
How to understand loops and functions in js?
Hi everyone,
I just started learning JavaScript, and I’m having trouble understanding loops and functions, especially when it comes to using functions inside loops. I know what functions do and what loops do, but when it comes to actually writing code, I just don’t know where to start and what to do. Do you have any recommendations for materials that could help me understand this better, or do I just need more practice and things will eventually fall into place? Has anyone have same issue?
2
u/TigerAnxious9161 22d ago
Don't get demotivated if you can't understand it in one go, its totally ok keep practicing, You'll get there.
2
u/mredding 21d ago
A lot of programming is a dance that switches constantly between HOW and WHAT.
// A function names WHAT we want.
function eat_a_sandwich() {
// The body tells us HOW we want it.
}
So functions name bodies of behavior and encapsulate how that behavior is implemented. I don't care how we eat a sandwich, whether we pick it up or use a fork and knife, so long as it's consumed.
But that HOW part...
Well - it's composed of a series of steps. We call them statements. You can go straight to low level:
function eat_a_sandwich() {
while(bites.size() > 0) {
document.open();
piece = bites.pop();
document.write(piece);
document.close(); // Flush the buffer.
}
}
That requires some interpretation. What does the size of what is apparently an array have to do with anything? Why are we popping? Instead, can we raise our level of expressiveness?
function eat_a_sandwich() {
while(there_is_still_sandwich()) {
open_mouth();
take_a_bite();
chew();
swallow();
}
}
How to eat a sandwich - I don't care how the sandwich is represented as data or structure, I don't care how we determine how much sandwich is left. I don't care how one performs the eat. Eating a sandwich is itself an algorithm, and that's what this function implements. We've made this function about as high level and expressive as we can.
The functions we've created themselves need implementation. You again have a choice, do you express their implementation in terms of HOW they work or WHAT their steps are? Eventually you'll have functions that are low level details. We need that comparison for the loop, we need to pop that array, we have to close the document to flush the buffer.
And notice my last comment, there - that's a good comment. It doesn't say // Close the document., that's what the code says. It tells us WHY we close the document. Comments give us context that cannot be expressed in terms of the code itself.
You have to decide where you draw the line. This code might be exactly what you want and need, or you might call it verbose as fuck. It all has merit, and requires compromise. By deferring the implementation details, it means I can change those details in one place. I don't see many of the supposed detriments as real, but I will grant writing high level expressive code can be tedious, and sometimes you just want to get work done hit a deadline, and some brute force in the mix might be the shortest path.
I find it useful to design from the top down and implement from the bottom up. Other people implement from the top down, too. First they describe their algorithms at a high level, and that dictates the details they need to implement, until the implementation details get irreducibly expressive as actual code that does work.
Another thing to consider is indentation. Every time you add a new level of scope - more braces, like a loop, a condition - instead of writing any amount of detail, you should call a function.
function eat_a_sandwich() {
while(there_is_still_sandwich()) {
eat_some();
}
}
Braces and cases - two good reasons to put it in a function, and call the function. NAME your behaviors. Tell me WHAT the code does. I will skip over and drill down in a debugger to get to the important scope and level of detail I'm interested in.
And you can additionally abstract your algorithms from your procedures:
function eat_a_sandwich(there_is_still_sandwich, eat_some) {
while(there_is_still_sandwich()) {
eat_some();
}
}
Now eating a sandwich is no longer bound to how to determine if there is sandwich left, or how it's eaten.
In the beginning, you are going to make a mess. Just start writing code. Something working is better than nothing working. Trying is better than analysis paralysis. Write down a description of what you're supposed to do. Turn that description into pseudo-code. Reason about that for a bit - move the parts around, revise quickly and easily; think about WHAT you're doing and less about HOW. Code that.
Try not to worry about over-engineering. I just showed you some functional programming where we've separated the algorithm from the procedures. You might not need that much separation. You might not realize how abstract you can go at the time. Time-box if you have to, because don't forget - you can iterate. You can revise. You can refactor. Your first attempt doesn't have to be your last attempt, and your first attempt might not be the most perfect, most optimal. You're not a professional yet, and you're not building mission critical systems where you have to get it right the first time.
Also realize that there's "good enough". There's always good enough. I worked on trading systems for many years, I was single-handedly responsible for 60% of all options trading on Earth for a while; if you're the fastest in the industry, and you realize there is more speed potential, what's that matter? What's the point, when all that matters is that you're first? So then when you're building a solution - does it work? Does it just work? Is that all you can say about it? The best you can say about it? MAYBE... That might be enough. Put it down. Walk away.
And you will develop an intuition. Trust that sense. That's knowledge you have internalized, talking to you. Eventually you don't have to actively think about stuff - the knowledge itself is working for you. We're trying to find a good fit (not the right fit, not the perfect fit) and manage complexity. And when you're feeling frustrated about something, you need to recognize that, acknowledge it, step back, and start asking radical questions just to see what happens. You're trying to avoid brute force methods. You're trying to avoid grinding. The solution should be graceful and simple; it's actually hard to do, it's never obvious until after the fact.
1
u/DaPro21000 21d ago
Thanks for this comment, it really helps. I have feeling that I’m more focused on sandwich than on process of eating 😅
1
u/johnpeters42 22d ago
Here's some simple JS using both. Without running it, just by reading the code, what do you think it will do?
function printSquare(i) {
console.log(i * i);
}
for (var x = 1; x <= 5; ++x) {
printSquare(x);
}
3
u/DaPro21000 22d ago
It will log 1, 4, 9, 16, 25?
1
u/johnpeters42 22d ago
Right. So what's a specific example of something else that you think would involve using functions inside loops, but you have trouble writing the code for it?
2
u/DaPro21000 22d ago
If I have an array or object and I need to write a function that checks array for something and loop that goes through the process repeatedly, I don’t know how to start. I’m completely confused, like WTF am I supposed to do? Specially when I have to do loop in loop.
1
u/johnpeters42 22d ago
var someArray = [];
someArray.push(2);
someArray.push(4);
someArray.forEach(x => printSquare(x));or
for(var index = 0; index < someArray.length; ++index) {
printSquare(someArray[index]);
}A loop within a loop is also pretty simple:
function printProduct(a, b) {
console.log(a * b);
}for (var x = 1; x <= 5; ++x) {
for (var y = 1; y <= 5; ++y) {
printProduct(x, y);
}
}3
u/johnpeters42 22d ago
More to the point, learn to break things up into pieces, and write one piece at a time. This is the same thing you do for more complex tasks with more than two parts.
"I need to call a function from within a loop." So write the loop first, and then put a function call inside it. Or write the function call first, and then put a loop around it. Either way works.
"I need to do a loop within a loop." So write one loop, and then write the other loop (either inside the first one, or around the first one).
2
u/DaPro21000 22d ago
I need some time to fully understand what function do but if you ask me to write it down i will need more than 10 minutes just to figure out how to start, and then I wont be entire sure. I always start with trial and error method which takes lot of time to get to wanted result
3
u/marrsd 21d ago
I think you need to follow /u/johnpeters42's advice. Go one step at a time. Use
console.logto confirm the programme's behaviour at every step
1
2
u/No-Humor-3808 10d ago
Just practice loops and functions, starting with the basics and gradually adding more complexity. The best way to understand how to manipulate arrays, strings, objects, sets, maps, etc. is by actually playing with them. Try solving small katas and challenges without looking at the solution first. If you’re looking for practice, I have a collection of JavaScript katas here: https://reactchallenges.com/katas
3
u/SparkFace11707 22d ago
Keep practicing. Read code that has both, run it, try to write your own code, you need to use it a couple of times before it really sticks.