f



Use "range," not "for"?

Thanks to everyone who suggested ways to get a proc to recognize all
variables in the global scope--here's why I wanted to know. (Maybe someone
has done this better already--if so, don't hesitate to let me know!)

I've found that a simple "foreach" loop fairly often won't do the jobs I
want done, and I need to use "for"--ugh! Well, I recently read at least
part of a book about Python. It didn't look like an improvement over Tcl
for the most part, but it has at least a few good features, one of which is
the "range" expression. I thought a "range" procedure in Tcl might be a
good substitute for the clumsy "for." So, here's my first effort. Instead
of writing this:

        for {set i 1} {$i<= 10} {incr i} {puts "$i. \"for\" is ugly!"}

you can write this:

        range i 1 to 10 {puts "$i. \"range\" is beautiful!"}

Or, if you have a list called "lum," instead of writing this:

        for {set i 0} {$i < [llength $lum]} {incr i} {puts [lindex $lum $i]}

you can write this:

        range i 0 no [llength $lum] {puts [lindex $lum $i]}

To go backward, skipping every other number, instead of this:

        for {set i 10} {$i >= 0} {incr i -2} {puts $i}

you can write this:

        range i 10 to 0 -2 {puts $i}

The usage is pretty obvious: "range var start cutoff end ?incr? body." In
other words, (1) the word "range"; (2) a variable to change through the
range; (3) the beginning of the range; (4) "to" if the range is inclusive
or "no" if it excludes the last number; (5) the end of the range; (6) a
number for the increment if it isn't 1 (for an ascending range) or -1 (for
a descending range); and (7) a body of code to execute on each iteration of
the loop.

The procedure is below. Please let me know if (1) somebody already did this
better, (2) you want to suggest any improvements or bugfixes, (3) you don't
think it's worth the effort of copying this procedure to get rid of all the
braces, repetition, and other minor difficulties in the "for" command, or
(4) (insert additional options here). Thanks in advance!

David McClamrock
____________________________________________________________________

# Procedure to do a "for" loop without ugly, awkward "for" code:

uplevel #0 {
proc range {var star cutoff fin args} {
        global codex $var
        if {[catch {expr $var+1}] == 0} {
                error "Use a letter, not a number, for the first \"arg\"!"
        }
        if {[catch {expr $star+$fin}] > 0} {
                error "Range must contain two numbers!"
        }
        if {$star == $fin} {
                error "Range cannot begin and end with the same number!"
        }
        switch $cutoff {
                "to" {set inclu 1}
                "no" {set inclu 0}
                default {
                        error "Use \"to\" for an inclusive range,\
                        or \"no\" for a noninclusive range!"
                }
        }
        set argleng [llength $args]
        set codex [lindex $args end]
        if {$argleng < 1 || $argleng > 2} {
                error "Number of additional \"args\" must be one or two!"
        } elseif {$argleng == 2} {
                set incro [lindex $args 0]
                if {[catch {expr $incro+1}] == 1} {
                        error "First of two additional \"args\" must\
                        be a number!"
                }
        }
        set starless [expr $star < $fin]
        switch "$starless $argleng $inclu" {
                "1 1 1" {
                        set sign "<="
                        set incro 1
                }
                "1 1 0" {
                        set sign "<"
                        set incro 1
                }
                "0 1 1" {
                        set sign ">="
                        set incro -1
                }
                "0 1 0" {
                        set sign ">"
                        set incro -1
                }
                "1 2 1" {
                        set sign "<="
                }
                "1 2 0" {
                        set sign "<"
                }
                "0 2 1" {
                        set sign ">="
                }
                "0 2 0" {
                        set sign ">"
                }
                default {
                        error "Number of additional \"args\" must\
                                be one or two!"
                }
        }
        if {$starless == 1 && $incro <= 0} {
                error "Range increases--increment must be positive!"
        } elseif {$starless == 0 && $incro >= 0} {
                error "Range decreases--increment must be negative!"
        }
        for "set $var $star" "$$var $sign $fin" "incr $var $incro" {
                uplevel #0 {
                        eval $codex
                }
        }
}
}

0
mcclamrock (108)
2/13/2004 12:16:33 AM
comp.lang.tcl 23429 articles. 2 followers. Post Follow

26 Replies
624 Views

Similar Articles

[PageSpeed] 28

David McClamrock <mcclamrock@locl.net> wrote:
>  I've found that a simple "foreach" loop fairly often won't do the jobs I
>  want done, 

Really?  Why?

[...]
>  Instead of writing this:
>          for {set i 1} {$i<= 10} {incr i} {puts "$i. \"for\" is ugly!"}
>  you can write this:
>          range i 1 to 10 {puts "$i. \"range\" is beautiful!"}
>  
>  Or, if you have a list called "lum," instead of writing this:
>          for {set i 0} {$i < [llength $lum]} {incr i} {puts [lindex $lum $i]}
>  you can write this:
>          range i 0 no [llength $lum] {puts [lindex $lum $i]}
>  
>  To go backward, skipping every other number, instead of this:
>          for {set i 10} {$i >= 0} {incr i -2} {puts $i}
>  you can write this:
>          range i 10 to 0 -2 {puts $i}
[...]

Woof, it looks needlessly complicated.  You don't have to muck about
with uplevel at all.  Have a look at http://wiki.tcl.tk/10795
It demonstrates an "integer range generator" proc called [..]
Using it would change your examples to:

1   foreach i [.. 1 10] {puts "$i. '..' is beautiful"}

2   foreach i [.. 0 [expr {[llength $lum] - 1}]] {puts [lindex $lum $i}
    # OK, that's not as pretty as your [range], but it's a crummy
    # example anyway

3   foreach i [.. 10 0 -2] {puts $i}

Here's a wiki page showing a "do ... until ..." loop, which demonstrates
how to neatly handle executing a script body that's passed as an
argument to a proc:
    http://wiki.tcl.tk/917

-- 
Glenn Jackman
NCF Sysadmin
glennj@ncf.ca
0
xx087 (199)
2/13/2004 1:10:24 AM
David McClamrock wrote:
> Thanks to everyone who suggested ways to get a proc to recognize all
> variables in the global scope--here's why I wanted to know. (Maybe someone
> has done this better already--if so, don't hesitate to let me know!)
> 
> I've found that a simple "foreach" loop fairly often won't do the jobs I
> want done, and I need to use "for"--ugh! Well, I recently read at least
> part of a book about Python. It didn't look like an improvement over Tcl
> for the most part, but it has at least a few good features, one of which is
> the "range" expression. I thought a "range" procedure in Tcl might be a
> good substitute for the clumsy "for." So, here's my first effort. Instead
> of writing this:
> 
>         for {set i 1} {$i<= 10} {incr i} {puts "$i. \"for\" is ugly!"}
> 
> you can write this:
> 
>         range i 1 to 10 {puts "$i. \"range\" is beautiful!"}

Using globals is not the right solution. Your range code simply won't 
work inside a procedure. Try running this code:

proc foo {} {
     set j "Hello, world"
     range i 1 to 10 {
         puts "$i: $j"
     }
}

You'll instantly see the problem. Instead of using global variables you 
need to use upvar and "uplevel 1".

Also, the very first uplevel "uplevel #0 proc ..." really doesn't do 
anything. What do you think it does? If you can explain what you are 
trying to accomplish we can tell you a better way to accomplish it. If 
you're trying to force the definition of range into the global scope 
it's better to fully qualify the name, ie: "proc ::range".

0
bryan1 (353)
2/13/2004 1:20:00 AM
David McClamrock wrote:
> 
> Thanks to everyone who suggested ways to get a proc to recognize all
> variables in the global scope--here's why I wanted to know. (Maybe someone
> has done this better already--if so, don't hesitate to let me know!)
> 
> I've found that a simple "foreach" loop fairly often won't do the jobs I
> want done, and I need to use "for"--ugh! Well, I recently read at least
> part of a book about Python. It didn't look like an improvement over Tcl
> for the most part, but it has at least a few good features, one of which is
> the "range" expression. I thought a "range" procedure in Tcl might be a
> good substitute for the clumsy "for." So, here's my first effort. Instead
> of writing this:
> 
>         for {set i 1} {$i<= 10} {incr i} {puts "$i. \"for\" is ugly!"}
> 
> you can write this:
> 
>         range i 1 to 10 {puts "$i. \"range\" is beautiful!"}
> 
> Or, if you have a list called "lum," instead of writing this:
> 
>         for {set i 0} {$i < [llength $lum]} {incr i} {puts [lindex $lum $i]}
> 
> you can write this:
> 
>         range i 0 no [llength $lum] {puts [lindex $lum $i]}
> 
> To go backward, skipping every other number, instead of this:
> 
>         for {set i 10} {$i >= 0} {incr i -2} {puts $i}
> 
> you can write this:
> 
>         range i 10 to 0 -2 {puts $i}
> 
> The usage is pretty obvious: "range var start cutoff end ?incr? body." In
> other words, (1) the word "range"; (2) a variable to change through the
> range; (3) the beginning of the range; (4) "to" if the range is inclusive
> or "no" if it excludes the last number; (5) the end of the range; (6) a
> number for the increment if it isn't 1 (for an ascending range) or -1 (for
> a descending range); and (7) a body of code to execute on each iteration of
> the loop.
> 

On the Wiki there is something similar - produce a list of integers that
you
can use in a foreach.

And I am very much reminded of the Fortran way of specifying for-loops
.... :)

Yes, I usually avoid for-loops in Tcl, as foreach is much more elegant.

Care to put this on the Wiki? Or submit it for Tcllib?

Regards,

Arjen
0
arjen.markus (2628)
2/13/2004 7:47:59 AM
David McClamrock <mcclamrock@locl.net> wrote:
> I've found that a simple "foreach" loop fairly often won't do the jobs I
> want done, and I need to use "for"--ugh! Well, I recently read at least
> part of a book about Python. It didn't look like an improvement over Tcl
> for the most part, but it has at least a few good features, one of which is
> the "range" expression. 

It's funny, how experience can be similar and yet completely
different:

I have read a book about Python, too, but I kind of dropped it,
 just because Python had no such thing as the classic
 "init/condition/incr"-controlled for-loop.

I posted to python-group, asking what pythoneers do in such cases,
 where such a for-loop is necessary, and all they came up was either
 the for_with_range-thing(1) or while-loops(2).
Both were not satisfactory:
(1) wouldn't give me "write-access" to the loop-variable, and
(2) misses the "incr"-part, that will be jumped to at a "continue".
  Answering to this, some came up with exception-handling tricks to
  work around that, but thats unpracticable.

Creating a list of numbers in memory just to iterate this list 
seems somewhat strange to me.

The only really cool thing about Python is the concept of "generators".
I think some time ago, I've heard some thoughts about lazy evaluation-
concepts in Tcl, but have no idea what became of it.

Seeing the indentation chaos that differing tab-size-settings of 
 different developers cause, I sometimes wish tcl,C,C++ and Java
 would care for indentation like python, but, well, I know this 
 is never going to happen, and it's likely better this way.


> Or, if you have a list called "lum," instead of writing this:
>         for {set i 0} {$i < [llength $lum]} {incr i} {puts [lindex $lum $i]}
Isn't this exactly what tcl's "foreach" is for?
% foreach i $lum {puts $i}
Isn't this nicer than:
>         range i 0 no [llength $lum] {puts [lindex $lum $i]}
?

0
avl1 (2748)
2/13/2004 9:48:17 AM
Glenn Jackman wrote:

> David McClamrock <mcclamrock@locl.net> wrote:
>>  I've found that a simple "foreach" loop fairly often won't do the jobs I
>>  want done,
> 
> Really?  Why?

Because I wanted to do something for each specific number in an integer
range (e.g., create a column in a multi-column list display), but the top
limit of the integer range was going to come from user input so I couldn't
identify it in advance, and I didn't have an integer range generator for
"foreach." I'll take a look at the one you suggested. Thanks!
  
David McClamrock
0
mcclamrock (108)
2/13/2004 10:26:20 AM
Bryan Oakley wrote:

> the very first uplevel "uplevel #0 proc ..." really doesn't do
> anything. What do you think it does?

When the "uplevel" wasn't there, the proc wouldn't recognize variables that
had been set in the global scope and weren't mentioned in the proc; when it
was, it would. But I'd prefer to avoid "uplevel" altogether and use an
integer range generator for "foreach," which I didn't know about until now.

> If you can explain what you are 
> trying to accomplish we can tell you a better way to accomplish it.

Somebody already did, I think:

http://wiki.tcl.tk/10795

David McClamrock

0
mcclamrock (108)
2/13/2004 11:14:24 AM
Arjen Markus wrote:
> Care to put this on the Wiki? Or submit it for Tcllib?

Maybe--after I've thoroughly reworked it! :o)

David McClamrock
0
mcclamrock (108)
2/13/2004 11:59:53 AM
Andreas Leitgeb wrote:
>>Or, if you have a list called "lum," instead of writing this:
>>        for {set i 0} {$i < [llength $lum]} {incr i} {puts [lindex $lum $i]}
> 
> Isn't this exactly what tcl's "foreach" is for?
> % foreach i $lum {puts $i}
> Isn't this nicer than:
> 
>>        range i 0 no [llength $lum] {puts [lindex $lum $i]}

Right up until the moment you need to change the [puts] call to
   puts "[lindex $lum $i] $i"

That's what always catches me. :-) Would be nice if foreach made up a $_ 
variable or some such god-awful perlism that said how many times thru 
the loop you've gone. :-)

-- 
Darren New, San Diego CA USA (PST)
   I am in geocentric orbit, supported by
   a quantum photon exchange drive....
0
dnew (1159)
2/13/2004 4:59:36 PM
On Fri, 13 Feb 2004, Darren New wrote:

> > Isn't this exactly what tcl's "foreach" is for?
> > % foreach i $lum {puts $i}
> > Isn't this nicer than:
> >
> >>        range i 0 no [llength $lum] {puts [lindex $lum $i]}
>
> Right up until the moment you need to change the [puts] call to
>    puts "[lindex $lum $i] $i"
>
> Would be nice if foreach made up a $_ variable or some such god-awful
> perlism that said how many times thru the loop you've gone. :-)

Yes, please, mommy, can I have that, me hates "initialize variable, incr
it every loop" sequence, please, me wants automagic $_, please.

-- 
-Kaitzschu
0
kaitzschu1 (358)
2/14/2004 1:40:47 AM
Kaitzschu wrote:

> On Fri, 13 Feb 2004, Darren New wrote:
> 
> 
>>>Isn't this exactly what tcl's "foreach" is for?
>>>% foreach i $lum {puts $i}
>>>Isn't this nicer than:
>>>
>>>
>>>>       range i 0 no [llength $lum] {puts [lindex $lum $i]}
>>
>>Right up until the moment you need to change the [puts] call to
>>   puts "[lindex $lum $i] $i"
>>
>>Would be nice if foreach made up a $_ variable or some such god-awful
>>perlism that said how many times thru the loop you've gone. :-)
> 
> 
> Yes, please, mommy, can I have that, me hates "initialize variable, incr
> it every loop" sequence, please, me wants automagic $_, please.
> 

I give that one a big thumbs down. Tcl doesn't need magic variables.

If you really want it, it's fairly trivial to make your own foreach that 
does this.

     proc _foreach {args} {
             set body [lindex $args end]
             set body "incr _;\n$body"

             set args [lreplace $args end end $body]
             set command [linsert $args 0 foreach]
             uplevel set _ 0
             uplevel $command
     }

     _foreach letter {a b c}  {
         puts "$_: letter=$letter "
     }

0
bryan1 (353)
2/14/2004 2:23:10 AM
Darren New <dnew@san.rr.com> wrote in message news:<Yn7Xb.7529$jf.5536@twister.socal.rr.com>...
> Right up until the moment you need to change the [puts] call to
>    puts "[lindex $lum $i] $i"
> 
> That's what always catches me. :-) Would be nice if foreach made up a $_ 
> variable or some such god-awful perlism that said how many times thru 
> the loop you've gone. :-)

See http://mini.net/tcl/ILoveForeach where the idea of foreachWithIndex
was discussed. Of course you can always do:

     set idx -1
     foreach item $list {
        incr idx
        # code
     }

Keith
0
keithv (23)
2/14/2004 3:41:53 AM
Bryan Oakley <bryan@bitmover.com> writes:

> I give that one a big thumbs down. Tcl doesn't need magic variables.

args, how I hates magic variables.  I don't env ee those perl programmers.

Donald Arseneau                          asnd@triumf.ca
0
asnd (4601)
2/14/2004 7:05:56 AM
Kaitzschu <kaitzschu@kaitzschu.cjb.net.nospam.plz.invalid> wrote:
>>
>> Right up until the moment you need to change the [puts] call to
>>    puts "[lindex $lum $i] $i"
>>
>> Would be nice if foreach made up a $_ variable or some such god-awful
>> perlism that said how many times thru the loop you've gone. :-)
> 
> Yes, please, mommy, can I have that, me hates "initialize variable, incr
> it every loop" sequence, please, me wants automagic $_, please.

I'd prefer if you would somehow explicitly declare it. Not fond of magic
variables. Or at the very least, something with a better name than $_ :P

-- 
                              / http://www.fishpool.com/~setok/
0
setok (206)
2/14/2004 4:49:57 PM
setok@fishpool.com writes:

> Kaitzschu <kaitzschu@kaitzschu.cjb.net.nospam.plz.invalid> wrote:
>>>
>>> Right up until the moment you need to change the [puts] call to
>>>    puts "[lindex $lum $i] $i"
>>>
>>> Would be nice if foreach made up a $_ variable or some such god-awful
>>> perlism that said how many times thru the loop you've gone. :-)
>> 
>> Yes, please, mommy, can I have that, me hates "initialize variable, incr
>> it every loop" sequence, please, me wants automagic $_, please.
>
> I'd prefer if you would somehow explicitly declare it. Not fond of magic
> variables. Or at the very least, something with a better name than $_ :P
>
> -- 
>                               / http://www.fishpool.com/~setok/

honestly what is the big deal, this works:

% set e 0
%  foreach bob {a b c d} {
incr e
puts "bob==$bob count==$e"
}
bob==a count==1
bob==b count==2
bob==c count==3
bob==d count==4

marc
0
mspitze1 (98)
2/14/2004 8:07:34 PM
On Sat, 14 Feb 2004, Marc Spitzer wrote:

> >>> Would be nice if foreach made up a $_ variable or some such god-awful
> >>> perlism that said how many times thru the loop you've gone. :-)
> >>
> >> Yes, please, mommy, can I have that, me hates "initialize variable, incr
> >> it every loop" sequence, please, me wants automagic $_, please.
> >
> > I'd prefer if you would somehow explicitly declare it. Not fond of magic
> > variables. Or at the very least, something with a better name than $_ :P
>
> honestly what is the big deal, this works:
>
> % set e 0
> %  foreach bob {a b c d} {
> incr e
> puts "bob==$bob count==$e"
> }

Works, yes, but
	foreach -var e bob {a b c d} {puts "bob==$bob count==$e"}
would be nicer. Would it?

-- 
-Kaitzschu
0
kaitzschu1 (358)
2/15/2004 12:09:56 AM
Kaitzschu <kaitzschu@kaitzschu.cjb.net.nospam.plz.invalid> writes:

> On Sat, 14 Feb 2004, Marc Spitzer wrote:
>
>> >>> Would be nice if foreach made up a $_ variable or some such god-awful
>> >>> perlism that said how many times thru the loop you've gone. :-)
>> >>
>> >> Yes, please, mommy, can I have that, me hates "initialize variable, incr
>> >> it every loop" sequence, please, me wants automagic $_, please.
>> >
>> > I'd prefer if you would somehow explicitly declare it. Not fond of magic
>> > variables. Or at the very least, something with a better name than $_ :P
>>
>> honestly what is the big deal, this works:
>>
>> % set e 0
>> %  foreach bob {a b c d} {
>> incr e
>> puts "bob==$bob count==$e"
>> }
>
> Works, yes, but
> 	foreach -var e bob {a b c d} {puts "bob==$bob count==$e"}
> would be nicer. Would it?

not necessarily, if indexing is a primary concern then use a for loop.
foreach says go through this list and do stuff, if I need some other
info I just add the code instead of looking up the annoying option
that I never use enough to remember.  Also my way you can have 0 or 1
or -42 based indexing or any steping function I want to use.  Your way
I would be stuck or do it my way anyway.

marc
0
mspitze1 (98)
2/15/2004 1:24:24 AM
On Sun, 15 Feb 2004, Marc Spitzer wrote:

> >> honestly what is the big deal, this works:
> >>
> >> % set e 0
> >> %  foreach bob {a b c d} {
> >> incr e
> >> puts "bob==$bob count==$e"
> >> }
> >
> > Works, yes, but
> > 	foreach -var e bob {a b c d} {puts "bob==$bob count==$e"}
> > would be nicer. Would it?
>
> not necessarily, if indexing is a primary concern then use a for loop.
> foreach says go through this list and do stuff, if I need some other
> info I just add the code instead of looking up the annoying option
> that I never use enough to remember.  Also my way you can have 0 or 1
> or -42 based indexing or any steping function I want to use.  Your way
> I would be stuck or do it my way anyway.

foreach -var e -base -42 -step [expr {int(42*rand())}] bob {a b c d}

Now we are _really_ getting somewhere, aren't we? Meaning the psychiatric
ward :P
You must admit, that there are more [foreach]s out there that do have
zero- or one-based indexing, and that step with +1, than [foreach]s with
base -42 and random stepping.
Also, there are (probably) some uses to tk_optionMenu. Now, _I_ don't use
tk_optionMenu, but someone else (apparently) does, _you_ wouldn't use
foreach -var, but (maybe) someone else would.

Oh, this is going to be a poor post. Waking up this early is not human.
Well, maybe someone got my point, probably not, I'm off to see some
rodents ->

-- 
-Kaitzschu
0
kaitzschu1 (358)
2/15/2004 7:05:34 AM
Kaitzschu <kaitzschu@kaitzschu.cjb.net.nospam.plz.invalid> wrote in message news:<Pine.GSO.4.58.0402150858010.5929@paju.oulu.fi>...
> On Sun, 15 Feb 2004, Marc Spitzer wrote:

> Also, there are (probably) some uses to tk_optionMenu. Now, _I_ don't use
> tk_optionMenu, but someone else (apparently) does

Actually I use tk_optionMenu fairly often as a portable 
replacement for a read-only combobox. In fact I like them 
better in one particular way--you can click anywhere on 
the widget to get it to pop down as opposed to the small 
little arrow button.

Keith
0
keithv (23)
2/16/2004 5:15:24 AM
David McClamrock wrote:
> 
> Arjen Markus wrote:
> > Care to put this on the Wiki? Or submit it for Tcllib?
> 
> Maybe--after I've thoroughly reworked it! :o)
> 
> David McClamrock

:)
0
arjen.markus (2628)
2/16/2004 8:06:01 AM
Kaitzschu wrote:
> On Sat, 14 Feb 2004, Marc Spitzer wrote:

>>honestly what is the big deal, this works:
>>
>>% set e 0
>>%  foreach bob {a b c d} {
>>incr e
>>puts "bob==$bob count==$e"
>>}
> 
> 
> Works, yes, but
> 	foreach -var e bob {a b c d} {puts "bob==$bob count==$e"}
> would be nicer. Would it?

http://mini.net/tcl/4469

-- 
  .-.    .-. .---. .---. .-..-. | Experts in Linux/Unix: www.WildOpenSource.com
  | |__ / | \| |-< | |-<  >  /  | "Making the bazaar more commonplace"
  `----'`-^-'`-'`-'`-'`-' `-'   | Check out my new novel: "Cloud Realm" at:
   home: www.smith-house.org    | http://www.smith-house.org/books/list.html

0
larry8761 (92)
2/16/2004 5:29:47 PM
David McClamrock <mcclamrock@locl.net> writes:
> When the "uplevel" wasn't there, the proc wouldn't recognize variables that
> had been set in the global scope and weren't mentioned in the proc; when it
> was, it would. But I'd prefer to avoid "uplevel" altogether and use an
> integer range generator for "foreach," which I didn't know about until now.

There's a basic problem with the integer range generator.  Consider

   foreach i [.. 1 1000000] { ... }

First, you create a list containing a million elements, then you
iterate over it.  Python has some magic behind the scenes so that
it only *looks* like you create a list containing a million elements.

If you're only iterating over small ranges it's OK, but it doesn't
scale nicely.

Will
0
will237 (2)
2/17/2004 7:08:06 PM
Will Duquette <will@dhcp-78-62-241.jpl.nasa.gov> wrote:

: There's a basic problem with the integer range generator.  Consider

:   foreach i [.. 1 1000000] { ... }

: First, you create a list containing a million elements, then you
: iterate over it.  Python has some magic behind the scenes so that
: it only *looks* like you create a list containing a million elements.

Hmm, lazy evaluation in Tcl? Sounds interesting. Actually, may be 
Tcl_Obj mechanism could allow to create "pseudo-list" object which would 
return elements on request. Or we need three-ported objects instead of
dual-ported for this

-- 

: How would you disambiguate these situations?

By shooting the person who did the latter.
             -- Larry Wall in <199710290235.SAA02444@wall.org>
0
vitus
2/17/2004 9:16:42 PM
Victor Wagner <vitus@45.free.net> wrote:
>  Will Duquette <will@dhcp-78-62-241.jpl.nasa.gov> wrote:
>  
> : There's a basic problem with the integer range generator.  Consider
>  
> :   foreach i [.. 1 1000000] { ... }
>  
> : First, you create a list containing a million elements, then you
> : iterate over it.  Python has some magic behind the scenes so that
> : it only *looks* like you create a list containing a million elements.
>  
>  Hmm, lazy evaluation in Tcl? Sounds interesting. Actually, may be 
>  Tcl_Obj mechanism could allow to create "pseudo-list" object which would 
>  return elements on request. Or we need three-ported objects instead of
>  dual-ported for this

A quick (dare I say lazy) search of the subject on the wiki reveals:
    http://wiki.tcl.tk/2515
    http://wiki.tcl.tk/3356
    http://wiki.tcl.tk/4833



-- 
Glenn Jackman
NCF Sysadmin
glennj@ncf.ca
0
xx087 (199)
2/17/2004 9:34:22 PM

Glenn Jackman wrote:

> Victor Wagner <vitus@45.free.net> wrote:
> 
>> Will Duquette <will@dhcp-78-62-241.jpl.nasa.gov> wrote:
>> 
>>: There's a basic problem with the integer range generator.  Consider
>> 
>>:   foreach i [.. 1 1000000] { ... }
>> 
>>: First, you create a list containing a million elements, then you
>>: iterate over it.  Python has some magic behind the scenes so that
>>: it only *looks* like you create a list containing a million elements.
>> 
>> Hmm, lazy evaluation in Tcl? Sounds interesting. Actually, may be 
>> Tcl_Obj mechanism could allow to create "pseudo-list" object which would 
>> return elements on request. Or we need three-ported objects instead of
>> dual-ported for this
> 
> 
> A quick (dare I say lazy) search of the subject on the wiki reveals:
>     http://wiki.tcl.tk/2515
>     http://wiki.tcl.tk/3356
>     http://wiki.tcl.tk/4833

There is also http://wiki.tcl.tk/iterators

-- 
-eric

0
beric (16)
2/18/2004 8:19:09 AM
According to Victor Wagner <vitus@45.free.net>:
:Hmm, lazy evaluation in Tcl? Sounds interesting. Actually, may be 
:Tcl_Obj mechanism could allow to create "pseudo-list" object which would 
:return elements on request. Or we need three-ported objects instead of
:dual-ported for this


I wonder - we've seen people who wrote virtual listboxes, etc. so they
could do 'lazy display' of data.  I seem to recall something similar being
written for MetaKit (perhaps in KitViewer), so that not all of the
metakit database need be read into memory at one time.

In the case of an iterator, can we just create a snit/itcl/xotcl/.../
object that has state and methods for what is needed?
-- 
<URL: http://wiki.tcl.tk/ > In God we trust.
Even if explicitly stated to the contrary, nothing in this posting
should be construed as representing my employer's opinions.
<URL: mailto:lvirden@yahoo.com > <URL: http://www.purl.org/NET/lvirden/ >
0
lvirden272 (610)
2/20/2004 12:47:46 PM
lvirden@yahoo.com wrote in message news:<c14vli$c7l$4@srv38.cas.org>...
> In the case of an iterator, can we just create a snit/itcl/xotcl/.../
> object that has state and methods for what is needed?

Sure, defining an for like iterator in xotcl is quite simple:

# Define the meta class VClass to create new volatile objects 
# on unknown calls
Class VClass -superclass Class \
  -instproc unknown {m args} {
    uplevel [self] new -volatile $m $args
  }

# Define an Iterator named iter using the tcl for statement
VClass iter -parameter {{from 0} to {step 1} code {var _}} \
  -instproc init {} {
    upvar [my var] _
    for {set _ [my from]} {$_<[my to]} {set _ [expr {$_+[my step]}]} {
      uplevel [my code]
    }
  }

# now try the iterator: 
proc foo {text} {
  iter -to 3 -code {puts "$_: $text"}
  iter -var x -to 30 -from 27 -code {puts "$text - $x"}
}
foo hello

### This code prints:
0: hello
1: hello
2: hello
hello - 27
hello - 28
hello - 29

The two instances of the iterator are deleted upon exit of foo 
due to 'new -volatile' in VClass.

The advantage on using objects here is not overwhelming.
however, one can use introspection within the code
to query the parameters, different kind of loops can be
defined easily, etc.

-gustaf neumann
0
neumann8225 (127)
2/23/2004 12:15:32 AM
Reply:

Similar Artilces:

""""""""""""""""""""""ADD ME""""""""""""""""""""
Hi , Hope you are doing great. Please let me take this opportunity to introduce myself, Iam Karthik working with BhanInfo Inc, a NY based company. We have consultants on our bench on various technologies, my request is to add me to your distribution list and kindly do send me the requirements. i have the below list available 1. Mainframe 2. Java 3.. Financial Analyst 4. Data Architect If there is any vendor ship agreement which has to be signed then I would like to take an opportunity to represent my company and expect your cooperation... We look forward to build a ve...

"""""""""ADD ME""""""""""
Hi , Hope you are doing great. Please let me take this opportunity to introduce myself, Iam Karthik working with BhanInfoi Inc, a NY based company. We have consultants on our bench on various technologies, my request is to add me to your distribution list and kindly do send me the requirements. i have the below list available 1. Mainframe 2. Java 3.. Financial Analyst 4. Data Architect If there is any vendor ship agreement which has to be signed then I would like to take an opportunity to represent my company and expect your cooperation... ...

Urgent Requirement in """""""""""""NEW YORK""""""""""""""""
Hello Partners, Please find the requirement below. Please send the updated resume along with rate and contact no. REQ#1: Title : Java Developer ( Rating Project) Duration : 6 months Rate : open Location : NY strong java, WebLogic 9.2, Web Services, Oracle REQ#2: Title : Java Developer Duration : 4 months Rate : open Location : NY Strong java, SQL REQ#3: Title : VB.Net Consultant Location : NY Duration : 4 months Rate : open Primarily looking at someone who has Excel, VB.net a...

"or" and "and"
Hi, I'm just getting to discover ruby, but I find it very nice programming language. I just still don't understand how the "or" and "and" in ruby... I was playing with ruby and for example made a def to print Stem and Leaf plot (for those who didn't have a statistics course or slept on it, e.g. http://cnx.org/content/m10157/latest/) Here is the Beta version of it: class Array def n ; self.size ; end def stem_and_leaf(st = 1) # if st != (2 or 5 or 10) then ; st = 1 ; end k = Hash.new(0) self.each {|x| k[x.to_f] += 1 } k = k.sort{|a, b| a[0].to_f <=&g...

about "++" and "--"
why this program snippet display "8,7,7,8,-7,-8" the program is: main() { int i=8; printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--); } > why this program snippet display "8,7,7,8,-7,-8" Ask your compiler-vendor because this result is IMHO implementation-defined. Check this out: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.15 http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.16 Regards, Irina Marudina fxc123@gmail.com wrote: > why this program snippet display "8,7,7,8,-7,-8&q...

why "::", not "."
Why does the method of modules use a dot, and the constants a double colon? e.g. Math::PI and Math.cos -- Posted via http://www.ruby-forum.com/. On Oct 26, 2010, at 01:48 , Oleg Igor wrote: > Why does the method of modules use a dot, and the constants a double > colon? > e.g. > Math::PI and Math.cos For the same reason why inner-classes/modules use double colon, because = they're constants and that's how you look up via constant namespace. Math::PI and ActiveRecord::Base are the same type of lookup... it is = just that Base is a module and PI is a float....

"If then; if then;" and "If then; if;"
I have a raw data set which is a hierarchical file: H 321 s. main st P Mary E 21 F P william m 23 M P Susan K 3 F H 324 S. Main St I use the folowing code to read the data to creat one observation per detail(P) record including hearder record(H): data test; infile 'C:\Documents and Settings\retain.txt'; retain Address; input type $1. @; if type='H' then input @3 Address $12.; if type='P' then input @3 Name $10. @13 Age 3. @16 Gender $1.; run; but the output is not what I want: 1 321 s. main H 2 321 s. main P Mary E 21 F 3 321 s...

"my" and "our"
Hi, while testing a program, I erroneously declared the same variable twice within a block, the first time with "my", the second time with "our": { my $fz = 'VTX_Link'; .... ( around 200 lines of code, all in the same block) our $fz = 'VTX_Linkset'; ... } So the initial contents of the $fz declared with "my" is lost, because "our" creates a lexical alias for the global $fz, thus overwriting the previous "my" declaration. It was my error, no question. But I wonder why Perl doesn't mention this - even with "use s...

"out" and "in out"
Hi i found the following explaination: In Ada, "in" parameters are similar to C++ const parameters. They are effectively read-only within the scope of the called subprogram. Ada "in out" parameters have a reliable initial value (that passed in from the calling subprogram) and may be modified within the scope of the called procedure. Ada "out" parameters have no reliable initial value, but are expected to be assigned a value within the called procedure. What does "have no reliable initial value" mean when considering the "out" parameter? By c...

"/a" is not "/a" ?
Hi everybody, while testing a module today I stumbled on something that I can work around but I don't quite understand. >>> a = "a" >>> b = "a" >>> a == b True >>> a is b True >>> c = "/a" >>> d = "/a" >>> c == d True # all good so far >>> c is d False # eeeeek! Why c and d point to two different objects with an identical string content rather than the same object? Manu Emanuele D'Arrigo wrote: >>>> c = "/a" >>>&...

Urgent Requirement for """""""""""""""INFORMATICA DEVELOPER"""""""""""""
Hello Partners, How are you ? Please find the requirements below. Title: Database/ETL Developer Duration: 6 months Location: NY Exp: 7+ Locals preferred Database/ETL requirements (Mandatory) Candidate must have worked with financial instruments, preferably Mutual Funds but, Equities are also ok. PL/SQL - packages, Stored procs, Functions, Aggregate functions, Pipelined Functions Informatica 8.6 - especially complex mappings, complex maplets, complex workflows, transformations Oracle 10g/11g Unix/Linux shell scripting ...

Urgent need """""""""""INFORMATICA DEVELOPER"""""""""""""
Hello Partners, How are you ? Please find the requirements below. Title: Database/ETL Developer Duration: 6 months Location: NY Exp: 7+ Locals preferred Database/ETL requirements (Mandatory) Candidate must have worked with financial instruments, preferably Mutual Funds but, Equities are also ok. PL/SQL - packages, Stored procs, Functions, Aggregate functions, Pipelined Functions Informatica 8.6 - especially complex mappings, complex maplets, complex workflows, transformations Oracle 10g/11g Unix/Linux shell scripting Database/ETL requirements (Optional) ...

A problem about "[ ]" "( )" "="
I want to read several images saved in a director,and give them to I1,I2 ,I3....,using the following codes: filelist=dir(['c:\MATLAB701\work\...\*.jpg']); for i=1 :length(filelist) I=imread(fullfile('c:\MATLAB701\work\...',filelist(i).name)); end; but failed. Then I used I(i)=imread... ,still failed. How could I do? "John" <mailofww@126.com> wrote in message news:ef19e12.-1@webx.raydaftYaTP... >I want to read several images saved in a director,and give them to > I1,I2 ,I3....,using the following codes: > filelist=dir(['c:\MATLAB701\work\.....

Does it need a ";" at the very after of "if" and "for"
write code like: int main(void) { int a=10; if(a<20) {} } Compiler ok on dev-cpp . don't we have to add a ";" after if statement? marsarden said: > write code like: > > int main(void) > { > int a=10; > if(a<20) > {} > } > > Compiler ok on dev-cpp . don't we have to add a ";" after if > statement? The syntax for 'if' is: if(expression) statement There is no semicolon after the ) but before the statement. The statement is either a normal statement (which can be empty), ending in a semicolon:- if(expr) ...

Web resources about - Use "range," not "for"? - comp.lang.tcl

Resources last updated: 2/8/2016 4:04:35 AM