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.

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

If the 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:

   f =: 'f' & ,
   g =: 'g' & ,

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 we have the trident VVC.

   f =: 'f' & ,
   g =: 'g' & ,
   h =: 'h' & ,

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 we have the bident NC.

   f =: 'f' & ,
   g =: 'g' & ,
   h =: 'h' & ,

+ (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.

   f =: 'f' & ,
   g =: 'g' & ,
   h =: 'h' & ,

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 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.11 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) / f & g @ h (f&g) @ h
(f@g)/
(f@g)/
(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        
 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) / 'f @ g / ' EVM
(f@g)/
(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
   
   'Maple Leaf Rag' EVM
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 2000. This material may be freely reproduced, provided that this copyright notice and provision is also reproduced.

last updated 16 Mar 00