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

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: for loop with custom step width (esp. ≠ 1)
« Reply #90 on: January 15, 2022, 08:20:19 pm »
Everybody here knows that "step" or "by" are most unlikely to be implemented by the core developers and that they have their own reasons for that decision, but "it's C-like" shouldn't be one of them and "Wirth didn't like it" /can't/ be one of them since it is manifestly untrue.

Repeating myself here:

For those interested: there is an old patch (even older than this discussion ;) ) that adds support for a by-clause to the for-loop. The patch won't apply on main, but it should be possible to rebase this...

I'm sorry, I'd forgotten that. I'll try to take a look at some point, but I'm currently up to my eyes in logic analyzer stuff.

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

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: for loop with custom step width (esp. ≠ 1)
« Reply #91 on: January 16, 2022, 04:29:39 am »
Everybody here knows that "step" or "by" are most unlikely to be implemented by the core developers and that they have their own reasons for that decision, but "it's C-like" shouldn't be one of them and "Wirth didn't like it" /can't/ be one of them since it is manifestly untrue.

Repeating myself here:

For those interested: there is an old patch (even older than this discussion ;) ) that adds support for a by-clause to the for-loop. The patch won't apply on main, but it should be possible to rebase this...

I once implemented "reverse enumerator" syntax locally in FPC (where you could do like "for i in reverse something" and it would just generate the loop backwards) in like a few hours, and it worked perfectly IIRC, so I feel like this wouldn't be very difficult. Might take a look at it. Based on my experience implementing multi-line strings, the compiler is pretty well-structured in that adding new stuff is generally able to just make use of existing "building block" code, so it typically isn't massively difficult unless the feature itself is really complicated.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: for loop with custom step width (esp. ≠ 1)
« Reply #92 on: January 16, 2022, 05:38:10 am »
Side note: My hack published in UNDU becomes 25 years old this year, 8-) and I still feel that something like step should be supported, Note the hack still works.
(And is still unsafe.... ;D )
Pity UNDU is not on the wayback machine. It was great while it lasted.
What is or was that UNDU you are talking about? URL?
UNDU was an acronym for Unofficial Newsletter of Delphi Users. This was an excellent digital newsletter, independent of Borland, produced by an American named Robert Vivrette in Borland's heyday in the 1980s/1990s, available originally on Compuserve, and as widely read as Borland's own forums at the time. I'm not sure when it ceased to be produced, but it was a very long time ago!

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: for loop with custom step width (esp. ≠ 1)
« Reply #93 on: January 16, 2022, 06:36:10 am »
UNDU rather suddenly disappeared, indeed. A pity. I write several articles for it, like the talking Parrot (ms speech API), re-using compiled tlb's, and several tips, as per the step hack. I must still have a lot of code from UNDU on a 1GB "Bigfoot" -period correct hardware -, but can't currently access it for lack of an IDE interface.
« Last Edit: January 16, 2022, 06:38:21 am by Thaddy »
Specialize a type, not a var.

dseligo

  • Hero Member
  • *****
  • Posts: 1194
Re: for loop with custom step width (esp. ≠ 1)
« Reply #94 on: January 16, 2022, 06:43:00 am »
I once implemented "reverse enumerator" syntax locally in FPC (where you could do like "for i in reverse something" and it would just generate the loop backwards)

Didn't you hear of downto? https://www.freepascal.org/docs-html/ref/refsu58.html
Or I misunderstood you.  :)

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: for loop with custom step width (esp. ≠ 1)
« Reply #95 on: January 16, 2022, 06:48:58 am »
I can't imagine that. Downto is rather essental for e.g. managing lists and arrays of managed types correctly (freeing) and has always been in Pascal.
« Last Edit: January 16, 2022, 06:51:10 am by Thaddy »
Specialize a type, not a var.

dseligo

  • Hero Member
  • *****
  • Posts: 1194
Re: for loop with custom step width (esp. ≠ 1)
« Reply #96 on: January 16, 2022, 06:55:52 am »
I think so too. He probably meant something else.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: for loop with custom step width (esp. ≠ 1)
« Reply #97 on: January 16, 2022, 07:03:16 am »
I once implemented "reverse enumerator" syntax locally in FPC (where you could do like "for i in reverse something" and it would just generate the loop backwards)

Didn't you hear of downto? https://www.freepascal.org/docs-html/ref/refsu58.html
Or I misunderstood you.  :)

Code: Pascal  [Select][+][-]
  1. var
  2.   a:array of string;
  3.   s:String;
  4. begin
  5.   a:=['one','two','three'];
  6.   for s in a do WriteLn(s);
  7.  
  8.   for s in reverse a do WriteLn(s);//<------- This

dseligo

  • Hero Member
  • *****
  • Posts: 1194
Re: for loop with custom step width (esp. ≠ 1)
« Reply #98 on: January 16, 2022, 07:10:15 am »
Ah, ok, thanks  :-[

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: for loop with custom step width (esp. ≠ 1)
« Reply #99 on: January 16, 2022, 07:50:18 am »
Code: Pascal  [Select][+][-]
  1. var
  2.   a:array of string;
  3.   s:String;
  4. begin
  5.   a:=['one','two','three'];
  6.   for s in a do WriteLn(s);
  7.  
  8.   for s in reverse a do WriteLn(s);//<------- This

That's exactly what it was yeah. IIRC it was limited only in terms of the borrowed-from-Delphi-who-borrowed-it-from-C# "GetEnumerator" way of doing things specifically for structured types, but that seemed solvable by just adding "GetReverseEnumerator" as an option as well.

Anyways, I digress. I'll be quiet before we stray too far off topic, haha.

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: for loop with custom step width (esp. ≠ 1)
« Reply #100 on: January 16, 2022, 02:35:20 pm »
Generic reverse:
Code: Delphi  [Select][+][-]
  1. program arrayhelp;
  2. {$mode delphi}
  3. type
  4.   TIntArray = TArray<integer>;
  5.   TStringArray = TArray<string>;
  6.   procedure swap<T>(var left,right:T);inline;
  7.   var
  8.     temp:T;
  9.   begin
  10.     temp:=left;
  11.     left:=right;
  12.     right:=temp;
  13.   end;
  14.  
  15.   procedure Reverse<T>(var Value:array of T);
  16.   var
  17.     i: Integer = 0;
  18.   begin
  19.     if Length(Value) > 0 then
  20.       for i := Low(Value) to High(Value) div 2 do
  21.         Swap<T>(Value[i],Value[High(Value) - i]);
  22.   end;
  23.  
  24. var
  25.   i:integer;
  26.   s:string;
  27.   si:TintArray = [1,2,3,4,5,6,7,8,9,10];
  28.   ss:TStringArray = ['there', 'is', 'more', 'Horatio'];
  29. begin
  30.   reverse<integer>(si);
  31.   for i in si do write(i:2);
  32.   writeln;
  33.   reverse<string>(ss);
  34.   for s in ss do writeln(s);
  35. end.
Note I couldn't get it to work in {$mode objfpc} but that is probably an oversight and laziness from me.
Note that altough the mode is Delphi it won't work in Delphi.
« Last Edit: January 16, 2022, 02:59:00 pm by Thaddy »
Specialize a type, not a var.

simone

  • Hero Member
  • *****
  • Posts: 573
Re: for loop with custom step width (esp. ≠ 1)
« Reply #101 on: January 17, 2022, 12:22:04 am »
Thanks Thaddy for the nice piece of code.

This is my version for {$mode ObjFpc}:

Code: Pascal  [Select][+][-]
  1. program arrayhelp;
  2. {$mode objfpc}
  3. type
  4.   TIntArray = specialize TArray<integer>;
  5.   TStringArray = specialize TArray<string>;
  6.   generic procedure swap<T>(var left,right:T);inline;
  7.   var
  8.     temp:T;
  9.   begin
  10.     temp:=left;
  11.     left:=right;
  12.     right:=temp;
  13.   end;
  14.  
  15.   generic procedure Reverse<T>(var Value:array of T);
  16.   var
  17.     i: Integer = 0;
  18.   begin
  19.     if Length(Value) > 0 then
  20.       for i := Low(Value) to High(Value) div 2 do
  21.         specialize Swap<T>(Value[i],Value[High(Value) - i]);
  22.   end;
  23.  
  24. var
  25.   i:integer;
  26.   s:string;
  27.   si:TintArray = (1,2,3,4,5,6,7,8,9,10);
  28.   ss:TStringArray = ('there', 'is', 'more', 'Horatio');
  29. begin
  30.   specialize reverse<integer>(si);
  31.   for i in si do write(i:2);
  32.   writeln;
  33.   specialize reverse<string>(ss);
  34.   for s in ss do writeln(s);
  35. end.

In addition to usage of generic/specialize keywords, note the round brackets in place of the square brackets to initialize dynamic arrays.
Microsoft Windows 10 64 bit - Lazarus 3.0 FPC 3.2.2 x86_64-win64-win32/win64

avk

  • Hero Member
  • *****
  • Posts: 752
Re: for loop with custom step width (esp. ≠ 1)
« Reply #102 on: January 17, 2022, 06:58:59 am »
I couldn't resist and added a reverse enumerator to the array helpers.

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: for loop with custom step width (esp. ≠ 1)
« Reply #103 on: March 08, 2022, 12:30:15 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

I very much agree that things should be kept simple. But almost any language I know of has at least two or even three different loop statements adding more keywords and rules to a language (= not simple). I must admit that when designing a new language it is very tempting to copy existing constructs rather than to break away from tradition and do one's own thinking. Of course, this does not apply to FreePascal or any other language set about to maintain compatibility.

In the last couple of months I've been struggling with loop constructs and the idea was quickly born to have just one loop flexible enough to cover everything. This morning I might have succeeded in doing just that. Amazingly, it cuts out quite some compiler code and complexity (especially when supporting jumps) while providing a very flexible loop construct. For those interested, here are a few examples: https://sharpbasic.com/forum/viewtopic.php?t=40

I agree with 440bx that a for-loop -- IF implemented (with or without a step or by clause) -- should maintain its traditional form. My attempts to redesign it never gave a truly satisfying result, until the introduction of well-designed shortcut operators, which can be applied consistently in a language.
« Last Edit: March 09, 2022, 08:42:26 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 #104 on: March 09, 2022, 08:45:45 pm »
A few days ago, when I looked at the poll, true and false were pretty even. Now false has gained quite a lead. I guess that means no stepping in the foreseeable future?
keep it simple

 

TinyPortal © 2005-2018