[racket] Loop in Racket

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Mon Jun 28 09:48:20 EDT 2010

>> What is the reason for not offering a looping construct in racket?  
>> For
>> example, something like:
>> (loop (i 1 10) (print i))
>> Just for the masses, it seems simpler to use.

Simpler than what?  For what application?

The classic C/C++/Java "for" loop was designed for, and is almost  
always used for, integer counters stepping through an array.  In most  
of these applications, what you really want to do is "do something to  
each element of this array," or perhaps "do something to each element  
of this array until you find one that meets this criterion."

One of my general principles of programming is "try to avoid  
introducing concepts in the solution that weren't part of the  
problem."  In both of the above cases, the problem statement doesn't  
say anything about integer counters, indices, or mutation, so one  
should be able to solve the problem without those things.

In a low-level language like C or Pascal, one can't hide the fact  
that arrays are indexed with integers, and the way to do something  
with various different integers is a for-loop.  C++ starts to address  
the problem with "iterators", which still act like mutable counters  
and are still used in classic "for" loops, but at least they hide the  
array indexing.  Java does the same thing with "Iterable" and goes a  
step farther with "foreach" loops, which partially hide the mutation  
as well... but anyone who's ever tried defining a class that  
implements Iterable found that it still has to use mutation  
internally.  Scheme/Racket's list and sequence operations -- "map",  
"filter", "foldr", "for", "in-range", "in-naturals", "in-string",  
"stop-before", etc. -- are yet another step in the direction of  
eliminating concepts from the solution that weren't in the problem.

In other words, what's "simpler" is to use a construct that says what  
you mean.  If you want to print the integers 1 through 10 in  
increasing order (actually a fairly artificial problem whose main  
purpose is to test integer-counting for-loop constructs), use "for"  
and "in-range".  If you want to do something to each element of a  
list and get a list of the results, use "map".  If you want to  
extract the elements of a list that meet a particular criterion, use  
"filter".  If you want to count the elements of a list that meet a  
particular criterion, use "count-if".  And in the unlikely event that  
what you want to do doesn't match any of the defined constructs,  
Scheme/Racket allows you to write your own control constructs  
(indeed, I have assigned my CS0 students to write their own versions  
of "map", "filter", and "count-if").

Stephen Bloch
sbloch at adelphi.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100628/679a10b5/attachment.html>

Posted on the users mailing list.