DEV Community

Types of Loops

Tamir Bahar on January 27, 2018

Recently I've been helping & tutoring some true code beginners. Not someone new to a language, but completely new to programming. I've done a ...
Collapse
 
theldoria_47 profile image
theldoria

Your "action" loop is normally called mapping, used for either side effects (this is your "action") or "transforming" sequences, see here for an example clhs.lisp.se/Body/f_map.htm.

Then there is your "count", which could be seen as a special case of reduce. Reduce is used to apply a function to a sequence using an operator, see clhs.lisp.se/Body/f_reduce.htm.

Btw, Ruby's array class (ruby-doc.org/core-2.2.0/Array.html) is a good source of "loop" operations. It contains "map", "reduce" and also other common loop operations as "include?" (your find), "delete", "drop", "each" (often used for your action), "keep_if", "reverse", "sort", "shift", "slice" amd much more...

Collapse
 
tmr232 profile image
Tamir Bahar

I agree. Those operations have better names and are part of larger use-cases or patterns.
The problem with those better names is that for beginners, they mean nothing. If you go to a beginner, who never ever coded before, and tell them to "reduce" an array, they will just stare at you wide-eyed.

The C++ <algorithm> header is also a great source for such operations. But again - too advanced.

Collapse
 
louy2 profile image
Yufan Lou

Personally my favorite source of names is Haskell. In the case of loops you can get them from Data.List.

The abstract names like "map", "fold" and "scan" are definitely too advanced for newcomers. But the more specialized ones like "reverse", "take", "drop", "filter", "splitAt", "concat", "sum", etc. are self-explanatory. I really wish I've learned about these names earlier, and so far these names are pretty general across languages I've dabbed into.

I prefer "fold" to "reduce" because I don't know what "reduce" wants to convey. "Fold" very vividly conveys that the operation folds the whole list into something else interesting, part by part.

I've also introduced the Java documentation early and showed my students and schoolmates how to explore it by searching and reading list of methods. It doesn't take much for them to start exploring themselves.

Collapse
 
louy2 profile image
Yufan Lou

Looks like you are teaching in Java. Java has iterator for loop syntax too, called for-each loop:

for (var hay : haystack) {}

Another point Haskell has revealed to me is that we don't need the concept of index to describe operations on a list. You mentioned the linked list loop as a "more advanced loop", but I think that might be the easier one, if we remove the ++i. It's a loop after all, so if you describe it as "we start from the beginning, process the next item, until we have nothing left," then it matches the language better than the index version. It's just convention that we introduce array before linked list, but that's from a implementer's perspective. I think from a user's perspective, a list interface, or in Java, the Iterator interface, is easier to learn because there's less to keep in mind. I don't think "iterate" the word itself is confusing your students, but rather the fact that they are learning "for loop" along with "iterate", and that the word "iterate" never appeared in the code.

A rewrite of your three loops with the Iterator interface:

Find loop

Because this accesses index it has to use listIterator(). I don't like Java.

public static int indexOf(List<String> haystack, String needle) {
    for (Iterator it = haystack.listIterator(); it.hasNext(); ) {
        if (needle.equals(it.next())) {
            return it.previousIndex();
        }
    }
}

Count loop

You know what, let's just use listIterator() throughout. One less thing to care about.

public static int countOf(List<String> haystack, String needle) {
    int count = 0;
    for (Iterator it = haystack.listIterator(); it.hasNext(); ) {
        if (needle.equals(it.next())) {
            count++;
        }
    }

    return count;
}

Action loop

public static void printAll(List<String> haystack) {
    for (Iterator it = haystack.listIterator(); it.hasNext(); ) {
        System.out.println(it.next());
    }
}