Re: Why doesn't foreach return a value



tom.rmadilo wrote:
On Jan 30, 8:47 am, Darren New <d...@xxxxxxxxxx> wrote:
tom.rmadilo wrote:
Foreach actually never 'goes away', so how could it return?
Of course it returns, like every other command does. (Well, except
infinite loops.) What do you mean "goes away"?

Call 'return' inside a loop and you will discover the difference
between a function/proc and a foreach loop. Foreach doesn't 'go away',
because the foreach body is executed in the current context.

I have no idea what you think "go away" means there. I know the difference between a proc and foreach. Call [break] inside a proc and the proc doesn't "go away" either. Call [error] and both the proc and the foreach it's in "go away".

So, no, I haven't any idea why you think the call to [foreach] doesn't return. Or maybe you're using the words in some odd context that's different from what other people mean.

Yes, in Tcl, but this is a syntactic feature of the language.

No, that's a fundamental part of the language. It's not like 'for' and 'while' being different syntaxes for essentially the same thing in C. It's part of what makes Tcl powerful.

Is the purpose to return a
value, or to perform some operation, or both?

Since foreach always returns the same value (modulo error cases), then the obvious answer is that it's to perform the looping operation. Some constructs loop, some return values, some do both.

If you don't make these
distinctions, but only compare the syntactic similarities, you will
have difficulty accounting for other commands like [catch], [return -
code return], [error], etc.

I have no difficulty accounting for these commands, because I understand what they do.

In this case, if you store the result of the function call, I assume
you want the value, otherwise you don't.

Well, yeah, that kind of goes without saying.

I doubt you will find any logical support for anything in particular.
Returning either the second argument or the final value of the first
argument or the length of the second argument might all be useful. But
these are all things that are trivial to get in other ways.


The final values are already available:

% foreach a {b c d} {break}
% puts $a
b

That's part of what makes it trivial to get that value in other ways.

If "break" was changed to take an argument, returning the value passed
to break might be interesting. But again, I expect this can already be
done with clever use of [return].

You don't usually [return] from a loop. (You can, but the [return] is
applied to the context, not the loop boundary.

[return] is the same thing as [break] and [continue] and [error], except returning different values. You do know that, right?

The problem of building in some additional meta-data is that it would
then be required to exist for every loop. How will this information be
accessed?

I'd assume through the Tcl result string. That's kind of what returning a result entails.

? The commands [break] and [continue] are part of the control
code, so you can do whatever you want before you call them.

I'm not real sure what this sentence means. [break] and [continue] are very straightforward commands. They're commands, not "control code".

The most obviously useful information would be some kind of metadata
which documents what happened, mostly for the case of continuing,
Continuing what? The loop runs until it exits, at which point you don't
continue it.


[continue] at the next iteration of the loop by skipping everything
following the [continue] command.

Oh. Well, in any case, it's pretty easy to assign to a variable "what happened", and then invoke [continue].

That is pretty much my point. If you break up a paragraph of my
statements and ask a question for each one, you miss the larger point.
There is not logical chunk of meta-data to track (like maybe exactly
how many iterations were completed, which if any iterations used
[continue], etc.) These are all useful in some situations, but not
generally.

Sure. And it's all stuff that's probably more clear to track manually, given how [foreach] is usually used.

Whether the loop ran off the end or exited via [break] is something that's often useful to me, actually. If I'm looking for something and find it and [break], not having to [set found 0] outside and [set found 1] inside might be more clear.

not even mentioning the ugliness of the code:

I don't know...

set found [foreach row $rows {
if {$row == ""} break
if {$row < $smallest} break
... do some processing on row ...
if {$processedrow in $goodvalues} break
puts "$row isn't any good"
}]

Seems no less straightforward than [catch]. Indeed, I'd vote for the return code that made foreach exit as the return value of foreach.


--
Darren New / San Diego, CA, USA (PST)
On what day did God create the body thetans?
.



Relevant Pages

  • Re: Count Lines in (Huge) Text Files
    ... A few years ago, I was doing some high-throughput disk stuff and my recollection is that I found the same thing you did: larger buffers only helped up to about 8K or so, and past that any improvement was minimal. ... me that with appropriate settings for its buffer, it should perform better, since it ought to be optimized for line-based i/o. ... Assuming what's hurting you in the explicit forloop is the retrieval of the data and not the counter increment, the above should perform basically as well as a plain foreach() loop. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: a question about for and foreach
    ... foreach (@array) { ... why @array are changed after this foreach loop!!! ... The "foreach" loop iterates over a normal list value and sets the ... If any element of LIST is an lvalue, you can modify it by modifying ...
    (perl.beginners)
  • Re: Lost data on socket - Can we start over politely?
    ... $clsel as a single-element-holding object containing the current ... simply performing the following check on $sel instead of $clsel? ... removing elements from something from a list used for the loop is a Bad ... Doesn't that throw the foreach() loop out of sync? ...
    (comp.lang.perl.misc)
  • Re: foreach statement output
    ... > I'm still trying to get an understanding of the way a foreach loop loops. ... You can't use the loop variable as an index to your array. ...
    (comp.infosystems.www.authoring.cgi)
  • Re: array and hash patter matching
    ... however I am struggling on how to compare the hash with an array for any ... Why are you using this foreach loop inside the while loop? ... client_list is a list of one or more host names, host addresses, ...
    (perl.beginners)