Chapter 31: Evaluating Expressions

31.1 Introduction

In this chapter we look at the process of evaluating a J expression. Evaluating a complete expression proceeds by a sequence of basic steps, such as obtaining the value assigned to a name, or applying a function to its argument(s). For example, given

   x =: 3

then the expression

   4+5*x
19

is (in outline) evaluated by the steps:

  1. obtain the value assigned to x giving 3
  2. compute 5 * 3 giving 15
  3. compute 4 + 15 giving 19

The sequence in which the steps take place is governed by the grammatical (or "parsing") rules of the J language. The parsing rules have various consequences, or effects, which can be stated informally, for example:

  • verbs have long right scope (this is the "rightmost-first" rule we saw above)
  • verbs have short left scope
  • adverbs and conjunctions get applied before verbs
  • adverbs and conjunctions have long left scope and short right scope
  • names denoting nouns are evaluated as soon as encountered
  • names denoting functions are not evaluated until the function is applied
  • names with no assigned values are assumed to denote verbs
  • long trains of verbs are resolved into trains of length 2 or 3
and we will look at how the parsing rules give rise to these effects. To illustrate the process, we can use a function which models, or simulates, the evaluation process step by step, showing it at work in slow motion.

This function, an adverb called EVM,is based on the description of the parsing algorithm given in the J Dictionary, section IIE. It is defined in a script which can be viewed as a web page and is also available as a downloadable J script.

I should say here that the EVM adverb is only my interpretation of the Dictionary (as indeed is the whole of this book). For the examples below, EVM appears to compute the same results as J itself, but it has not been exhaustively tested.

31.2 First Example

Evaluation of an expression such as 2+3 can be modelled by offering the argument '2+3' (a string, notice) to the modelling adverb EVM.

2+3 '2+3' EVM
5
5

We see that '2+3' EVM computes the same value as 2+3, but EVM also produces a trace, or history, of the evaluation process. The history of 2+3 looks like this:

   show ''

  queue  stack  rule
0   § 2 + 3              
1   § 2 +    3          
2   § 2    +  3        
3   §    2  +  3      
4       §  2  +  3     dyad
5       §  5        

We see successive stages of the process. Each stage is defined by the values of two variables. Firstly there is a "queue", initially containing the expression being evaluated, divided into words and preceded by a symbol to mark the beginning. Secondly, there is a "stack", initially empty. Stage 0 shows queue and stack at the outset.

At each stage the stack is inspected to see if anything can be done, that is, whether the first few words in the stack form a pattern to which a rule applies. There are 10 of these rules, and each one is tried in turn. If no rule applies, then a word is transferred from the tail of the queue to the head of the stack, and we go to the next stage and try again. This process takes us from stage 0 to stage 4.

At stage 4, we find that a rule is applicable. This rule is identified as dyad in the rightmost column. Informally, the dyad rule is:

if the first four items in the stack are something, noun, verb, noun, then apply verb to noun and noun to get new-noun, and replace the first four items in the stack by two, namely original-something followed by new-noun.

Stage 5 shows the results of applying the "dyad". in stage 4. The rules are tried again, with no result, and there are no more words in the queue, so we have finished. The final result is the second item of the stack.

The history is represented by 3 global variables, Qh Sh and Rh. The history can be displayed directly in the execution window by entering the expression Qh,.Sh,.Rh.

   Qh ,. Sh ,. Rh
+----+-+-+-+----+-+-+-+----+
|mark|2|+|3|    | | | |    |
+----+-+-+-+----+-+-+-+----+
|mark|2|+| |3   | | | |    |
+----+-+-+-+----+-+-+-+----+
|mark|2| | |+   |3| | |    |
+----+-+-+-+----+-+-+-+----+
|mark| | | |2   |+|3| |    |
+----+-+-+-+----+-+-+-+----+
|    | | | |mark|2|+|3|dyad|
+----+-+-+-+----+-+-+-+----+
|    | | | |mark|5| | |    |
+----+-+-+-+----+-+-+-+----+

However, a more readable display is produced by the show function which computes, from Qh Sh and Rh, a fragment of HTML. This HTML is not for viewing in the execution window but rather for pasting into a web page such as this one. Corresponding to Qh Sh and Rh as above we would see:

   show ''

  queue  stack  rule
0   § 2 + 3              
1   § 2 +    3          
2   § 2    +  3        
3   §    2  +  3      
4       §  2  +  3     dyad
5       §  5        

31.3 Parsing Rules

In this section an example is shown of each of the 10 parsing rules. Each rule looks for a pattern of items at the front of the stack, such as something verb noun verb. Each item of the stack is classified as one of the following: verb, noun, adjective, conjunction, name, left-parenthesis, right-parenthesis, assignment-symbol (=. or =:) or beginning-mark.

To aid in a compact statement of the rules, larger classes of items can be formed. For example, an item is classified as an "EDGE" if it is a beginning-mark, an assignment-symbol or a left-parenthesis.

The rules are always tried in the same order, the order in which they are presented below, beginning with the 'monad rule' and ending with the 'parenthesis rule'.

31.3.1 Monad Rule

If the first 3 items of the stack are an "EDGE" followed by a verb followed by a noun, then the verb is applied (monadically) to the noun to give a result-value symbolized by Z say, and the value Z replaces the verb and noun in the stack. The scheme for transforming the items of the stack is:

      monad rule: EDGE VERB NOUN etc  =>   EDGE Z etc

where Z is the result computed by applying VERB to NOUN. For example:

*: 4 '*: 4' EVM
16
16

   show ''

  queue  stack  rule
0   § *: 4            
1   § *:    4        
2   §    *:  4      
3       §  *:  4     monad
4       §  16      

31.3.2 Second Monad Rule

An item in the stack is classified as "EAVN" if it is an EDGE or an adverb or verb or noun. The scheme is:

      monad2 rule: EAVN VERB1 VERB2 NOUN etc => EAVN VERB1 Z etc

where Z is VERB2 monadically applied to NOUN. For example:

- *: 4 '- *: 4' EVM
_16
_16

   show ''

  queue  stack  rule
0   § - *: 4              
1   § - *:    4          
2   § -    *:  4        
3   §    -  *:  4      
4       §  -  *:  4     monad2
5       §  -  16       monad
6       §  _16        

31.3.3 Dyad Rule

The scheme is

      dyad rule:  EAVN NOUN1 VERB NOUN2 etc => EAVN Z etc

where Z is VERB applied dyadically to NOUN1 and NOUN2. For example.

3 * 4 '3 * 4' EVM
12
12

   show ''

  queue  stack  rule
0   § 3 * 4              
1   § 3 *    4          
2   § 3    *  4        
3   §    3  *  4      
4       §  3  *  4     dyad
5       §  12        

31.3.4 Adverb Rule

An item which is a verb or a noun is classified as a "VN" The scheme is:

      adverb rule: EAVN VN ADVERB etc => EAVN Z etc

where Z is the result of applying ADVERB to VN. For example:

+ / 1 2 3 '+ / 1 2 3' EVM
6
6

   show ''

  queue  stack  rule
0   § + / 1 2 3              
1   § + /    1 2 3          
2   § +    /  1 2 3        
3   §    +  /  1 2 3      
4       §  +  /  1 2 3     adv
5       §  +/  1 2 3       monad
6       §  6        

31.3.5 Conjunction Rule

The scheme is:

      conjunction  EAVN VN1 CONJ VN1 etc => EAVN Z etc

where Z is the result of applying conjunction CONJ to arguments VN1 and VN2. For example:

1 & + 2 '1 & + 2' EVM
3
3

   show ''

  queue  stack  rule
0   § 1 & + 2                
1   § 1 & +    2            
2   § 1 &    +  2          
3   § 1    &  +  2        
4   §    1  &  +  2      
5       §  1  &  +  2     conj
6       §  1&+  2         monad
7       §  3          

31.3.6 Fork Rule

The scheme is:

      fork rule: EAVN VERB1 VERB2 VERB3 etc => EAVN Z etc

where Z is a single verb defined as the fork (VERB1 VERB2 VERB3). For example:

   f=: +/
   g=: %
   h=: #

(f g h) 1 2 '(f g h) 1 2' EVM
1.5
1.5

   show ''

  queue  stack  rule
0   § ( f g h ) 1 2                  
1   § ( f g h )    1 2              
2   § ( f g h    )  1 2            
3   § ( f g    h  )  1 2          
4   § ( f    g  h  )  1 2        
5   § (    f  g  h  )  1 2      
6   §    (  f  g  h  )  1 2     fork
7   §    (  f g h  )  1 2         paren
8   §    f g h  1 2            
9       §  f g h  1 2           monad
10       §  1.5            

31.3.7 Trident Rule

We can write "CAVN" to denote an item which is a conjunction or adverb or verb or noun. The scheme is:

      trident rule: EDGE CAVN1 CAVN2 CAVN3 etc => EDGE Z etc

where Z is a single item (itself a CAVN) defined by one of the schemes for tridents in Chapter 13. In the following example the expression (g,@) is of the form verb, verb conjunction, and so is an instance of trident VVC. Therefore it is a conjunction.

f (g,@) h 'f (g,@) h' EVM
g , (f@h)
g , (f@h)

   show ''

  queue  stack  rule
0   § f ( g , @ ) h                  
1   § f ( g , @ )    h              
2   § f ( g , @    )  h            
3   § f ( g ,    @  )  h          
4   § f ( g    ,  @  )  h        
5   § f (    g  ,  @  )  h      
6   § f    (  g  ,  @  )  h     trident
7   § f    (  g , @  )  h         paren
8   § f    g , @  h            
9   §    f  g , @  h          
10       §  f  g , @  h         conj
11       §  g , (f@h)            

31.3.8 Bident Rule

The scheme is:

      bident rule: EDGE CAVN1 CAVN2 etc => EDGE Z etc

where Z is a single item (itself a CAVN) defined by one of the schemes for bidents in Chapter 13. In the following example the expression (1 &) is of the form noun conjunction, and so is an instance of bident NC. Therefore it is an adverb.

+ (1 &) 2 '+ (1 &) 2' EVM
3
3

   show ''

  queue  stack  rule
0   § + ( 1 & ) 2                
1   § + ( 1 & )    2            
2   § + ( 1 &    )  2          
3   § + ( 1    &  )  2        
4   § + (    1  &  )  2      
5   § +    (  1  &  )  2     bident
6   § +    (  1&  )  2       paren
7   § +    1&  2          
8   §    +  1&  2        
9       §  +  1&  2       adv
10       §  1&+  2         monad
11       §  3          

31.3.9 Assignment Rule

We write NN to denote a noun or a name. and Asgn for the assignment symbol =: or =.. The scheme is:

      assign rule: NN Asgn CAVN etc => Z etc

where Z is the value of CAVN.

1 + x =: 6 '1 + x =: 6' EVM
7
7

   show ''

  queue  stack  rule
0   § 1 + x =: 6              
1   § 1 + x =:    6          
2   § 1 + x    =:  6        
3   § 1 +    x  =:  6       assign
4   § 1 +    6          
5   § 1    +  6        
6   §    1  +  6      
7       §  1  +  6     dyad
8       §  7        

31.3.10 Parenthesis Rule

The scheme is:

     paren rule: ( CAVN ) etc => Z etc

where Z is the value of CAVN. For example:

(1+2)*3 '(1+2)*3' EVM
9
9

   show ''

  queue  stack  rule
0   § ( 1 + 2 ) * 3                    
1   § ( 1 + 2 ) *    3                
2   § ( 1 + 2 )    *  3              
3   § ( 1 + 2    )  *  3            
4   § ( 1 +    2  )  *  3          
5   § ( 1    +  2  )  *  3        
6   § (    1  +  2  )  *  3      
7   §    (  1  +  2  )  *  3     dyad
8   §    (  3  )  *  3         paren
9   §    3  *  3            
10       §  3  *  3           dyad
11       §  9              

31.3.11 Examples of Transfer

The following example shows that when a name is transferred from queue to stack, if the name denotes a value which is a noun, then the value, not the name, moves to the queue.

a =: 6 (a=:7) , a
6
7 6

a=: 6 '(a =: 7) , a' EVM
6
7 6

   show ''

  queue  stack  rule
0   § ( a =: 7 ) , a                  
1   § ( a =: 7 ) ,    6              
2   § ( a =: 7 )    ,  6            
3   § ( a =: 7    )  ,  6          
4   § ( a =:    7  )  ,  6        
5   § ( a    =:  7  )  ,  6      
6   § (    a  =:  7  )  ,  6     assign
7   § (    7  )  ,  6        
8   §    (  7  )  ,  6       paren
9   §    7  ,  6          
10       §  7  ,  6         dyad
11       §  7 6            

By contrast, if the name is that of a verb, then the name is transferred into the stack without evaluating it. Hence a subsequent assignment changes the verb applied.

f=: + ((f=:-) , f) 4
+
_4 _4

f =: + '((f =: -),f) 4' EVM
+
_4 _4

   show ''

  queue  stack  rule
0   § ( ( f =: - ) , f ) 4                      
1   § ( ( f =: - ) , f )    4                  
2   § ( ( f =: - ) , f    )  4                
3   § ( ( f =: - ) ,    f  )  4              
4   § ( ( f =: - )    ,  f  )  4            
5   § ( ( f =: -    )  ,  f  )  4          
6   § ( ( f =:    -  )  ,  f  )  4        
7   § ( ( f    =:  -  )  ,  f  )  4      
8   § ( (    f  =:  -  )  ,  f  )  4     assign
9   § ( (    -  )  ,  f  )  4        
10   § (    (  -  )  ,  f  )  4       paren
11   § (    -  ,  f  )  4          
12   §    (  -  ,  f  )  4         fork
13   §    (  - , f  )  4             paren
14   §    - , f  4                
15       §  - , f  4               monad
16       §  _4 _4                

31.3.12 Review of Parsing Rules

rule   stack before   stack after   where Z is ...
monad   EDGE Verb Noun etc   EDGE Z etc   Verb applied to Noun
monad2   EAVN Verb1 Verb2 Noun   EAVN Verb1 Z   Verb2 applied to Noun
dyad   EAVN Noun1 Verb Noun2   EAVN Z etc   Verb applied to Noun1 and Noun2
adverb   EAVN VN Adv etc   EAVN Z etc   Adv applied to VN
conj   EAVN VN1 Conj VN2   EAVN Z etc   Conj applied to VN1 and VN2
fork   EAVN Verb1 Verb2 Verb3   EAVN Z etc   fork (Verb1 Verb2 Verb3)
trident   EDGE CAVN1 CAVN2 CAVN3   EDGE Z etc   trident (CAVN1 CAVN2 CAVN3)
bident   EDGE CAVN1 CAVN2 etc   EDGE Z etc   bident (CAVN1 CAVN2)
assign   NN Asgn CAVN etc   Z etc etc   CAVN
paren   ( CAVN ) etc   Z etc etc   CAVN

31.4 Effects of Parsing Rules

Now we look at some of the effects, of the parsing rules. In what follows, notice how the parsing rules in effect give rise to implicit parentheses.

31.4.1 Dyad Has Long Right Scope

Consider the expression 4+3-2, which means 4+(3-2).

4 + 3 - 2 4 + (3-2) '4+3-2' EVM
5
5
5

   show ''

  queue  stack  rule
0   § 4 + 3 - 2              
1   § 4 + 3 -    2          
2   § 4 + 3    -  2        
3   § 4 +    3  -  2      
4   § 4    +  3  -  2     dyad
5   § 4    +  1        
6   §    4  +  1      
7       §  4  +  1     dyad
8       §  5        

Here we have an example of a general rule: a dyadic verb takes as its right argument as much as possible, so in this example + is applied to 3-2, not just 3.

Further, a dyadic verb takes as left argument as little as possible. In this example the left argument of - is just 3, not 4+3. Hence a dyadic verb is said to have a "long right scope" and a "short left scope".

31.4.2 Operators Before Verbs

Adverbs and conjunctions get applied first, and then the resulting verbs:

* & 1 % 2 * & (1 % 2) (*&1) % 2
0.5
*&(0.5)
0.5

   '* &  1 % 2' EVM
0.5
   show ''

  queue  stack  rule
0   § * & 1 % 2                  
1   § * & 1 %    2              
2   § * & 1    %  2            
3   § * &    1  %  2          
4   § *    &  1  %  2        
5   §    *  &  1  %  2      
6       §  *  &  1  %  2     conj
7       §  *&1  %  2         monad2
8       §  *&1  0.5           monad
9       §  0.5            

31.4.3 Operators Have Long Left Scope

An adverb or a conjunction takes as its left argument as much as possible. In the following, look at the structure of the resulting verbs: evidently the / adverb and the @ conjunction take everything to their left:

f @ g / f & g @ h 'f&g@h' EVM
(f@g)/
(f&g)@h
(f&g)@h

   show ''

  queue  stack  rule
0   § f & g @ h                  
1   § f & g @    h              
2   § f & g    @  h            
3   § f &    g  @  h          
4   § f    &  g  @  h        
5   §    f  &  g  @  h      
6       §  f  &  g  @  h     conj
7       §  f&g  @  h         conj
8       §  (f&g)@h            

Thus operators are said to have a "long left scope". In the example of f&g@h we see that the right argument of & is just g, not g@h . Thus conjunctions have "short right scope".

31.4.4 Train on the Left

The long left scope of an adverb does not extend through a train: parentheses may be needed to get the desired effect. Suppose f g h is intended as a train, then compare the following:

f g h / (f g h) /
f g (h/)
(f g h)/

   'f g h / ' EVM
f g (h/)
   show ''

  queue  stack  rule
0   § f g h /              
1   § f g h    /          
2   § f g    h  /        
3   § f    g  h  /       adv
4   § f    g  h/        
5   §    f  g  h/      
6       §  f  g  h/     fork
7       §  f g (h/)        

Similarly for a conjunction (with a right argument)

f g h @ + 'f g h @ +' EVM
f g (h@+)
f g (h@+)

   show ''

  queue  stack  rule
0   § f g h @ +              
1   § f g h @    +          
2   § f g h    @  +        
3   § f g    h  @  +      
4   § f    g  h  @  +     conj
5   § f    g  h@+        
6   §    f  g  h@+      
7       §  f  g  h@+     fork
8       §  f g (h@+)        

However, for a conjunction with no right argument, the left scope does extend through a train:

f g h @ 'f g h @' EVM
(f g h)@
(f g h)@

   show ''

  queue  stack  rule
0   § f g h @                
1   § f g h    @            
2   § f g    h  @          
3   § f    g  h  @        
4   §    f  g  h  @      
5       §  f  g  h  @     fork
6       §  f g h  @         bident
7       §  (f g h)@          

By contrast, in the case of of f @ g /, notice how the "conj" rule is applied before there is a chance to apply the "adverb" rule"

f @ g / 'f @ g / ' EVM
(f@g)/
(f@g)/

   show ''

  queue  stack  rule
0   § f @ g /                
1   § f @ g    /            
2   § f @    g  /          
3   § f    @  g  /        
4   §    f  @  g  /      
5       §  f  @  g  /     conj
6       §  f@g  /         adv
7       §  (f@g)/          

31.4.5 Presumption of Verb

A name with no value assigned is presumed to be a verb. For example, in the following the three names make a fork:

Maple Leaf Rag 'Maple Leaf Rag' EVM
Maple Leaf Rag
Maple Leaf Rag

   show ''

  queue  stack  rule
0   § Maple Leaf Rag              
1   § Maple Leaf    Rag          
2   § Maple    Leaf  Rag        
3   §    Maple  Leaf  Rag      
4       §  Maple  Leaf  Rag     fork
5       §  Maple Leaf Rag        

This is the end of Chapter 31



Table of Contents


Copyright © Roger Stokes 2001. This material may be freely reproduced, provided that this copyright notice is also reproduced.

last updated 12 Sep 01