Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by adrianh (Chancellor) on Sep 29, 2005 at 14:39 UTC
|
print map { uc "$_ " } qw( i cannot believe you missed out map ), "\n"
| [reply] [d/l] |
|
Bah. Map is extremely limited. Now fold on the other hand...
| [reply] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by ambrus (Abbot) on Sep 29, 2005 at 19:12 UTC
|
I certainly wouldn't think it's a
drag to use just one kind of loop:
it can be kind of elegant.
However, the rest of my life is just too long,
my opinion on which single loop is elegant varies with time.
Also I wouldn't use a single loop just because I'm
forced to it: I like TIMTOWTDI languages that
don't force me to use a single programmign style.
Scheme basically has one kind of looping construct:
tail recursion.
However, it has some advanced special forms
built upon tail recursion.
It has let which is just a short notation for tail
recursion.
But the most important looping construct is do
which is by itself so powerful that one could
program using only it.
However, using do comes out really good
only if you're doing side-effectless programming,
which I don't always like.
(There's a do form in common lisp too, which is similar
in form but very different deep down. That do
<disgust>changes the values of loop variables</disgust>,
so it's not side-effect-less, and has nothing to do
with tail recursion which Common lisp doesn't have anyway.)
What I've said above is not entirely true:
there's one more way of looping in scheme apart from
calls and tail calls: call-with-current-continuation
is by itself a universal looping construct.
It's however not something I'd use as a single looping
construct in my whole life.
(Even worse than that would be to use only
setjmp/longjmp in C.)
If my mind is in a
low level state,
I could live with only conditional gotos.
If I program C, I'd definitely go with for.
(That's what I've voted for.)
It's just much more general than while.
To tell the truth, just about any looping construct is
more general than while.
It's also nice that you don't have to look at keywords
if you only use if and for as they
have different number of argumets.
So, I definitely don't like while.
(Update: I forgot to mention it, but I did mean
using only for seriously: Re: Pattern matching)
At one time, I thought that the best looping
construct was { ...; ... and last; ...; redo }.
This is not only my mania, as the while loop in bash,
and the \loop ... \repeat macros in Plain TeX work like
this.
At that time, I actually wrote a toy language where the only
looping construct was ( COMMANDS; *) which executed
COMMANDS repeatedly.
You can exit from it with
the COND ? RET operator which exited from the innermost
pair of parentheses
iff COND stands, and make the result of the parenthisized
expression be RET.
I certainly wouldn't choose foreach as the
single looping construct, as I've learnt
that it wouldn't give me a Turing-complete language.
In logician terms, we say that you can build
constructive languages from foreach,
which is a true subset of the set of
recursively enumerable languages.
Update 2010-10-17: see also the other poll Re: My favorite looping mechanism in Perl is:.
| [reply] [d/l] [select] |
|
| [reply] |
|
That's it: an infinitely looping foreach isn't a foreach.
It's not a foreach in perl.
It's not a for-each in standart scheme either, as
r5rs clearly says that the arguments to for-each are lists.
(In some interpreters, you can give an infinite list to
for-each, but that's clearly an extension. Others, like
mzscheme, raise an error on an infinite list.)
For in sh and foreach in csh won't allow you to loop
infinitely (except for the new arithmetic for loop in bash,
but that's not a foreach loop, it's rather a c-style for
loop).
| [reply] |
|
|
|
|
If I program C, I'd definitely go with for. (That's what I've voted for.) It's just much more general than while. To tell the truth, just about any looping construct is more general than while.
Now I'm curious. Could you give an example of a loop you could write with "for" that you couldn't write with "while"?
#include<stdio.h>
int main(int argc, char** argv)
{
int a = 0;
while(a++,a<10)
{
printf("%d\n",a);
}
}
| [reply] [d/l] |
|
While it's true you can do anything you can do with a for loop with a while loop, I picked for.
I really like the capability that for gives you to keep all the operations controlling the loop - initialisation, incrementing and testing - in one place. In C99 (and Perl) you can declare variables in the for statement, and they will have a scope of precisely the for loop. You'll need an extra block to do that with while. So taking the example above, I assume this is intended to synthesise (updated:) ambrus noted that this is equivalent to:
// UNTESTED
for(int a = 1; a<10; a++)
{
printf("%d\n",a);
}
In fact, you'll need an extra block to get the correct scope:
// UNTESTED
// UPDATED: de-obfuscated
{
int a = 1;
while(a<10)
{
printf("%d\n",a);
a++;
}
}
Which is starting to look rather messy.
Context switch back to Perl here!
Synthesising while and foreach from for seems reasonably intuitive to me on the other hand.
# UNTESTED
for (;EXPR;) BLOCK # leave first and third EXPRs blank to be
# equivalent to while (EXPR) BLOCK
# UNTESTED
for (my @list = LIST, VAR = shift @list; # iterate manually through
@list; # LIST in "for" to be
VAR = shift @list) BLOCK # somewhat like
# foreach VAR (LIST) BLOCK
# without the usual aliasing
OK, the foreach is starting to look a bit funny, but a foreach from while will be worse, and spread into the block, rather than be confined to the statement itself.
One issue is that for doesn't have a continue block, but as I come from C I don't tend to use those. continue blocks also split up code that happens every time round the loop, which puts me off. for's third expression is roughly equivalent I suppose, but stuffing a large continue block there could hardly be called good style.
Recursion is another story but I don't think I could live with it as the only looping mechanism. I'd rather have the reverse issue of synthesising recursion, say with a list of hashes, on the rare occasions I really needed it.
updated in response to ambrus's comments.
Also, note:
perl -MO=Deparse -e "for (;<>;){print}"
while (defined($_ = <ARGV>)) {
print $_;
}
-e syntax OK
the for deparses as a while! | [reply] [d/l] [select] |
|
|
| [reply] |
|
I certainly wouldn't choose foreach as the single looping construct, as I've learnt that it wouldn't give me a Turing-complete language. In logician terms, we say that you can build constructive languages from foreach, which is a true subset of the set of recursively enumerable languages.
Who cares about Turing completeness? You're running on a machine with a finite number of states; so a DFA language is all you can really implement in real life. Turing complete languages can't be implemented; just approximated.
Godel's theorem implies that any language you design is by definition incomplete; no matter how big you make the field of numbers that it enumerates, you can make an infinite number of infinitely more expressive languages (which is unsurprising, since Cantor proved that there are an infinite number of magnitudes of infinities, making the whole thing hard to talk about...)
It's silly to stop with a Turing machine; why not work over a bigger field than the integers, if you're just doing abstract math for the fun of it? And if you're not just doing abstract math for the fun of it, why are you bothering to talk about infinity at all?
--
AC
| [reply] |
|
Who cares about
Turing completeness? You're running on a machine with a finite
number of states; so a DFA language is all you can really
implement in real life. Turing complete languages can't be
implemented; just approximated.
I could attack this statement from the theocretical side.
Computer hardware is developping in a very fast pace.
Let's imagine you have a system where
the state of the program can be saved and reloaded on a
machine with more memory,
or one that runs on a transparent
cluster of machines where new nodes can be added dynamically
and old nodes discarded.
Such a system could run forever, if you keep updating it with
new hardware.
While my lifetime or the lifetime of the computer I'm typing
on right now is certainly finite, such an advanced system
could live forever, if the civilisation doesn't end in
some catastrophe.
(In fact, Paul Davies argues in his book
The Last Three Minutes that a super-entity
could do an infinite number of calculations,
and discusses this in the two cases of whether the Universe
will expand forever and end in a Big Chill, or
gravitation will win and the Universe will end in a
Big Crunch.)
However, even if a DFA is all you can implement in the
real-world
(there are some steps between the DFA and a Turing
machine in power of course),
I am a mathematician, and I'd like to at least imagine that
I have a Turing-complete machine.
I use it even if it's only a theocretical construction.
I am not an engineer, who uses a ruler to draw straight line,
and uses large plastic templates to be able to draw any
kind of ellipse.
I just draw a bumpy line or a potato by hand, and say it's
a straight line (moreover,
an infinitely extending straight line that has no width or
thickness) or an ellipse.
This is a very pleasant, almost god-like state,
because I can create objects engineers can't even dream of
just by the power of my mind.
Naturally, this is not the real reason I wouldn't rely on
foreach loops.
The reason is simply that they're often difficult to use.
It's not easy to convert while loops to foreach loops.
It's even more difficult to do it if you care about efficency
(because I don't just have any DFA, but a DFA with a
limited number of states and limited speed of execution).
Foreach loops require to use side-effects even if I
don't want to, and you could easily avoid it with do loops.
Foreach loops come in different versions
in each programming language.
But the deciding reason is that C doesn't have a
foreach loops, so if I decided on foreach, I couldn't use
C anymore.
Update: "it's silly to stop with a Turing-machine" -- you're
right with this part.
"Why not use a bigger field(?) than the integers" -- indeed, why not:
Symbolic calculations with operator overload, Re^3: Illegal Modulus zero.
| [reply] |
|
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by prasadbabu (Prior) on Sep 29, 2005 at 14:18 UTC
|
while(1)
{
print "Rest of my days\n";
}
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by gloryhack (Deacon) on Sep 30, 2005 at 00:17 UTC
|
while ($bastard -> state() =~ /^alive$/i) {
$bastard -> beat(severity => $max);
}
$cool_looping_constructs -> restore();
| [reply] [d/l] |
|
$bastard->beat(severity => $max)
while ( lc($bastard->state()) eq 'alive' );
$cool_looping_constructs->restore();
| [reply] [d/l] [select] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by wolfger (Deacon) on Sep 30, 2005 at 01:42 UTC
|
Maybe we should abolish all loops entirely, and force programmers to manually iterate.
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by theorbtwo (Prior) on Sep 29, 2005 at 14:40 UTC
|
Really, the only loop you need is a bare block... but if I'm going to play "build your own loop" games, I use while (1) {...}, so I know there's "interesting" games going on.
Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by diotalevi (Canon) on Sep 29, 2005 at 17:40 UTC
|
Hey! Where's my (loop ...) macro!? | [reply] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by gri6507 (Deacon) on Sep 29, 2005 at 14:03 UTC
|
What about GOTO? You could do just about everything with that!Update Sorry, I glanced at the "Nested labeled goto spaghetti loop" option too fast and was confused by its accidental reference to The Church of the Flying Spaghetti Monster.
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by ciderpunx (Vicar) on Sep 30, 2005 at 16:16 UTC
|
One more kind of loop ...
$self->try_and_kill_bastard until ($successful);
;-P
Update Just realized you could read that either way. It has been a long week, but I'd like to assure the monks that I'm not feeling suicidal quite yet ...
| [reply] [d/l] |
|
unless ($bastard eq 'ciderpunx') {
$self->try_and_kill($bastard) until ($successful);
}
Hey, I saved your life ;)
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by BrowserUk (Patriarch) on Oct 01, 2005 at 13:38 UTC
|
{
...
redo;
...
}
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by Happy-the-monk (Canon) on Sep 29, 2005 at 21:47 UTC
|
Lindy Circle
Lindy Turn.
Alas, I will now have to write an article to explain what that is...
(Update: and I keep confusing them, you see.)
Cheers, Sören
| [reply] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by renodino (Curate) on Sep 30, 2005 at 04:25 UTC
|
| [reply] |
|
if(($able_to_use eq 'for')||($able_to_use eq 'while')||($able_to_use e
+q 'foreach'))
{
while $living -e or die "Unable to live without a loop $:";
}
prad | [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by arc_of_descent (Hermit) on Oct 03, 2005 at 03:16 UTC
|
Definitely a foreach over a for
Wouldn't want to be stuck with a $_ in my loops now for the rest of my life. I prefer a meaningful name for the it variable
| [reply] |
|
(Updated) I rather feel some people would regret their choices. Only recursion can replace all the others, although I voted for for, because recursion is not technically a loop and in many replacement scenarios it would need some horrible overworking to overcome certain scoping issues, but for has enough machinery to replace everything else except recursion. For example, while (condition) is functionally the same as for (;condition;) and do {} while (condition) could be replaced by for (my $first = 1; $first or condition; $first=0) {}
| [reply] [d/l] [select] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by theroninwins (Friar) on Oct 04, 2005 at 12:34 UTC
|
Well I love while loops ...but that is a personal think :-). They helped me many times before. But here I went for the italian option (shagetthi nested...), since someone would FORCE me to just keep to them. Just to show him what just one sort of loops could mean :-). | [reply] |
Missing Poll Option!
by Anonymous Monk on Sep 30, 2005 at 23:31 UTC
|
Self-triggering event loop! :-)
You set attribute X which sets attribute Y which sets attribute X which sets attribute Y which sets attribute X ... until the CPU catches fire!
Hehehehe....
| [reply] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by radiantmatrix (Parson) on Oct 06, 2005 at 21:35 UTC
|
What about until? I voted for while, in any case, because I can trivally (if annoyingly) make for loops with while, but the other way 'round is not so easy.
my $counter = 0;
while ($counter <= 5) {
print $counter;
$counter++;
}
| [reply] [d/l] |
Re: If I was forced to use only one kind of loop for the rest of my days it would be a
by saskaqueer (Friar) on Oct 08, 2005 at 15:51 UTC
|
I missed the 'triple nested labeled goto spaghetti loop' and wound up voting for the simply uninteresting 'labeled block'. My reasoning behind wanting the triple nested goto block is simple enough: if I'm going to be using the construct for the short eternity of my life, I'd better enjoy using it. Just reming yourself that you are going to drive yourself crazy using one looping mechanism, so you'd might as well choose the crazy one.
# why code this (equiv: print $_, "\n" for 1 .. 10;)
for my $i (1 .. 10) {
print $i, "\n";
}
# when you can code this? -- untested, no perl
# on current box; probably doesn't do what
# the above snippet does, but it's suppose to
my $i = 0;
ONE:
{
$i -= (8 - 2 * 2 - 2 * 4); # $i += 4
goto FOUR;
TWO:
{
print $i;
THREE:
{
print "\n";
10 == $i ? exit() : goto ONE;
FOUR:
{
$i += 3 * -1; # $i -= 3;
goto TWO;
}
}
}
}
| [reply] [d/l] |