:TITLE: Looping 102 - For and incr
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_English/Tcl_English10.lsn,v 1.1 2008/08/02 12:37:17 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# See file "NOTICE" for licensing terms.
;#
:LESSON_TEXT_START_LEVEL 0:
<B>Syntax: </B><CODE>for</CODE><I>start test next body</I>
<P>
The man page entry for <CODE>for</CODE>:
<P>
For is a looping command, similar in structure to the C for statement. 
The start, next, and body arguments must be Tcl command strings, and
test is an expression string.
<P>
The for command first invokes the Tcl
interpreter to execute start.  Then it repeatedly evaluates test as an
expression; if the result is non-zero it invokes the Tcl interpreter on
body, then invokes the Tcl interpreter on next, then repeats the loop. 
The command terminates when test evaluates to 0.
<P>
  If a continue command
is invoked within body then any remaining commands in the current
execution of body are skipped; processing continues by invoking the Tcl
interpreter on next, then evaluating test, and so on.
<P>
  If a break
command is invoked within body or next, then the for command will return
immediately.  The operation of break and continue are similar to the
corresponding statements in C.  
<P>
For returns an empty string. 
<P>
As with the <CODE>while</CODE> command, the test should be placed within
braces to keep the substitution phase of the interpreter from replacing the
iterating variable with its start value before evaluating the for command.
<P>
Because incrementing the iteration variable is so common, Tcl has a special
command for this: 
<P>
<B>incr</B> <I>varName ?increment?</I>
<P>
This command adds the value in the second argument to the variable named in
the first argument.  If no value is given for the second argument, it
defaults to 1. 
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Tcl supports an iterated loop construct similar to the <CODE>for</CODE>
in C, and the <CODE>do</CODE> loop in Fortran.  The <CODE>for</CODE> command
in Tcl takes four arguments; an initialization, a test, an increment, and
the body of code to evaluate on each pass through the loop.  The syntax
for the <CODE>for</CODE> command is:
<P>
<CODE>for</CODE> <I>start test next body</I>
<P>
During evaluation of the <CODE>for</CODE> command, the <I>start</I> code
is evaluated once, before any other arguments are evaluated.  After the
start code has been evaluated, the <I>test</I> is evaluated.  If the
<I>test</I> evaluates to true, then the <I>body</I> is evaluated, and
finally, the <I>next</I> argument is evaluated.  After evaluating the
<I>next</I> argument, the interpreter loops back to the <I>test</I>, and
repeats the process.  If the <I>test</I> evaluates as false, then the
loop will exit immediately. 
<P>
<I>Start</I> is the initialization portion of the command.  It is commonly 
used to initialize the iteration variable, but can contain any code that
you wish to execute before the loop starts.
<P>
The <I>test</I> argument is evaluated numerically, just as with the <CODE>expr</CODE>
command, and as done in the <CODE>while</CODE> command.  This can contain
any expression that you would pass to <CODE>expr</CODE>.
<P>
<I>Next</I> is commonly an incrementing command, but may contain any 
command which the Tcl interpreter can evaluate.
<P>
<I>Body</I> is the body of code to execute.
<P>
Since you commonly do not want the Tcl interpreter's substitution phase
to change variables to their current values before passing control to
the <CODE>for</CODE> command, it is common to group the arguments with
braces.  When braces are used for grouping, the newline is not treated
as the end of a Tcl command.  This makes it simpler to write multiple
line commands.  However, the opening brace must be on the line with the
<CODE>for</CODE> command, or the Tcl interpreter will treat the close of
the <I>next</I> brace as the end of the command, and there will not be
enough arguments for the <CODE>for</CODE> command. 
<P>
Within the <I>body</I> code, the commands <CODE>break</CODE> and
<CODE>continue</CODE> may be used just as they are used with the
<CODE>while</CODE> command.  When a <CODE>break</CODE> is encountered,
the loop exits immediately.  When a <CODE>continue</CODE> is encountered,
evaluation of the <I>body</I> ceases, and the <I>test</I> is re-evaluated.
<P>
Because incrementing the iteration variable is so common, Tcl has a special
command for this: 
<P>
<B>incr</B> <I>varName ?increment?</I>
<P>
This command adds the value in the second argument to the variable named in
the first argument.  If no value is given for the second argument, it
defaults to 1. 
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
The <CODE>while</CODE> command is very powerful, and can be used 
anyplace you need to perform a loop.  However, there are many times
when you want a simpler method of constructing a loop.
<P>
Tcl supports an iterated loop construct called the <CODE>for</CODE> command.
The <CODE>for</CODE> command
takes four arguments; an initialization, a test, an increment, and
the body of code to evaluate on each pass through the loop.  These are the
same four pieces of code you'd have to use with a <CODE>while</CODE> command,
but they can be expressed more compactly with the <CODE>for</CODE> command.
<P>
  The syntax
for the <CODE>for</CODE> command is:
<P>
<CODE>for</CODE> <I>start test next body</I>
<P>
The evaluation of the <CODE>for</CODE> goes through these steps:
<OL>
<LI> the <I>start</I> code is evaluated once, before any other arguments are evaluated.  
<LI> the <I>test</I> is evaluated.  
<UL>
<LI>If the <I>test</I> evaluates to true, then  the <I>body</I> is evaluated, 
<LI>If the <I>test</I> is not true, then the loop will exit immediately.
</UL>
<LI> the <I>next</I> argument is evaluated
<LI> loop back to step 2, and repeat process.
</OL>
<P>
<I>Start</I> is the initialization portion of the command.  It is commonly 
used to initialize the iteration variable, but can contain any code that
you wish to execute before the loop starts.
<P>
The <I>test</I> argument is evaluated numerically, just as with the <CODE>expr</CODE>
command, and as done in the <CODE>while</CODE> command.  This can contain
any expression that you would pass to <CODE>expr</CODE>.
<P>
<I>Next</I> is commonly an incrementing command, but may contain any 
command which the Tcl interpreter can evaluate.
<P>
<I>Body</I> is the body of code to execute.
<P>
Since you commonly do not want the Tcl interpreter's substitution phase
to change variables to their current values before passing control to
the <CODE>for</CODE> command, it is common to group the arguments with
braces.  When braces are used for grouping, the newline is not treated
as the end of a Tcl command.  This makes it simpler to write multiple
line commands.  However, the opening brace must be on the line with the
<CODE>for</CODE> command, or the Tcl interpreter will treat the close of
the <I>next</I> brace as the end of the command, and there will not be
enough arguments for the <CODE>for</CODE> command. 
<P>
Within the <I>body</I> code, the commands <CODE>break</CODE> and
<CODE>continue</CODE> may be used just as they are used with the
<CODE>while</CODE> command.  When a <CODE>break</CODE> is encountered,
the loop exits immediately.  When a <CODE>continue</CODE> is encountered,
evaluation of the <I>body</I> ceases, and the <I>test</I> is re-evaluated.
<P>
Because incrementing the iteration variable is so common, Tcl has a special
command for this: 
<P>
<B>incr</B> <I>varName ?increment?</I>
<P>
This command adds the value in the second argument to the variable named in
the first argument.  If no value is given for the second argument, it
defaults to 1.  The second argument (<I>increment</I>) can be a negative
value if you want to count down, instead of up.
:TEXT_END:

:CODE_START:
for {puts "Start"; set i 0} {$i < 2} {incr i; puts "I after incr: $i"; } {
  puts "I inside first loop: $i"
  }

;# Because the test is evaluated before the body,
;#  this loop won't execute the body of the code.

for {puts "Start"; set i 3} {$i < 2} {incr i; puts "I after incr: $i"; } {
  puts "I inside second loop: $i"
  }

;# A while loop equivalent to the first for loop:

puts "Start"; set i 0;
while {$i < 2} {
  puts "I inside first loop: $i"
  incr i; 
  puts "I after incr: $i"; 
  }

:TEXT_END:

