Gregory Higley
Gregory Higley

Reputation: 16598

Strange length error when defining a conjunction in J

I'm playing around with adverbs and conjunctions in J, and have run across a strange problem. I've defined a simple adverb called persistence that can be used to view the progression of numbers generated when calculating the digital product or digital sum of a number.

S =: 1 : 'u/@:("."0)@":^:a:"0'

+ S 234 gives us 234 9. I then used this to create another adverb that calculates the persistence of a number.

P =: 1 : '<:@#@(u S)"0'

+ P 234 gives us 1. Now, imagine we want to find all numbers below 30 with additive persistence of 2 and then view the list generated by S for each number, e.g.,

+ S I. 2 = + P i.30

This generates the following list:

19 10 1
28 10 1
29 11 2

So far, so good. Now, I wanted to take this and turn it into a conjunction, the left-hand side of which contains the verb to use for persistence and the right-hand side of which contains the number used to limit the list. (2 in the example above.) Here's my definition of that conjunction:

Q =: 2 : 'u S I. n = u P'

If I enter the expression + Q 2 into the J console, I get back the following:

+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0

This is exactly correct, and if I run the full expression with an argument such as i.30, it works fine:

+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0 i.30

However, when I enter the expression + Q 2 i.30 into the J console, I get back a 'length error'. Why?! Isn't + Q 2 exactly equivalent to +/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0?

I'm completely stumped. What am I missing? I've played around with rank both inside the definition of the conjunction and outside of it. I just don't get it.

Upvotes: 3

Views: 234

Answers (1)

koz
koz

Reputation: 206

+ Q 2 is exactly equivalent to the expression you provided, but when using it in an expression it is as if it is in parenthesis.

   +/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0 i.30
19 10 1
28 10 1
29 11 2
   (+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0) i.30
|length error

In general f g h y != (f g h) y. In the latter f g h defines a train. For example:

   avg=: +/ % #
   +/ % # 1 2 3
0.333333
   (+/ % #) 1 2 3
2
   avg 1 2 3
2

You can fix your conjunction by adding a reference to y to it like this:

   Q=: 2 : 'u S I. n = u P y'
   + Q 2 i.30
19 10 1
28 10 1
29 11 2

Upvotes: 3

Related Questions