Recent

Poll

I want for-loops with custom step widths (plural!).

false
24 (42.1%)
true
27 (47.4%)
42
6 (10.5%)

Total Members Voted: 57

Author Topic: for loop with custom step width (esp. ≠ 1)  (Read 51355 times)

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
for loop with custom step width (esp. ≠ 1)
« on: December 15, 2016, 02:52:05 am »
Hey,
Code: Pascal  [Select][+][-]
  1. for i := 0 step 2 until 10 do
  2. begin
  3.   writeln(i);
  4. end;
How do I make a for-loop iterate with a custom step width? So everything regarding iteration is in the top line. That'd be more readable than the corresponding Ersatz-statement. Thx for your answers!
Yours Sincerely
Kai Burghardt

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: for loop with custom step width (esp. ≠ 1)
« Reply #1 on: December 15, 2016, 05:00:13 am »
Maybe not the best solution, but I use this:

Code: Pascal  [Select][+][-]
  1. var
  2.   i, idx: integer;
  3. // ...
  4. for i := 0 to 5 do
  5. begin
  6.   idx := i * 2;
  7.   writeln(idx);
  8. end;
« Last Edit: December 15, 2016, 09:49:03 am by Handoko »

balazsszekely

  • Guest
Re: for loop with custom step width (esp. ≠ 1)
« Reply #2 on: December 15, 2016, 06:26:38 am »
Code: Pascal  [Select][+][-]
  1. for( i = 0; i <= 10; i = i + 2 ){
  2.   printf("i: %d\n", i);
  3. }
:P I'm afraid you cannot do this in pascal.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: for loop with custom step width (esp. ≠ 1)
« Reply #3 on: December 15, 2016, 06:53:32 am »
I'm afraid you cannot do this in pascal.
nay sayer !  >:D ;-)

Of course you can do exactly that. You just have to write it a bit differently  :P
Code: [Select]
var
  i: integer;
begin
  i := 0;
  while i < 10 do
  begin
    WriteLn('i: ', i);
    i := i + 2;
  end;
end;

balazsszekely

  • Guest
Re: for loop with custom step width (esp. ≠ 1)
« Reply #4 on: December 15, 2016, 07:13:52 am »
@molly
The OP explicitly talks about a for-loop and "everything regarding iteration is in the top line". Of course you can do it with a while/repeat loop. It can be done even with a recursive function.  :D

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: for loop with custom step width (esp. ≠ 1)
« Reply #5 on: December 15, 2016, 07:36:24 am »
@GetMem:
I just wanted to avoid the misconception that the c code you wrote can't have a Pascal counterpart (the c code seemed to me as placed out of context so i allowed myself to do so as well).

Ok, so ... the following is a for loop ? ;-)

Code: [Select]
var
  i : integer;
  ia: array of integer;
begin
  i := 0;
  while i < 10 do
  begin
    SetLength(ia, Length(ia)+1);
    ia[High(ia)] := i;
    i := i + 2;
  end;
   
  for i in ia do WriteLn('i: ',i);
end;

But, it does raise the question why not support something like:
for i := 0 to 10 step 2 do ...

There once was a time when it was allowed to assign another value to the iterator. A step modifier could at least lift some restriction.

balazsszekely

  • Guest
Re: for loop with custom step width (esp. ≠ 1)
« Reply #6 on: December 15, 2016, 07:57:59 am »
Quote
I just wanted to avoid the misconception that the c code you wrote can't have a Pascal counterpart
In my opinion there is no c code that cannot be done in pascal, perhaps not so efficiently but it can be done.
Regarding your for loop, it's a valid one, but you increased the complexity of the algorithm, now it's a double loop, looks nice though.  :)

Quote
There once was a time when it was allowed to assign another value to the iterator. A step modifier could at least lift some restriction.
Yes, I agree. I don't think it's gonna be implemented though.

minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: for loop with custom step width (esp. ≠ 1)
« Reply #7 on: December 15, 2016, 09:53:59 am »
Reminds me of Sinclair Spectrum BASIC

10 FOR n=10 TO 1 STEP -1
20 PRINT n
30 NEXT n
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

BeniBela

  • Hero Member
  • *****
  • Posts: 906
    • homepage
Re: for loop with custom step width (esp. ≠ 1)
« Reply #8 on: December 15, 2016, 12:30:25 pm »
How about

Code: Pascal  [Select][+][-]
  1.   for i in range(0, 10, 2) do
  2.     writeln(i);
  3.  

?

Needs a little help

Code: Pascal  [Select][+][-]
  1. {$modeswitch advancedrecords}
  2. type TIntRange = record
  3.   c: integer;
  4.   f,t,s: integer;
  5.   function getEnumerator: TIntRange;
  6.   function moveNext: boolean; inline;
  7.   property current: integer read c;
  8. end;
  9.  
  10. function range(f,t: integer; s: integer=1): TIntRange;
  11. begin
  12.   result.c := f - s;
  13.   result.f := f;
  14.   result.t := t;
  15.   result.s := s;
  16. end;
  17.  
  18. function TIntRange.getEnumerator: TIntRange;
  19. begin
  20.   result := self;
  21. end;
  22.  
  23. function TIntRange.moveNext: boolean;
  24. begin
  25.   c += s;
  26.   result := c <= t;
  27. end;
  28.  

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: for loop with custom step width (esp. ≠ 1)
« Reply #9 on: December 15, 2016, 02:04:57 pm »
nay sayer !  >:D ;-)

Of course you can do exactly that. You just have to write it a bit differently  :P
Code: [Select]
var
  i: integer;
begin
  i := 0;
  while i < 10 do
  begin
    WriteLn('i: ', i);
    i := i + 2;
  end;
end;

Not exactly.
Pascal evaluates the number of iterations prior to the execution of the for loop.  Thus the loop should/could/would look like this:
Code: [Select]
var
  i: integer;
  c: integer;
begin
  i := 0;
  c:=10 div 2; // one time count evaluation
  while c>0 do // efficient check for the end of the loop
  begin
    WriteLn('i: ', i);
    i := i + 2;
    dec(c);
  end;
end;
It looks like a nonsense in this case, but when it comes to deal with real-like loops (i.e. traversing an indexe-list or a string, etc), it all starts to make sense.

Speaking of syntax. Why to introduce a new keyword? Instead an existing colon-construction could be used. Such as this.
Code: [Select]
for i:=1 to 10:2 do
  writeln
colon-construction is used in language-special routines, such as: Str, Write, Writeln.. etc

And, introducing "step" might come in conflict with "downto".

But what algorithms require "step"? ... or is just for educational tasks?
« Last Edit: December 15, 2016, 02:07:07 pm by skalogryz »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: for loop with custom step width (esp. ≠ 1)
« Reply #10 on: December 16, 2016, 04:45:02 pm »
@BeniBela
Using a enumerator, nice !

I hadn't thought of that.

@skalogryz:
Thanks for the correction as you are correct. Not much use for this simple case though but, i get your point.

Quote
Why to introduce a new keyword?
Well, it was the first thing that popped to mind. As minesadorada noticed correctly, i once started out with basic and some things seem to have survived my decaying brain-cells (that is, assuming i have any to begin with  ;D).

Your idea/suggestion is just as valid.

Quote
And, introducing "step" might come in conflict with "downto".
Yes you are correct.

As a matter of fact that is enclosed in the Pascal for construction to begin with.

The moment downto was introduced it causes ambiguity. Some basic language variants solved that by interpreting the values.

Assuming the step value is a signed integer your solution suffers from that as well.

Probably reason why something like it was not implemented/supported already ?

Quote
But what algorithms require "step"? ... or is just for educational tasks?
It is just syntax sugar as things can be solved using other another approach.

However, support for something like this can make the life of a programmer a bit easier (or make the programmer more lazy, depending on how you look at it).

There is a reason why OP asked his/her question. Most likely because such construct was encountered in another language before looking at Pascal.

Although i dislike most suggestions made to improve the language because it really is syntax sugar alone or an attempt to whore the language itself, it is imo a bit strange to keep having to say no to someone asking such a question. Apparently there is an expectation that such a construct is available.

Even though the enumerator solution is able to solve that partly, it isn't a basic solution that a beginner would look at (i overlooked it as well)

But, i have a feeling that this discussion was made long before it was brought up here. I simply haven't looked at any of them yet. Would be nice to have some idea on the reason(s) why it was rejected (if any).

Kays

  • Hero Member
  • *****
  • Posts: 575
  • Whasup!?
    • KaiBurghardt.de
Re: for loop with custom step width (esp. ≠ 1)
« Reply #11 on: December 19, 2016, 12:52:33 am »
[…]How do I make a for-loop iterate with a custom step width? So everything regarding iteration is in the top line.[…]
OK, for the record: It is not possible. I didn't found it, because it's not there.

[…]
Code: Pascal  [Select][+][-]
  1. []
  2. for i := 0 to 5 do
  3. begin
  4.   idx := i * 2;[]
Yeah a solution w/ one less line I haven't thought of. So I correct my lower limit: You have to spend two or three lines of code, if the loop needs a custom step width. On the other hand, (IMO) it loses some readability.

[… construct an array of indices …]
[… implement IEnumerate …]
Gee, molly and BeniBela, you both overreached the goal. No offense, but I'd be better off with the three line surrogate statement.

[…]But what algorithms require "step"? ... or is just for educational tasks?
Yeah, this question raised during education. So?

[…]Although i dislike most suggestions made to improve the language because it really is syntax sugar alone or an attempt to whore the language itself, it is imo a bit strange to keep having to say no to someone asking such a question. Apparently there is an expectation that such a construct is available.
Exactly.


While we're at formulating Xmas wishes: I wouldn't be satisfied with a linear step width alone. E.g.:
Code: C  [Select][+][-]
  1. for (i ≔ 1; i < 1234; i ≔ 2 * i) {}
« Last Edit: December 19, 2016, 01:06:54 am by Kays »
Yours Sincerely
Kai Burghardt

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: for loop with custom step width (esp. ≠ 1)
« Reply #12 on: December 19, 2016, 01:07:18 am »
OK, for the record: It is not possible. I didn't found it, because it's not there.
That is correct.

Pascal does not have such construct as you showed in your initial post, or in your post i now reply to for that matter.

Quote
Gee, molly and BeniBela, you both overreached the goal.
It is a bit over the top, yes. In the discussion the opinion was raised that it could not be done using a for loop. Two examples (how even unlikely to be practical for you as  expressed) show it is possible, just not in the way you expected  :)

Quote
While we're at formulating Xmas wishes: I wouldn't be satisfied with a linear step width alone. E.g.:
Code: C  [Select][+][-]
  1. for (i ≔ 1; i < 1234; i ≔ 2 * i) {}
Yes, but that is actually a while loop (or repeat until in case that has your preference).

In case of applying the while solution the lower and upper bounds (usually) also makes more sense (in comparison to Handoko's solution). Although it of course depends on the practical situation (sometimes Handoko's solution makes the code better readable/understandable).

Code: [Select]
i := LowerBound
while i < Upperbound  do
begin
  i := i * 2;
end;

It is far from your x-mas wish though...

edit: additional reply.
« Last Edit: December 19, 2016, 01:39:13 am by molly »

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: for loop with custom step width (esp. ≠ 1)
« Reply #13 on: December 19, 2016, 07:11:17 am »
Code: Pascal  [Select][+][-]
  1. function step(var  i:integer;const astep:integer):integer;inline;
  2. begin
  3.   Result:=i;  // use then increment step
  4.   inc(i, AStep);
  5. end;
  6.  
  7. var
  8.   i:integer = -2;
  9. begin
  10.   while step(i,2) < 100 do
  11.     writeln(i);  
  12.  
  13. //or
  14. i :=0;
  15.   repeat
  16.     writeln(i);
  17.   until step(i,2) = 100;
  18.  
  19. // or even
  20.   repeat
  21.     writeln(step(i,2));
  22.   until i = 100;
  23. end.
  24.  
« Last Edit: December 19, 2016, 07:38:56 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Deepaak

  • Sr. Member
  • ****
  • Posts: 454
Re: for loop with custom step width (esp. ≠ 1)
« Reply #14 on: December 19, 2016, 07:47:44 am »
The counter in for loop cannot be altered by user unlike C/C++ for loop. This discussion has no ending for something that is not designed in the compiler/language. It can be done using While/Repeat loop. So go for while/repeat loop. Don't make program unnecessary complex.

Agree with @molly
Holiday season is online now. :-)

 

TinyPortal © 2005-2018