## среда, 20 января 2016 г.

### #869. :, PROCEDURE, FUNCTION. Parameters at the left and at the right. Part 2

Original in Russian: http://programmingmindstream.blogspot.ru/2015/12/1167-procedure-function-2.html

The previous series was here: http://18delphi.blogspot.ru/2016/01/868-procedure-function-parameters-at.html.

The key words :, ;, FUNCTION, PROCEDURE and “parameters at the left” were considered there.

Now, let’s discuss the “parameters at the right”.

Suppose, we have an example with “parameters at the left”:

```INTEGER FUNCTION Plus
INTEGER IN A
INTEGER IN B
A B + >>> Result // adds A to B and write to Result
; // Plus

1 2 Plus . // calls the function and prints the result
```

This is a case of “typical” RPN.

How can we use infix notation?

This is where parameters at the right will help.

We rewrite the example using parameters at the right:

```INTEGER FUNCTION Plus
INTEGER IN A // parameter at the left
^ IN B // parameter at the RIGHT is passed by REFERENCE rather than by VALUE.
//   It has to be dereferenced.
A // value of parameter A
B DO // dereferences the value B, i.e. calls the DO method on the word specified by B
+ >>> Result // adds A to B and write to Result
; // Plus

1 Plus 2 . // calls the function “INFIXELY” and prints the result
```

Note that parameters at the right are passed by reference.

We can also write:

1 Plus ( 2 Plus ( 3 Plus 4 ) ) .

The brackets is a must for now.

I’ll write how to do without them in a special article.

We can rewrite the example as follows:

```INTEGER FUNCTION Plus
INTEGER IN A // parameter at the left
^ IN B // parameter at the RIGHT is passed by REFERENCE rather than by VALUE.
//   It has to be dereferenced.
A // value of parameter A
B |^ // dereferences the value B, i.e. calls the |^ method on the word specified by B
+ >>> Result // adds A to B and writhes to Result
; // Plus

1 Plus 2 . // calls the function “INFIXELY” and prints the result
```

|^ is used instead of DO here.

They are equal actually.

A bit later, I will write about the differences.

The |^ method is defined in axiomatic as follows:

```: |^
^@ IN aRef

%SUMMARY 'Dereferences the parameter at the left' ;
aRef pop:Word:GetRef DO
; // |^
```

The details of  |^ implementation will also be described later.

Now, I will note that |^ uses DO, i.e. |^ is derived from DO.

Let’s go on.

Why are the parameters at the right passed by reference rather than by value?

There are many reasons, in particular "lazy evaluations".

Let’s look at the implementation of the Boolean operation AND and OR:

```BOOLEAN operator AND
BOOLEAN IN aFirst
^ IN aSecond
%SUMMARY 'Double-sided rather than reverse polish &&' ;
if aFirst then
(
if ( aSecond DO ) then
( true >>> Result )
else
( false >>> Result )
)
else
( false >>> Result )
; // AND

BOOLEAN operator OR
BOOLEAN IN aFirst
^ IN aSecond
// Double-sided rather than reverse polish  ||
if aFirst then
( Result := true )
else
if ( aSecond DO ) then
( Result := true )
else
( Result := false )
; // OR
```

As we can see, the parameter aSecond is calculated ONLY in case we need to calculate the whole expression.

It means that the result of expression is not clear on the parameter aFirst.

The word operator is equal to the words : and FUNCTION. It merely stresses the words are “operator-related”.

In particular, operators can set "order of operations" as in Prolog, for example, to get rid of the brackets in the example with Plus (see above).

Now, let us believe the operator is specified as follows:

```WordAlias operator :
WordAlias OPERATOR :
```

What do we get using lazy evaluation?

Without lazy evaluation:

```if ( ( anObject <> nil ) ( anObject .SomeMethod ) && ) then
```

we get Access Violation.

With lazy evaluation:

```if ( ( anObject <> nil ) AND ( anObject .SomeMethod ) ) then
```

we get no Access Violation.

Hope you see why.

The operation <> is, by the way, defined in base axiomatic using parameters at the right and at the left and the operation =.

In this way:

```BOOLEAN operator <>
IN aLeft
^ IN aRight
%SUMMARY 'Right-sided rather than reverse polish !=' ;
Result := ( aLeft = ( aRight DO ) ! )
; //<>
```

No comments. Note that the operation ! is a postfix denial.

Let’s go on.

The fact that the reference to the word rather than value is passed means that, if a variable is given as the word, we can write to it.

Let us implement the examples of increment and decrement methods as in axiomatic:

```VOID operator DEC
^ IN aWhatToDecrement
aWhatToDecrement DO // dereferences the variable aWhatToDecrement
1 - // decrement by 1
>>>^ aWhatToDecrement // writes the value as pointed by the aWhatToDecrement
; // DEC

VOID operator INC
^ IN aWhatToIncrement
aWhatToIncrement DO // dereferences the variable aWhatToDecrement
1 + // increment by 1
>>>^ aWhatToIncrement // writes the value as pointed by the aWhatToIncrement
; // INC
The call:
INTEGER VAR A // specifies the integer variable A
0 >>> A // initializes it using zero
A . // prints
INC A // increases A by 1
A . // prints
DEC A // decreases A by 1
A . // prints
```

Sure, if we write Inc 1 we get compilation error, if not particularly run-time error.

Suppose also that we need to describe the methods IncBy and DecBy.

Here they are:

```VOID operator DecBy
^ IN aWhatToDecrement
aWhatToDecrement DO // dereferences the variable aWhatToDecrement
- // substraction
>>>^ aWhatToDecrement //  writes the value as pointed by the aWhatToDecrement
; // DecBy

VOID operator IncBy
^ IN aWhatToIncrement
aWhatToIncrement DO // dereferences the variable aWhatToDecrement
>>>^ aWhatToIncrement //  writes the value as pointed by the aWhatToIncrement
; // IncBy
```

The call:

```INTEGER VAR A // specifies the integer variable A
0 >>> A // initializes it using zero
A . // - печатаем
IncBy A 2 // increases A by 2
A . // prints
DecBy A 2 // decreases A by 2
A . // prints
```

Let’s move on.

parameters at the right are also useful when dealing with lambda expressions.

Here is an example:

```: Iteration
^ IN aLambda
0 // initial value
1 aLambda DO
2 aLambda DO
3 aLambda DO
4 aLambda DO
5 aLambda DO
6 aLambda DO
7 aLambda DO
8 aLambda DO
9 aLambda DO
10 aLambda DO
; // Iteration

// The call:

Iteration ( IN A IN B A B + ) . // sums numbers from 0 to 10 and prints the result

// a shorter version:

Iteration + . // sums numbers from 0 to 10 and prints the result
```

The initial value can be factored out:

```: Iteration
^ IN aLambda
1 aLambda DO
2 aLambda DO
3 aLambda DO
4 aLambda DO
5 aLambda DO
6 aLambda DO
7 aLambda DO
8 aLambda DO
9 aLambda DO
10 aLambda DO
; // Iteration

// The call:

0 Iteration ( IN A IN B A B + ) . // sums numbers from 0 to 10 and prints the result

// a shorter version:

0 Iteration + . // sums numbers from 0 to 10 and prints the result

1 Iteration * . // multiplies numbers from 1 to 10 and prints the result

Arrays and iteration (in Russian) can be used for them:
^ IN aLambda
[ 1 2 3 4 5 6 7 8 9 10 ] .for> ( aLambda DO )
; // Iteration

// The call:

0 Iteration ( IN A IN B A B + ) . // sums numbers from 0 to 10 and prints the result

// a shorter version:

0 Iteration + . // sums numbers from 0 to 10 and prints the result

1 Iteration * . // multiplies numbers from 1 to 10 and prints the result
```

Let us sum up.

Parameters at the right and dereferencing were analyzed.

We also considered writing values to the variables the parameters at the right point to and how parameters at the right can be used for lambda expressions.

We scraped the surface of arrays and iteration through arrays.

In the next article, the parameters at the right passed by reference will be discussed along with the way of implementing the operations like += -= and so on.

Hope the article was of some use for you.