John Kouraklis 93 Posted December 3, 2018 Hi, I am looking at some older code and I see the author uses the following statement: for i:=0 to Pred(WhateverList.count) do instead of the usual one: for i:=0 to WhateverList.count - 1 do Does it make any real difference or it's just a personal preference? Thanks 1 Share this post Link to post
KodeZwerg 54 Posted December 3, 2018 (edited) In that code statement it does not matter if Pred() or attached -1 will be used. Both do same but Pred() can do more than give back decremented number. Those types are supported: Characters, Non-floating number types, Enumeration types and Pointers Example: Character := Pred( Char( 'X' ) ); = W /edit It might be possible that on mass operations a -1 is faster than using Pred(). Not tested by myself but possible. (not for above example, when used inside loops) Edited December 3, 2018 by KodeZwerg Share this post Link to post
John Kouraklis 93 Posted December 3, 2018 @KodeZwerg Thanks for the answer Yes I know about the use of Pred with other arguments. I was just wondering for that particular code snippet Share this post Link to post
Mike Torrettinni 198 Posted April 12, 2020 On 12/3/2018 at 5:03 PM, John Kouraklis said: for i:=0 to Pred(WhateverList.count) do I just saw noticed this (or recognized what it is) in sample code, for the first time! Pretty cool, can replace StringList.Count - 1, like High(Array) replaces Length(Array) - 1. @John Kouraklis let's see what else I can figure out a 1.5 years later than you 🙂 1 Share this post Link to post
David Heffernan 2345 Posted April 12, 2020 The difference is that Pred(...) is verbose and opaque. 1 Share this post Link to post
Anders Melander 1775 Posted April 12, 2020 6 hours ago, Mike Torrettinni said: Pretty cool, can replace StringList.Count - 1, Why is that "cool"? Share this post Link to post
Mike Torrettinni 198 Posted April 13, 2020 You don't use Pred(List.Count), you don't think is useful? Share this post Link to post
vfbb 285 Posted April 13, 2020 Pred and Succ best use is when used with enum. LBrushKind := Pred(LBrushKind); replace LBrushKind := TBrushKind(Ord(LBrushKind)-1); 3 Share this post Link to post
David Heffernan 2345 Posted April 13, 2020 5 hours ago, Mike Torrettinni said: You don't use Pred(List.Count), you don't think is useful? No. It's pointless verbiage. Use List.Count - 1 1 Share this post Link to post
Cristian Peța 103 Posted April 13, 2020 I would like to have List.High or List.HighIndex or List.LastIndex or whatever. Why to write every time -1 when you want the last index? 2 Share this post Link to post
Fr0sT.Brutal 899 Posted April 13, 2020 I only use Pred rarely with enums. With integers it's worse than N-1. 21 minutes ago, Cristian Peța said: I would like to have List.High or List.HighIndex or List.LastIndex or whatever. Why to write every time -1 when you want the last index? I guess having for-in construction there's not much need in last index 2 Share this post Link to post
Anders Melander 1775 Posted April 13, 2020 11 hours ago, Mike Torrettinni said: You don't use Pred(List.Count), you don't think is useful? I notice you didn't answer the question, but no; It makes the code harder to read as you have to think about what Pred does. With "Count-1" there's no doubt. Don't use a feature just because it's new or you've just discovered it. 2 Share this post Link to post
pyscripter 689 Posted April 13, 2020 5 hours ago, Cristian Peța said: I would like to have List.High or List.HighIndex or List.LastIndex or whatever. Why to write every time -1 when you want the last index? You can add an extension method if you wish to do that using a class helper. (Low as well). Share this post Link to post
Mike Torrettinni 198 Posted April 13, 2020 (edited) 1 hour ago, Anders Melander said: It makes the code harder to read as you have to think about what Pred does. With "Count-1" there's no doubt. Well, I have different experience. For a long time i didn't know about High(Array) and dealing with a lot of arrays, i had occasions forgetting -1 in Length(Array) -1, so High(Array) is, for me, excellent replacement. Edited April 13, 2020 by Mike Torrettinni softer tone of words. Share this post Link to post
David Heffernan 2345 Posted April 13, 2020 High is fine for an array. Pred is a stupid way to write Count - 1. I mean, you aren't proposing writing Pred(Length(arr)) are you. 1 Share this post Link to post
Mike Torrettinni 198 Posted April 13, 2020 I use High with Arrays, Pred I saw in example with List.Count example. I see High used with Arrays very often, but not every body is using it, of course. Years ago I had a custom checker that would check for Length(Array) that is missing -1... lot's of fun, before I started using High 🙂 Share this post Link to post
Mike Torrettinni 198 Posted April 13, 2020 15 hours ago, Fr0sT.Brutal said: I guess having for-in construction there's not much need in last index I only rarely use for-in, perhaps I should try using it more often. I only use it for enums, I never thought you can use it for TList, even though it makes sense. Good thread @John Kouraklis , good ideas coming out of this! 🙂 1 1 Share this post Link to post
Fr0sT.Brutal 899 Posted April 14, 2020 8 hours ago, Mike Torrettinni said: I only rarely use for-in, perhaps I should try using it more often. I only use it for enums, I never thought you can use it for TList, even though it makes sense The coolest thing about for-in is that you can implement it for any custom class or record by implementing an iterator. So, f.ex., you can have `for jsonval in JSONDoc.Values['somearray']`. For-in works for strings as well iterating by chars though I personally haven't used it in such way. And it's a bit slower so for time-critical routines usual `for` still remains actual (though for very super time-critical things pointer increasing could beat `for` anyway) 2 Share this post Link to post
Anders Melander 1775 Posted April 14, 2020 27 minutes ago, Fr0sT.Brutal said: (though for very super time-critical things pointer increasing could beat `for` anyway) It depends. Sometimes indexed access is faster. Share this post Link to post
John Kouraklis 93 Posted April 14, 2020 I also use for..in all the time. Don't forget though that in for loops you can not modify the iteration variable. So, if you have a TStringList, this code does not compile: for item in list do item:=item + '123'; In such cases, iterating through the items via index is the only option for num := 0 to list.Count - 1 do list[num]:=list[num] + '123'; Share this post Link to post
Mike Torrettinni 198 Posted April 14, 2020 1 minute ago, John Kouraklis said: I also use for..in all the time. Don't forget though that in for loops you can not modify the iteration variable. So, if you have a TStringList, this code does not compile: for item in list do item:=item + '123'; In such cases, iterating through the items via index is the only option for num := 0 to list.Count - 1 do list[num]:=list[num] + '123'; You mean this, right? : for num := 0 to Pred(list.Count) do list[num]:=list[num] + '123'; 🙂 1 Share this post Link to post
John Kouraklis 93 Posted April 14, 2020 @Mike Torrettinni Hahaha...yes...my bad 😋 1 Share this post Link to post
Fr0sT.Brutal 899 Posted April 14, 2020 (edited) 8 hours ago, Anders Melander said: It depends That's why I said "could". 😉 Edited April 14, 2020 by Fr0sT.Brutal Share this post Link to post
David Heffernan 2345 Posted April 14, 2020 9 hours ago, Anders Melander said: It depends. Sometimes indexed access is faster. For an array indexed access is usually fastest. Delphi RTL enumerators are often sub optimal. I mean, heap allocation to iterate a collection ffs. Share this post Link to post
David Schwartz 426 Posted April 14, 2020 off-by-one errors are the bane of most programmers' existence. I eventually learned to look for "... 0 to ... -1" or "... 1 to ... <x>" where "x" does not contain a '-1' The use of pred() in place of '-1' is inconsistent at best, and rarely used, so it much harder to detect quickly when it's not used appropriately. Wirth threw it into the language as a pedagogical tool. That was nice, but it's impractical. The 'for ... in' approach is far less likely to lead to such errors. The use of 'Low(x) to High(x)' is even less error-prone than '0 to ...-1' IMO. Share this post Link to post