I wrote:
> it is possible to build and execute arbitrary noun phrases
> from gerunds with a tacit verb. I'll be busy today, so
> I'll leave that as a little puzzle.
I got out of a meeting early. Spoilers in 10,
9,
8,
7,
6,
5,
4,
3,
2,
1,
Here, we have a sneaky verb which allows us to apply each of the verbs in the
gerund RHA to the LHA.
+:`%`-: sneaky 7
14 0.142857 3.5
Now, we can use our usual tools, i.e. rank, to pair arbitrary cells of the left
and right arguments. For example, apply each verb on the left to the
corresponding item on the right, use rank 0:
+:`%`-: sneaky"0 i.3
0 1 1
Or, apply each verb on the left to the entire right argument, use rank 1:
+:`%`-: sneaky"1 i.3
0 2 4
_ 1 0.5
0 0.5 1
And, by the same token, we can generalize to higher-order gerunds (gerunds with
rank > 1):
Apply each verb to the corresponding atom of the table ("0)
(2 2 $ +:`-:`*:`%:) sneaky"0 i. 2 2
0 0.5
4 1.73205
Apply verb to the corresponding row of the input ("1):
(2 2 $ +:`-:`*:`%:) sneaky"1 i. 2 2
0 2
0 0.5
4 9
1.41421 1.73205
Apply each verb to the entire input ("2 or "_ or just leave rank off):
(2 2 $ +:`-:`*:`%:) sneaky"2 i. 2 2
0 2
4 6
0 0.5
1 1.5
0 1
4 9
0 1
1.41421 1.73205
Note that, unlike 128!:2, this is a native gerund solution; we can apply verbs
of arbitrary complexity, even tacit, compound verbs:
+~`+:`(2&*) sneaky"0 *:1 2 3
2 8 18
+~`+:`(2&*) sneaky"1 *:1 2 3
2 8 18
2 8 18
2 8 18
How do we do it, you ask? Simple! Just use ]^:] .
sneaky =: (]^:] '1:' ; '@' <@; <@,&(<'['))"_ 0~
Hey, it's named "sneaky" for a reason :) Of course, in general, the verbs may
produce incompatible outputs (e.g. one may produce numbers and another strings,
or one may produce tables and another scalars, etc). In that case, we may want
to box each output individually:
sneakyB =: (<@]^:[~ '1:' ; '@' <@; <@,&(<'['))"_ 0~
For example:
+:`%`-: sneakyB 7
+--+--------+---+
|14|0.142857|3.5|
+--+--------+---+
+:`%`-: sneakyB"0 ] 1 2 3
+-+---+---+
|2|0.5|1.5|
+-+---+---+
Which is kind of nice, because it also provides the behavior of the original
sneaky (i.e., don't bother boxing the results if they're conformable) by simply
switching the 1: with 0: :
sneaky =: (<@]^:[~ '0:' ; '@' <@; <@,&(<'['))"_ 0~
+:`%`-: sneaky 7
14 0.142857 3.5
Which also hints at the mechanism being used.
Anyway, a further generalization would be to express sneaky as a tacit adverb,
taking the gerund as its argument; this would lose some of the control rank
gives us, but on the flip side would let us apply verbs dyadically as well as
monadically. Left as an exercise for the (masochistic) reader.
-Dan
PS: Roger, there's a bug in J. We can write sneaky as:
sneaky =: (]^:] '1:' ; '@' <@; <@,&(<'['))"_ 0~
+:`%`-: sneaky 7
14 0.142857 3.5
So we should be able to write sneakyB as :
sneakyB =: (<@]^:] '1:' ; '@' <@; <@,&(<'['))"_ 0~
that is, just tack a <@ in front, but we can't:
+:`%`-: sneakyB 7
|domain error: sneakyB
| +:`%`-: sneakyB 7
So we have to use circumlocutions, like:
sneakyB =: (([: < ])^:] '1:' ; '@' <@; <@,&(<'['))"_ 0~
+:`%`-: sneakyB 7
+--+--------+---+
|14|0.142857|3.5|
+--+--------+---+
or
sneakyB =: (4 : '<y'^:] '1:' ; '@' <@; <@,&(<'['))"_ 0~
+:`%`-: sneakyB 7
+--+--------+---+
|14|0.142857|3.5|
+--+--------+---+
or
sneakyB =: (<@]^:[~ '1:' ; '@' <@; <@,&(<'['))"_ 0~
+:`%`-: sneakyB 7
+--+--------+---+
|14|0.142857|3.5|
+--+--------+---+
etc. That these methods work may indicate that the bug lies in some special
code supporting <@]^: .
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm