Richard Donovan <[EMAIL PROTECTED]> wrote:

> CHAR =: 1  :0
> t1=: a.i.x
> t2=: a.i.y
> t1 u t2
> )
>
> but...
>
>    'z'> CHAR 'a'
> |domain error
> |   'z'   >CHAR'a'
>   t1
> 33
>    t2
> 97
>    t1{a.
> !
>    t2{a.
> a
>
> I am missing something obvious (again!)

Adverbs and conjunctions can be used to make verbs in two ways:

1) They can immediately return tacit verbs, which are then invoked.
   This is the style used in several responses to your message.
   The bodies of such adverbs/conjunctions may use only the operator
   parameter names (m/u and/or n/v). They may not use the verb
   paramaters (x,y) since the verb is being returned to be executed
   later, but not executed at this time.
   (An obsolescent style is also supported, which uses only x and y
    are used; in this case, x and y are equivalent to u and v.)

2) They can include entire verb bodies which are executed each time.
   This style is invoked when you use both the operator parameters
   (m/u/n/v) and verb parameters (x/y).
   In this case, the verb may be ambivalent (just as with 3 : 0),
   with the monad part coming first, optoinally followed by an
   empty line containing a single : followed by the dyad part.

In the example above, you defined an adverb that executes a
verb with a monadic part, but no dyadic part. As such, invoking
it dyadically yields a domain error.

(This is a VERY common error - I find myself making it all the time!)

If you want the result to be dyadic, do this: 

CHAR =: 1  :0
:
  t1=: a.i.x
  t2=: a.i.y
  t1 u t2
)

The reason you got valid (and strange) results for t1 and t2 was
that your adverb body never got executed, and t1/t2 contained
garbage left over from things you had done previously.

Something else you should consider when writing explicit verb
or operator definitions: in most cases, unless you have a very
good reason to do so, you should try to avoid using global
assignments (=:) as they produce side-effects and pollute
the namespace. For temporary variables you should use local
assignmetns (=.) whenever possible.

One good reason to violate the above rule, however, is if you
are trying to debug something; sometimes saving the results from
each line in a verb in a global variable for subsequent
examination can often be less cumbersome than using the
debugging primitives.

Once you learn to "think tacitly", you will be able to refactor
thinks like the above; For eaxmple:

NB. Initial explicit form
CHAR =: 1 : 0
:
  t1 =. a.i.x
  t2 =. a.i.y
  t1 u t2
)

NB. Use constants with monads
NB. k u y  ->  k&u y
CHAR =: 1 : 0   
:
  t1 =. (a.&i.) x
  t2 =. (a.&i.) y
  t1 u t2
)

NB. Eliminate temporaries
CHAR =: 1 : 0
:
  ((a.&i.) x) u ((a.&i.) y)
)

NB. Factor common sub-expressions by using bonding conjunctions or trains:
NB. (If v has infinite rank, the conjunctions & &. and @ are equivalent to &: 
&.: and @:)
NB. In this case: v = a.&i. so (v x) u (v  y) -> x u&:v y
NB. These other patterns are also commonly used:
NB. u (v y)  ->  u@:v y  or  u&:v y  or  ([: u v) y
NB. v^:_1 (u (v y))  ->  u&.:v y
NB. v^:_1 ((v x) u (v y))  ->  x u&.:v y
NB. u (x v y)  ->  x u@:v y
NB. (x u y) v (x w y)  ->  x (u v w) y
NB. (u y) v (w y)  ->  x (u v w) y
NB. x u (v y)  ->  x (u v) y
NB. y u (v y)  ->  (u v) y
CHAR =: 1 : 0   
:
  x (u &: (a.&i.)) y
)

NB. Final tacit form
CHAR =: 1 : 'u &: (a.&i.)'

-- Mark D. Niemiec <[EMAIL PROTECTED]>

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to