Building an array of verbs in J - j

Is it possible to build arrays of verbs?
I've tried this:
f =: >:
f2 =: f f
There's no syntax error but f2 is clearly not an array of verbs.
For instance
f2 yields f f
$ f2 yields $ f2
0 { f2 yields 0 { f2
2 3 $ f behaves in a similar way.
I'd also like to know if verbs can be activated by the name.
Edited
Instead of f2 =: f f, which is a composition, let's have
f =: >:
f2 =: 2 1 $ f
f2 yields 2 1 $ f
$ f2 yields $ f2
0 { f2 yields 0 { f2
It seems that f2 represents the sequence 2 1 $ f, while in the case of an atom, e.g. 2 1 $ 7, the right side is a vector.

A collection of functions is called a gerund in J and is formed using the tick "`":
g =: +`-`f
┌─┬─┬─┐
│+│-│f│
└─┴─┴─┘
You can use #. to apply the appropriate verb using its index:
4 2 3 (g #. 0) 1 5 6
5 7 9
4 2 3 (g #. 1) 1 5 6
3 _3 _3
4 2 3 (g #. 2) 1 5 6
1 0 0
NB. defining a 2x2 gerund:
k =: 2 2 $ +`-`*`%
┌─┬─┐
│+│-│
├─┼─┤
│*│%│
└─┴─┘
1 (((<0 0) { k) #. 0) 2
3
1 (((<0 1) { k) #. 0) 2
_1
1 (((<1 0) { k) #. 0) 2
2
1 (((<1 1) { k) #. 0) 2
0.5
The index can also be a new verb that depends on the arguments or a list of indices.

As the comments point out, f2=: f f creates a composition and f3=: 2 1 $ f creates a composition as well. In the case of f2 you are defining a hook and in the case of f3 you are defining a fork that will take the results of f when it is given an argument and return the 2 1 shape of that result. The reason that it just parrots back your input is that is the way that J displays verbs without arguments. It shows you the construction, because it does not know what the verb will be applied to.
I think what you may want is the process of making a verb into a gerund, which is the noun form of a verb that can be activated in a number of ways. Creating a gerund is done by inserting a backtick between two verbs or for a single verb, a backtick between the verb and an empty string. Examples of conjunctions that work on gerunds are Agenda and Evoke Gerund.
Although this can be done in J, it is pretty clunky because J does not have the meta-operators that are necessary to manipulate verbs as if they are nouns, aside from turning them into gerunds.

Related

different result once square root is added inside tacit

Very new to J. I love it but still far from fluent in it.
I have managed to hit an issue and I don't know why it is happening. If somebody could please explain why this is occuring I could learn more about this straight-to-the-point language.
Basically I'm doing difference (-) then squared (*:) then sum (+/) then want to take the square root (%:).
Now the sum square error part ( (+/#:*:#:-) ) works fine:
1 2 3 4 5 (+/#:*:#:-) 2 2 2 2 2
15
Then I can get the square root this way (just add %: to left):
%: 1 2 3 4 5 (+/#:*:#:-) 2 2 2 2 2
3.87298
But when I add square root to left of the atco (tacit?) part in the middle it doesn't give me the right result:
1 2 3 4 5 (%:#:+/#:*:#:-) 2 2 2 2 2
1.57001
It instead returns 1.57001 instead of 3.87298.
My understanding is all I have done is add a 'then do square root' but obviously I am wrong. But I don't understand why.
When I dissect:
require 'debug/dissect'
dissect '1 2 3 4 5 (%:#:+/#:*:#:-) 2 2 2 2 2'
I see diff (-) and square (*:) are in their own dissect boxes. But then the last box combines sum (+/) and square root (%:) together, showing %:#:+/ . Not a separate box for +/ and then %: .
As I said I am new to J and am struggling to understand why this is occuring here.
I've tried changing to &, &: and # instead but as expected that didn't fix this issue.
It doesn't appear to be due to some composition limit either since this works fine (has many more atco's combined):
(>:#:>:#:>:#:>:#:>:#:>:#:>:#:>:#:>:) 2 2 2
11 11 11
Thank you
The issue that you are encountering is that
(%:#:+/#:*:#:-)
is being evaluated as
1 2 3 4 5 ((%:#:+)/#:*:#:-) 2 2 2 2 2
1.57001
and not
1 2 3 4 5 %:#:(+/#:*:#:-) 2 2 2 2 2
3.87298
because of the way that conjunctions take as much of the left operand as possible. This means that your partial result from *:#:- is being processed by %:#:+/ when you want %: to apply to the result of +/#:*:#:-
Since you are just starting your journey with J, this may be a bit advanced, but at some point you may want to read the tacit programming section of J for C programmers by Henry Rich. It has a very good explanation about how J sentences are parsed. Parenthesis are your friend when you want to change the order of execution. https://www.jsoftware.com/help/jforc/contents.htm#_Toc191734581
Edit: As #Eelvex points out in the comment below the break actually occurs at (+/), but the result is the same because of the way that conjunctions are evaluated left to right.
You are trying to form a dyadic verb for the expression:
%: +/ *: x - y NB. which we can write as
f g h x - y NB. if we define:
f =: %:
g =: +/
h =: *:
f g h x - y
3.87298
One way of making this a dyadic verb is to apply #: everywhere:
x (f#:g#:h#:-) y
3.87298
x (%: #: (+/) #: *: #: -) y
3.87298
A more idiomatic way of doing it uses under (&.) which inverses a verb after applying another:
f &.: g y NB. expands to
(g-inverse) f g y
g &.: h (x - y)
3.87298
x ( g &.: h #: -) y
3.87298
NB. or if you prefer monadic verbs:
(g &.: h #: -/) x,: y

Is there any use for dyadic hooks in J?

It occurs to me that a dyadic hook has the same effect as the same verbs without the parentheses, e.g.,
2 (+ #) 1 2 3
2 + # 1 2 3
These both produce the same result: 5. What can I do with (+ #) that I can't do with + #?
I think that the big difference is that you can use hooks tacitly to build more complex verbs. The hook becomes a module that you can drop into a longer fork. Removing parentheses takes away the functionality of the hook.
2 (+ #) 1 2 3
5
This allows me to pad out a list with 2 more zeros
2 ((+ #){. ]) 1 2 3
1 2 3 0 0
This gives a different result
2 (+ # {. ]) 1 2 3
3 4 5
Dyadic hook solves the composition "problem" where M stands for a monadic verb, and D a dyadic verb.
M#D
(D M)
Dyadic hook is more necessary than the monadic version which is just a short cut for
(] D M)
though dyadic hook can also be modeled as
([ D M#:])
which is also an ambivalent expression. An example:
(, *~)
monadically, appends y and its square
dyadically, appends x and the product of x and y.
(oops, bob is right). Correct ambivalent verb with above explanations.
([ , *~)

Finding the minimum integer satisfying a predicate

Is there a good way of finding the smallest integer (starting zero) that satisfies a given predicate in J ?
This is what infinite power with a right verb is for (^:v^:_). For example, find the first integer divisible by 7.
check =: 0 ~: 7 | ] NB. check if y is not a multiple of 7
(>:^:check)^:_ ] 1 NB. increment y (1) while check is true
7
A second point is that if you are searching in an array, you can use the special code f i. 1: (first place where x f y). See: http://www.jsoftware.com/help/release/edot504.htm
Eelvex's answer may be what you are looking for, but one way to read your question is what is the minimum integer greater than 0 in a list. These functions return index of first conditional minimum.
(i. <./) _"_^:(<&0)("0) _3 _1 3 4 2
4
minatleast =: (i. <./)#]#:(_"_^:>("0))
0 minatleast _3 _1 3 4 2
4
3 minatleast _3 _1 3 4 2
2

column and row join a second box data

I want to column join
┌─┬─┬─┐
│1│1│2│
│2│4│4│
│3│9│6│
└─┴─┴─┘
and I'd like to put a=.1 2 3 as the fourth row, and then put b=.1 1 1 1 as the first column to the new boxed data. How can I do this easily? Do I have to ravel the whole thing and compute the dimention on my own in order to box it again?
Also, if I want the data i.8 to be 2 rows, do I have to calculate the other dimension 4(=8/2) in order to form a matrix 2 4$i.8? And then box it ;/2 4$i.8? Can I just specify one dimension, either the number of row or columns and ask automatic boxing or forming the matrix?
The answer to your question will involve learning about &. , the 'Under' conjunction, which is tremendously useful in J.
m
┌─┬─┬─┐
│1│1│2│
│2│2│4│
│3│9│6│
└─┴─┴─┘
a=. 1 2 3
b=. 1 1 1 1
So we want to add each item of a to each boxed column of m . It would be perfect if we could unbox the column using unbox(>), append the item of a to the column using append (,) and then rebox the column using box (<). This undo, act, redo cycle is exactly what Under (&.) does. It undoes both its right and left arguments ( m and a ) using the verb to its right, then applies the verb to its left, then uses the reverse of the verb to its right on the result. In practice,
m , &. > a
┌─┬─┬─┐
│1│1│2│
│2│2│4│
│3│9│6│
│1│2│3│
└─┴─┴─┘
The fact that a is unboxed when it was never boxed to begin with means that it is not changed, while m is unboxed before (,) is applied to each a . In fact this is used so often in J that &. > is assigned the name 'each'.
m , each a
┌─┬─┬─┐
│1│1│2│
│2│2│4│
│3│9│6│
│1│2│3│
└─┴─┴─┘
Prepending a boxed version of b requires first giving it an extra dimension with laminate (,:) then transposing (|:) b and finally boxing (<) the result. The step of adding the extra dimension is required because transposing swaps the indices and b start as a one-dimensional list.
(<#|:#,:b)
┌─┐
│1│
│1│
│1│
│1│
└─┘
The rest is easy as we just use append (,) to join the boxed b with (m, each a)
(<#|:#,: b) , m , each a
┌─┬─┬─┬─┐
│1│1│1│2│
│1│2│2│4│
│1│3│9│6│
│1│1│2│3│
└─┴─┴─┴─┘
Brackets around (<#|:#,: b) are necessary to force the correct order of execution.
For the second question, you can use i. n m to create a n X m array, which may help.
i. 4 2
0 1
2 3
4 5
6 7
i. 2 4
0 1 2 3
4 5 6 7
but perhaps I am misunderstanding your intentions here.
Hope this helps, bob
append a (with rank): ,"x a
You can simply append (,) a to your unboxed (>) input but you have to be careful with the append rank. You want to append each "item" of a, so you have right rank of "0". You want to apend to a 2-cell so you have a left rank of "2". Therefore, the , you need has rank "2 0. After the append, you rebox your data to a 2-cell with <"2.
<"2(>in)(,"2 0) a
┌─┬─┬─┐
│1│1│2│
│2│4│4│
│3│9│6│
│1│2│3│
└─┴─┴─┘
prepend b: b,
If your b has the right shape you prepend it with b,. The shape you seem to use is (boxed) 4 1:
b =: < 4 1$ 1
┌─┐
│1│
│1│
│1│
│1│
└─┘
b,in
┌─┬─┬─┬─┐
│1│1│1│2│
│1│2│4│4│
│1│3│9│6│
│1│1│2│3│
└─┴─┴─┴─┘

J # not working as expected

I'm just starting to try to pick up the J language, and am confused by the following:
1 2 +/#{ i.4
1 2
+/ 1 2 { i.4
3
when in the documentation for # it says: "x u#v y ↔ u x v y"
I assume I'm just mistaking one part of speech for another, but can't figure it out
also, how do I tell what type of speech a name is?
NB. u b. 0 returns the rank of u
NB. the rank of a verb determines the arguments it applies to at a time
NB. monadic + y applies to atoms; dyadic x + y applies to pairs of atoms
+ b. 0
0 0 0
NB. monadic +/ y and dyadic x +/ y apply to anything (unbounded rank)
+/ b. 0
_ _ _
NB. monadic { y applies to arrays of atoms;
NB. dyadic x { y applies to pairs of atoms and anything
{ b. 0
1 0 _
NB. u # v has the rank of v
+/#{ b. 0
1 0 _
NB. since 1 2 { i.4 returns atoms at a time, +/ works on atoms
+/"0 [ 1 2 { i.4
1 2
NB. u #: v has unbounded rank
+/#:{ b. 0
_ _ _
NB. +/ applies to all of 1 2 { i.4 at once
+/"_ [ 1 2 { i.4
3
NB. mechanical translation to tacit form
13 : '+/ x { y'
[: +/ {
Wikipedia has, in my biased opinion, a decent writeup on rank, and what it means in the context of the different parts of "speech" in J.
But to answer the original question, J's trace facility can be useful for understanding how its grammar works:
require'trace'
trace '1 2 +/#{ i.4'
This will take you step by step through the parsing process, showing the words being consumed by each production rule and the result each generates.
Ah, I think I may have figured it out, I need to use #: instead of #
1 2 +/#:{ i.4
3
which is what I wanted. Guess I'm going to have to read up some more on rank, which is the only difference between # and #:

Resources