### - or how could I forget some set operators.

Recently a colleague of mine asked me to review some old code, and a line similar to the one below pop into my view as strange:

if (doorStates * [dsClosed, dsUnlocked] <> []) then

It had been so many years since I had used that specific syntax, that I completely forgot about some of the set operators in Pascal and Delphi - so I thought I would write up a small post on Sets in Pascal/Delphi.

In regards to the silly doorStates example above - here is a little riddle:

**When is a door not a door?**The theory on the subject is just basic algebra and useful in relational algebra also - so help me Codd.

A set variable in Pascal can hold up till 256 elements, which ordinal values can be 0..255. The type of the elements must all be the same, and be a scalar type - but not floating point numbers.

And compared to other variables can a set have none, 1 or multiple values, and values in a set is unique - in an array you can have duplicates.

Set types are defined with the SET OF keywords - like:

Type

TDigits = set of '0'..'9';

TGarmentColors = set of (Yellow, Green, Blue, Red, Black);

TDoorStates = set of (dsOpen, dsClosed, dsLock, dsUnLock, dsAjar);

TBelow50 = set of 0..49;

TLetters = set of 'A'-'Z';

So let us go through the various set operators one by one with some examples, and also add a couple that are not directly represented by a single operator.

Example set variables defined are - using just sets of integers to keep it simple:

A := [5, 3, 7, 9, 16];

B := [2, 6, 9, 1, 4];

C := [1..7, 9, 16];

#### Union

A ∪ B is in Pascal with as A + B so:

A + B = [1, 2, 3, 4, 5, 6, 7, 9, 16]

#### Difference

A ∖ B or A - B is in Pascal written as A - B so:

A - B = [3, 5, 7, 16]

#### Intersection

A ∩ B is in Pascal written as A * B, so:

A * B = [9]

#### Subset

A ⊂ C is in Pascal written as A <= C, so:

A <= C = True;

#### Superset

C ⊃ A is in Pascal written as C >= A, so:

C >= A = True;

#### Equality

C = A ∪ B is in Pascal written as C = A + B, so:

(C = A + B) = True;

#### Inequality (disjoint)

A ≠ B is in Pascal written as A <> B, so:

(A <> B) = True;

#### Membership

{3} ⊂ A could in Pascal be written as 3 in A, so:

3 in A = True;

#### Symmetric difference

A Δ B or A ⊕ B which is the same as (A ∪ B) - (A ∩ B), can in Pascal be written as (A + B) - (A * B), so:

(A + B) - (A * B) = [1, 2, 3, 4, 5, 6, 7, 16]

or

(A - B) + (B - A) = [1, 2, 3, 4, 5, 6, 7, 16]

#### Include

B ∪ {3} could in Pascal be written as Include(B, 3), so:

Include(B, 3);

B = [1, 2, 3, 4, 6, 9]

#### Exclude

C ∖ {5} or C - {5} could in Pascal be written as Exclude(C, 5), so:

Exclude(C, 5);

C = [1,2,3,4,6,7,9,16]

I did a small application to illustrate the operators, and it can be used as evaluator - on a 0..255 integer set. I will put it on GitHub, if it has any interest.

So I do like Pascal sets, I think the only drawback is that a set is restricted by 256 element and the ordinal value must also be within 0-255.

Coming back to the riddle:

**When It's A Jar.**Which is also the title of one of Tom Holts many funny books - which I highly recommend.

**Amazon link.**There are also many great Delphi books being published recently - which will fit great as a Christmas gift for your employees, if you are an employer or team lead.

/Enjoy

Nice overview!

ReplyDeleteOne small detail - there is absolutely no need to compare boolean result to True. One does not have to write "(C = A + B) = True" when "(C = A + B)" does the work.

Thanks Primož! I am aware that I would not need the = True, but it was just to illustrate what it evaluates to. I should have written a proper if statement, the line you point out could be mistaken as code.

Delete