# Difference between Pred and -1

## Recommended Posts

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

for i:=0 to WhateverList.count - 1 do

Does it make any real difference or it's just a personal preference?

Thanks

• 1

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 by KodeZwerg

Yes I know about the use of Pred with other arguments. I was just wondering for that particular code snippet

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

The difference is that Pred(...) is verbose and opaque.

• 1

6 hours ago, Mike Torrettinni said:

Pretty cool, can replace StringList.Count - 1,

Why is that "cool"?

You don't use Pred(List.Count), you don't think is useful?

Pred and Succ best use is when used with enum.

LBrushKind := Pred(LBrushKind);

replace

LBrushKind := TBrushKind(Ord(LBrushKind)-1);

• 3

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

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

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

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

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).

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 by Mike Torrettinni
softer tone of words.

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

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 🙂

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

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

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.

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';```

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

• 1

8 hours ago, Anders Melander said:

It depends

That's why I said "could".  😉

Edited by Fr0sT.Brutal

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.

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.