Version 2 of I Know Nothing

Updated 2009-09-08 04:45:17 by Ro

Ro 2009

This is a page about Execution and Custom Control Structures.

I found out that I know nothing about how execution happens, how the tcltk interpreter works, and what it's capable of. In the end, I truly know nothing.

  proc imdone {} {
    puts "yknow what, im done"
    set level [info level]
    return -level $level -code return
  }

When you execute this, at any time, from any proc, however many levels deep: all execution ends. No error, it just triggers a cascading normal return.

To people who understand everything already (har har), this is nothing new. But to me, it just about rendered me incapable of thought and threw into questioning everything I knew about life.

I'm used to thinking that g2 will return, and g1 will continue running. But no, when you use return with the -level option, you can actually cause the interpreter to finish all execution.

  proc g2 {} {
    puts G2-hello
    imdone
    puts G2-goodbye
  }

  proc g1 {} {
    puts g1-BEGIN
    g2
    puts g1-END
  }

  g1

So that's the first bit of code.


proc limited_while {cond body {limit 10}} {

  set n 0
  while 1 {
    if {$n == $limit} {
      error "hit limit of $n loops"
    }

    # evaluate the condition
    #
    set c [uplevel [list catch [list expr $cond] ::m ::o]]

    # if the evaluation doesnt return ok, then throw exception
    #
    if {$c != 0} {
      dict incr ::o -level
      return -options $::o $::m
    }

    # now the condition actually evaluated but is it true?
    #
    if {$::m != 1} {
      return
    }

    # ok so now we evaluate the body
    #
    set c [uplevel [list catch $body ::m ::o]]

    # ok 0              next iteration
    # error 1 return 2  throw exception
    # break 3           quit this proc
    # continue 4        next iteration just like ok 0
    #
    switch -exact -- $c {
      0 {}
      3 {
        return
      }
      4 {}
      default {
        dict incr ::o -level
        return -options $::o $::m
      }      
    }

    incr n
  }
  return

}

  set i 0
  limited_while {$i < 5} {

    if {$i == 3} {break}
    puts $i

    incr i
  }