Re: What if you lost 'if ' !!
Available news archives: comp.lang.tcl - comp.lang.python - comp.security.firewalls - sci.crypt - comp.lang.php - comp.lang.javascript
Google
 
Web news.hping.org


comp.lang.tcl archive

Re: What if you lost 'if ' !!

From: Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date: Tue Dec 06 2005 - 09:26:53 CET

MH <mghembru@harshrealm.uwaterloo.ca> wrote:
>>It's definitely impossible before 8.5, and quite easily
>>achievable in 8.5 (using new -level option for return).

> Ok, just to clarify...
> proc x { } { return -code break -level ?? }
> proc y { } { while { cond } { x }; puts "After Cond" }
> proc z { } { while { cond2 } { y }; puts "After Cond2" }
> z

> If I understand correctly, then, this would mean that
> -prior to 8.5, both puts would get executed (and y possibly
> invoked multiple times, depending on cond2), since -level
> isn't there
Well, it would really error out for the unknown option "-level".
But if you omitted the "-level ??", then yes it would act as
you guessed.

> -with 8.5, the "return -code break -level ??" actually causes a RETURN
> INSIDE y (as opposed to a break as with <8.5), which returns a BREAK to z,
> such that while { cond2 } is only executed ONCE, since it gets a BREAK back
> from calling y.
Yes, but only for an appropriate number substed for the "??".
It would work the way you guessed, with "-level 1"
If you used "-level 2", then
  foreach j {1 2 3 4} {z}
would leave j at 1, and none of the puts reached.

> Is that it? I'm guessing that someone has a good use for it somewhere.. It's
> just not obvious to me right now what that use is.. (it would mean x would
> have to know about y, and the fact that return -code break -level ?? would
> "do the right thing".)

It is specifically useful for writing one's own control-structures.
So far you were only able to write your own "break", "continue",
"error" as procedures doing "return -code whatever"
However, if your procedure was supposed to "pass through"
such a "return -code whatever", then you hit a wall.
Why would one need it? For example when doing the stuff
that this thread is actually about. In real world nobody
messes with actually replacing "if", but there are also
custom loops, which need to do the same "passing on":

Imagine you create your own loop to do a reverse-foreach:
  proc hcaerof {varname list body} { ... }
and use it:
  hcaerof i $list { puts $i }

Later, you perhaps need a custom "break"-alike, that
only breaks if a global boolean var is set:
proc mybreak {} {
   if {$::globvar} {return -code break} ;# ok even before 8.5
}

And again later, this global boolean turns into a list of
threevalued(0,1,2) items, and your break should only fire,
if a "1" is found after any "2":

proc mybreak {} {
   hcaerof i $::globVar {
      if {$i==2} {break} elseif {$i==1} {return -code break}
   }
}

This new "mybreak" still looks like 8.4-compatible, but for
this to work, hcaerof would need to be able to call a
one-level-deeper "return -code ...", since in the end, it
is the "hcaerof" that has to behave like "return -code break"

PS:
Even if tclsh8.5 had a bug that would mercilessly crash any
application that uses a -level greater than 2, then I'm
quite sure that no one would notice for a very long time ...
(except for some possibly well-crafted test-suites :-)
Received on Sun Dec 11 13:53:48 2005