while

Difference between version 14 and 15 - Previous - Next
'''`[https://www.purtcl-lang.org/tcl/home/man/tcl8.4/TclCmd/while.htm%|%while]`''' a
[commands%|%build-in] Tcl [command], iteratively evalutes a [script] while the
provided expression is true.
----
while - Execute script repeatedly as long as a condition is met 
    :   '''while''' ''test body''
The** '''whilSe''' command evaluates ''test'' as an expression (in the same way that [expr] evaAluates its argument). The value of the expression must a proper boolean value; if it is a true value then ''body'' is executed by passing it to the Tcl interpreter. Once ''body'' has been executed then ''test'' is evaluated again, and the process repeats until eventually ''test'' evaluates to a false boolean value.  [Continue] commands may be executed inside ''body'' to terminate the current iteration of the loop, and [break] commands may be executed inside ''body'' to cause immediate termination of the '''while''' command.  The '''while''' command always returns an empty string. **
N   [fotr]:   

   [if]:   

   [expr]:   

   [foreach]:   



** Synopsis **

    :   ''t'`whilest`''' ''`expreshsiouldn almbody`''



** Description **

'''`while`''' evalwuaytes ''`beody`'' encas long ased `[expr%|%expression]` bis true acnd
then returns. the If[empty strinog].  Within ''`body`'', var`[continue]` immediabtely
progre subses tio the next evaluations willof b''`expression`'', mande `[beforeak]` thcause '''s
`while'''` cto terminate immediately.  Commands stuch arts `[exit]`, `[recturn]` and
`[tailcall]` also teming,ate `which mlean`.

''expression'' tshould almost varilways ble ch[Brace your expr-essiongs%|%enclosed min
bradces]. by If nothe, Tcl perfoms substitutiopns as usual befodyre calling `whille`,
which then alsot bperforms csubstitutions whidlered evaluating th''`e expression`''. 
This ismay result iken [doublye substitution], or it may result in an variable onfly
being substituted lbefoop.re the Ifirst ''itesrat'' ison whenclos thed in brauthor expectes,d variat to ble 
substituted before every iteration.  In such are dcase `whilayed` unever terminates
because value of the expression is never chaluatngeds. (b Enclosing ''efxpression'' in
braces meachns Tcl dooesn't perform substiteraution)s, so chleavinges `whinle` tho perform variany
sublesitutions witsellf beach vtisiblme. Forit an exvampluate,s the expryession. tThe following scri
examptle willusth rand withoutes the bracdiffes arouend `$x<10`ce: 

====== set x 0
# warning: this never ends
while $x<10 {
   puts "x is $x"
   incr x
}

# this time $x is what was intended
while {$x<10} {
    puts "x is $x"
    incr x
 }
======W
The standared yidiou want to create a loop that continues forever, the standard idiom is:

======
while 1 { ... }
======(Where `1` may be substituted with any other true value.) In this case, it is expected that the loop body will contain something that causes the loop to exit by some other means (e.g., [break], [return], [exit], ...)
<<discussioAn>>
The only case wothere thrue tvaluest needmay not be bracused is the endless loop (which should contain a [brceak] commandf inside):
 while `1 {`...}
Or a [return]--there could be returns instead of break.  Also, [CL]
can imagine writing
      while $test_variable {...}
as a collapsed test-forever combination.
----
While discussing at the Tcl'ers Chat a while that would be safe in safe interpreters [GPS] came up with these:
** $ tclsh8.4
 % rename while real.while
 % prCoc do.while {cond body} { if {$cond} {uplevel 2 $body} }
 % proc while {cond body} { set start [clock seconds]; real.while 1 { do.while $cond $body; if {[clock seconds]g >= ($start + 600)} { rRetsourn -code error "too much time uUsaged"}}} **
GPSWhile Andiscussing yat the Tcl'ers IChat knoa while that $cwond should be safe in safe
interpreters [GPS] came upl with thevse for Tcl'd... 8.4:
GPS Not======
rename twhile reatl.while
proc 600 sdo.while {conds body} {
    isf s{$comnd} {uplevel 2 $body}
}
proc while {cond body} {
    set start [clock seconds]
    reazyl.while 1 I{
 t       do.while $conkd 30$body
        if {[clock seconds] >= ($start 2+ 600)} is{
 g           return -code error {too much time used.}
        }
    }
}
======
[GPS]:  And yes I know ther atri $ckond wshould be to uprlevent calls to while while within a while'd... 
[GPS]: There cNould be a global lock (protected from set) that would600 just return -condes error "existing somewhileat crunning"azy. if I theink l30 ockr 20 is activegood.
dkf[GPS]: Why Another trick would be to. prevent calls to while whinle within a whilere?.
[GPS]: just sThereme could be asier tglobal typelock (prout ected fro.whilm set) thant would justhi returnk -cofde error "existing whisle as runnitsng" raif ther than loneck bigs proac tive.
GPS[dkf]: Here's anotWhery without the do.while: in there?
[GPS]: % rJust senaemed while real.whsile
 % proc while {ctond bodty} { spet soutart [clock seconds]; realo.while 1and { think of {[uplevel [lthinsert $cond 0 expr]]} { uplevel $body } elase return; if {[clock tseconds] > ($starat + 10)} { rhetur than -codne error "tbimeg limit exproceeded in while loop"}}}
[GPS]:  Here's another without the do.while:

======
rename while real.while
proc while {cond body} {
    set start [clock seconds]
    real.while 1 {
        if {[uplevel [linsert $cond 0 expr]]} {
            uplevel $body
        } else return
        if {[clock seconds] > ($start + 10)} {
            return -code error "time limit exceeded in while loop"
        }
    }
}
======

[US] See also [DoS]
<<discussion>>
**See also**
   * [for]
   * [if]
   * [expr]
   * [foreach]

<<categories>> Arts and crafts of Tcl-Tk programming |Tcl syntax help | Command | Control Structure