Fr0sT.Brutal 900 Posted April 15, 2020 (edited) I was bitten several times by errors in "for 0..N-1" loops when container was empty and iterator was unsigned. So for arrays "for Low..High", for other types "for in" and "for 0..Count-1" only when modification of an element is required Edited April 15, 2020 by Fr0sT.Brutal Share this post Link to post
Alexander Elagin 143 Posted April 15, 2020 Pred() and Succ() are simple iterators defined for enumerable simple data types. If only they could be overloaded for other data types (lists, collections, whatever... maybe even for yield support) their usefulness would be much higher. Share this post Link to post
David Heffernan 2345 Posted April 15, 2020 58 minutes ago, Alexander Elagin said: Pred() and Succ() are simple iterators defined for enumerable simple data types. If only they could be overloaded for other data types (lists, collections, whatever... maybe even for yield support) their usefulness would be much higher. That doesn't make a lot of sense. What is the successor of a collection. Perhaps you mean the successor of a member of a collection. But that only makes sense in the context of the collection. Share this post Link to post
Lars Fosdal 1792 Posted April 15, 2020 Scoured our complete source code and found only one occurence each of pred and succ. One was legit. for e := Low(TElementType) to Pred(High(TElementType)) do // i.e. do not include the last enum value in the loop. The other one was a bullshit one - and I was probably the author of both. function AfterFirst(const Match:char; const st:string):String; var index : Word; begin index := pos(Match,st); if index <> 0 then Result := Copy(st, index + 1, succ(Length(st) - index)) else Result := st; end; It's not even consequent. 1 1 Share this post Link to post
Anders Melander 1782 Posted April 15, 2020 17 minutes ago, Lars Fosdal said: The other one was a bullshit one It matches the indention style though Share this post Link to post
Lars Fosdal 1792 Posted April 15, 2020 I know... My indendation style is unconventional. It works for me, though. Share this post Link to post
Sherlock 663 Posted April 15, 2020 Finally my 2cts: Using methods like Predecessor (or Successor) to access an index based on the amount of items in a container would just hurt my brain to much. I also would always think that -1 or +1 is faster than calling some method, but then I'm the kind of developer that doe not inspect Delphis libs, I just use them and rely on documentation...a dying breed I know. But know this, all you Delphi RTL and VCL know-it-alls give Embarcadero an excuse to not maintain the online help. Please consider this comment tongue-in-cheek. 1 Share this post Link to post
Mike Torrettinni 198 Posted April 18, 2020 I did a quick look at some of the big component sources and you can actually find Pred() usage quite often. You can see some pas files use both options, Pred() and Count - 1. which I assume is due to different developers being involved. But this one is interesting: if Idx > pred(FItems.Count - 1) then and no comments. Since the same method already uses Pred(), I assume someone didn't like Count-1 and they changed it half way. 🙂 Share this post Link to post
David Heffernan 2345 Posted April 18, 2020 1 minute ago, Mike Torrettinni said: I did a quick look at some of the big component sources and you can actually find Pred() usage quite often. You can see some pas files use both options, Pred() and Count - 1. which I assume is due to different developers being involved. But this one is interesting: if Idx > pred(FItems.Count - 1) then and no comments. Since the same method already uses Pred(), I assume someone didn't like Count-1 and they changed it half way. 🙂 Total obfuscation here. Just because it exists doesn't mean you should use it. Share this post Link to post
Attila Kovacs 629 Posted April 18, 2020 @Mike Torrettinni Do you know Concat() ? Share this post Link to post
Mike Torrettinni 198 Posted April 18, 2020 20 minutes ago, Attila Kovacs said: @Mike Torrettinni Do you know Concat() ? If you are referring to: http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Concat then yes, I know it, but I prefer string1+string2, when needed concatenation. Why? Share this post Link to post
Attila Kovacs 629 Posted April 18, 2020 @Mike Torrettinni Nothing special, I thought you like exotic methods 😉 1 Share this post Link to post
Mike Torrettinni 198 Posted April 18, 2020 37 minutes ago, David Heffernan said: Total obfuscation here. Just because it exists doesn't mean you should use it. True, interesting it wasn't caught in code review before release. Share this post Link to post
Stefan Glienke 2002 Posted April 20, 2020 On 4/15/2020 at 10:30 AM, Lars Fosdal said: The other one was a bullshit one - and I was probably the author of both. function AfterFirst(const Match:char; const st:string):String; var index : Word; begin index := pos(Match,st); if index <> 0 then Result := Copy(st, index + 1, succ(Length(st) - index)) else Result := st; end; It's not even consequent. Fun fact: you can omit the 3rd argument of Copy if you just want to cut from the beginning. 2 1 Share this post Link to post
Lars Fosdal 1792 Posted April 20, 2020 Just now, Stefan Glienke said: Fun fact: you can omit the 3rd argument of Copy if you just want to cut from the beginning. Wow! That fact had eluded me! Share this post Link to post
Fr0sT.Brutal 900 Posted April 20, 2020 3 hours ago, Stefan Glienke said: Fun fact: you can omit the 3rd argument of Copy if you just want to cut from the beginning. I always used MaxInt to copy til the very end but wasn't aware I can omit Count 🙂 Share this post Link to post
Bill Meyer 337 Posted April 20, 2020 4 hours ago, Lars Fosdal said: Wow! That fact had eluded me! Yeah, it's in the fine print. 😉 I learned that one only in the last few years. 1 Share this post Link to post
flcop 0 Posted April 23, 2020 On 4/21/2020 at 12:49 AM, Bill Meyer said: Yeah, it's in the fine print. 😉 I learned that one only in the last few years. It seems to exist for a long time, may be from delphi2005, when I omission the 3rd argument, it should be a compile error, but it works 🙂 . Share this post Link to post
flcop 0 Posted April 24, 2020 I also found many funs in math, for example: function Mean(const Data: array of Single): Single; begin Result := SUM(Data) / (High(Data) - Low(Data) + 1); end; delphi usually uses "(High(Data) - Low(Data) + 1)" to get the length, and FPC uses “High(Data)+1”(fortunately,I had never seen "Succ(High(L)"),so why it just not use the concise and readable "Length(Data)"? Share this post Link to post
Mike Torrettinni 198 Posted May 25, 2020 OK, I must say that I started using Pred() more and more and I must say I like it, more and more. I re-read the comments above, but I have to say it really looks like High for arrays. I don't see it exotic anymore. This makes sense: for i := 0 to High(aArray) do for i := Low(aArray) to High(aArray) do for i := 0 to Pred(aList.Count) do Reading some comments again was interesting, so if using Pred() means I will never go beyond Delphi beginner level, so be it 🙂 Share this post Link to post