It's cool that 3 * 4 results in 12, and * 4 results in 1, but does using the same primitive for both operations ever provide a benefit? For example, let's say I were to define the following:

SIGNUM =: * : [:
TIMES =: [: : *

If I were to only ever use SIGNUM and TIMES instead of *, would I ever miss out on a clever use of *? That is, x TIMES y seems to be exactly the same as x * y for every x I can imagine (although my imagination is pretty limited in this regard). Is there an x where x * y produces the same result as SIGNUM y?

In case * : [: isn't immediately clear, the following should illustrate:

   SIGNUM =: * : [:
   TIMES =: [: : *
   SIGNUM 4
1
   3 TIMES 4
12
   * 4
1
   3 * 4
12
   3 SIGNUM 4
|domain error: SIGNUM
|   3     SIGNUM 4
   TIMES 4
|domain error: TIMES
|       TIMES 4
2

There are 2 answers

3
jpjacobs On BEST ANSWER

Let's write conclusions from the comments down:

There is no direct language-level reason not to use names for primitives

Using names instead of primitives can however harm performance, as special code does not necessarily get triggered. I think this can be remedied by fixing verbs after building them with f..

The reason for having the same name for monadic and dyadic verbs is historical: APL used it before. Most verbs have a related actions in monadic / dyadic versions and inflections (a number of trailing dots and colons).

For instance, ^ can be expressed in traditional notation as pow(x,y) or exp(y) where x and y are left and right arguments, and e is Euler's constant. Here, the monadic version is the same as the dyadic version, with a sensible default left argument. Different inflections of the same root are all power-related verbs: - ^. does logarithms (base e for the monad) - ^: does Power conjunction, applying a verb a variable number of times.

Other relations between monadic and dyadic verbs can also exist, for example $ can be said to get or set the Shape of an array, depending on whether it is used as monad or dyad.

That said, I think that once one gets a bit of experience with J, it becomes easier to spot which valence a verb has based on the sentence it is used in. Examples are:

Monad @ Ambiv NB. Mv is always used monadically, Av depends on arguments
Ambiv & Monad
(Dyad Monad) NB. A hook, where verb 1 is always dyadic
(Ambiv Dyad Ambiv) NB. A fork, the middle is one always dyadic
0
pascalJ On

It was probably a mistake to use the same symbols for dyadic and monadic built-ins except for those where the monadic case is a default parameter to the dyad.

TIMES =: 1&$: : *

would be a good defnition that doesn't give an error.

As for ambivalent cases,

(3 * TIMES) 4
12
2 (3 * TIMES) 4
24

Another useful ambivalent verb is:

TIMESORSQUARE =: *~

*~ 3
9
2 *~ 3
6