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 51106 times)

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #60 on: December 12, 2021, 10:34:25 am »
This could also be combined into a block. Not sure if this would cover common cases though.
Code: [Select]
  count i
    down 10 to 1 do
      print i;
    up 0 to 9 do
      print i;
  end;
keep it simple

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: for loop with custom step width (esp. ≠ 1)
« Reply #61 on: December 12, 2021, 10:47:17 am »
the options you show look reasonable.  I think that you should first decide how English or formula like you want the construct to be.

I like reading a statement as if it were plain English and have the statement make sense that way.  if that makes it a little more verbose than it could be, I think that is worth the price as long as the result is natural and intuitive.

Using that "metric", I think the Pascal "for" statement is actually quite good.  Adding a "by" option would polish it nicely.



(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

jcmontherock

  • Full Member
  • ***
  • Posts: 234
Re: for loop with custom step width (esp. ≠ 1)
« Reply #62 on: December 12, 2021, 11:02:28 am »
The best seems to me that we can change the value of index in the loop:
Code: Pascal  [Select][+][-]
  1. for i := 0 to 10 do begin
  2. ...
  3. i := i + 1;    // not accepted now by the compiler
  4. ...
  5. end;
  6.  
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: for loop with custom step width (esp. ≠ 1)
« Reply #63 on: December 12, 2021, 11:17:27 am »
Yes, thats a simple change if we must have this feature. But its the sort of thing easily overlooked as you read someone else's code. "Ah, a loop, yep, indexed, thats normal...."

My view is we really don't need this. I always consider a for loop as just a special case of a while or repeat loop with some default behavior built in.  If we need to change that default behavior, we should just drop back to using a while or repeat loop and construct it our self. Its not hard.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: for loop with custom step width (esp. ≠ 1)
« Reply #64 on: December 12, 2021, 11:19:16 am »
The best seems to me that we can change the value of index in the loop:
Code: Pascal  [Select][+][-]
  1. for i := 0 to 10 do begin
  2. ...
  3. i := i + 1;    // not accepted now by the compiler
  4. ...
  5. end;
  6.  
That would change the very essence of a "for" loop.  A "for" loop is designed to be a consecutive count. Allowing assignment to the index variable in it breaks that property.

One thing that would sometimes be nice is for the index variable to be in a predictable state when the loop exits.  That is sometimes useful but, it has performance consequences and, if index manipulation is needed using a "while" loop indicates the "while" may depend on some variable thus accomplishing what you asked for while "documenting" it is a possibility (unlike in a "for".)

Essentially, what @dbannon stated.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #65 on: December 12, 2021, 12:00:20 pm »
One thing that would sometimes be nice is for the index variable to be in a predictable state when the loop exits.

There's no reason not to have that state. In BASIC the iterator was always the maximum value + 1 and I often used it following the loop. Of course, if the iterator's scope is limited to the loop it's different.
keep it simple

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: for loop with custom step width (esp. ≠ 1)
« Reply #66 on: December 12, 2021, 12:21:01 pm »
One thing that would sometimes be nice is for the index variable to be in a predictable state when the loop exits.

There's no reason not to have that state. In BASIC the iterator was always the maximum value + 1 and I often used it following the loop. Of course, if the iterator's scope is limited to the loop it's different.

It's /defined/ in Pascal as being unpredictable. That's reason enough: if you want to argue take it up with the core compiler developers but I think you'll find they've got even less respect than I for an opinion based on BASIC.

Having said that, I don't like it. As I've already said, I think it should be resolved by restricting both the scope and visibility of the index variable which is what's done in C etc. But that was vetoed years ago.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #67 on: December 12, 2021, 12:22:44 pm »
Using that "metric", I think the Pascal "for" statement is actually quite good.  Adding a "by" option would polish it nicely.

Designing a new language allows for other syntax not necessarily leaning on tradition for tradition's sake. I admit I like the keyword count because it is more telling. Adjusting the example I gave earlier, there is consistency in both the count and when statement (and consistency is what we want):
Code: Text  [Select][+][-]
  1.   l = len(s) - 1;
  2.   p = sadd(s);
  3.   count i up 0 to l do
  4.     a = bya(p + i);
  5.     when a is 48 to 55 do
  6.       r = r + (a - 48);
  7.       if i < l do
  8.         r = r * 8;
  9.       end;
  10.     end;
  11.   end;

Looking at wikipedia there are many different examples, one of the worst IMO Algol 68.

I agree with dbannon that a count-loop should provide a consecutive iteration. Any variation can be achieved through variable loops. It keeps the syntax clean and simple. So no step or by option I'd say (I already voted against it).
« Last Edit: December 12, 2021, 12:48:33 pm by munair »
keep it simple

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #68 on: December 12, 2021, 12:32:14 pm »
It's /defined/ in Pascal as being unpredictable. That's reason enough: if you want to argue take it up with the core compiler developers but I think you'll find they've got even less respect than I for an opinion based on BASIC.

I'm very well aware of Pascal documentation and my remark wasn't meant to argue against Pascal, nor to show respect/disrespect for any language. Please keep the conversation civilized.
keep it simple

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: for loop with custom step width (esp. ≠ 1)
« Reply #69 on: December 12, 2021, 01:28:23 pm »
Code: Text  [Select][+][-]
  1.   count i up 0 to l do
  2.    ...
  3.   end;
the thing I don't care for in that statement is that it doesn't read natural.  IMO, it would read better as:
Code: Text  [Select][+][-]
  1.   count i from 0 to l do  { or downto)
  2.    ...
  3.   end;
or "=" instead of "from" and use "to"/"downto" to indicate the count direction.

My liking Pascal's "for" isn't because of tradition.  I like it because it's succinct, intuitive and very clear.  IMO, a really good balance between the extremes of too verbose and too cryptic/symbolic.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #70 on: December 12, 2021, 01:55:46 pm »
My reason for avoiding downto (OCaml also adopted it) is that to can naturally apply to both upward and downward iteration. It keeps the syntax clean, consistent and less verbose:
Code: Text  [Select][+][-]
  1. count i from 10 downto 1 do
  2. //vs
  3. count i down 10 to 1 do
  4.  

It's a mix of clean, concise and good readable code mixed with a drive not to just copy constructs from other languages. Looking at the wikipedia article I linked to earlier, it's amazing (or not) how many languages simply adopted the C-style for-loop. I wish to avoid being classed in such a class at all cost.
keep it simple

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #71 on: December 12, 2021, 03:26:48 pm »
I'm not sure why FPC has the iterator in an undetermined state after loop exit, or do they mean that it depends on the code like whether or not the loop was shortcut with a break?

The iterator being max + 1 or min - 1 after loop exit comes naturally with the iteration. After all, the iterator is tested against the maximum/minimum value and the loop ends if the iterator is greater or less respectively.

The following SharpBASIC code demonstrates this:
Code: Text  [Select][+][-]
  1. main do
  2.  
  3.   count i up 1 to 10 do
  4.     print i;
  5.   end;
  6.  
  7.   print;
  8.   print i;
  9.  
  10. end;

which translates to (non-optimized) ASM as:
Code: ASM  [Select][+][-]
  1. _start:
  2. ; load immediate constant '1'
  3.         movsx   eax, byte [_C4]
  4. ; save i
  5.         mov     [_I55], al
  6. ; dec i
  7.         dec     byte [_I55]
  8. ; load immediate constant '10'
  9.         movsx   eax, byte [_C5]
  10.         push    eax
  11. ._L0:
  12. ; inc i
  13.         inc     byte [_I55]
  14.         pop     eax
  15. ; cmp i
  16.         cmp     [_I55], al
  17.         jg      ._L1
  18.         push    eax
  19. ; print:
  20. ; load i
  21.         movsx   eax, byte [_I55]
  22.         call    _sb_print_int
  23.         jmp     ._L0
  24. ._L1:
  25. ; print:
  26.         call    _sb_printlf
  27.  
  28. ; print:
  29. ; load i
  30.         movsx   eax, byte [_I55]
  31.         call    _sb_print_int
  32.  
  33. _end:
  34.         mov     ebx, 0
  35.         mov     eax, 1
  36.         int     80h

Note line 17: jg      ._L1 It means that the iterator becomes one higher than the specified maximum. Unless the iterator is messed with at the end (scope issue?) it should be max + 1. No effort needed to make that happen.
keep it simple

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: for loop with custom step width (esp. ≠ 1)
« Reply #72 on: December 12, 2021, 03:52:16 pm »
Please keep the conversation civilized.

Please stop jumping into every thread with your BASIC fixation, /particularly/ in the beginners section.

My apologies to the mods.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #73 on: December 12, 2021, 04:09:16 pm »
Please stop jumping into every thread with your BASIC fixation, /particularly/ in the beginners section.

If you don't like it then just ignore these language conversations which, as we've stated before, can be quite insightful and educational and a source for ideas. And I'm certainly not jumping into every thread. Why the exaggeration?

BTW, I have no BASIC fixation. The language I'm developing has actually more in common with Pascal than traditional BASIC. So again, don't be fooled by the name and simply ignore the posts that don't interest you. Thank you.
« Last Edit: December 12, 2021, 04:21:43 pm by munair »
keep it simple

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: for loop with custom step width (esp. ≠ 1)
« Reply #74 on: December 12, 2021, 04:25:43 pm »
Hi!

There are two kinds of loop with any step you like.

They are while and repeat.

So we don't have to mess Pascal with any C syntax.

Keep it simple!

Winni

 

TinyPortal © 2005-2018