I'm trying to get my head around J. In the easy-j.pdf (available here; page 19) introduction there is this hook:
ti=.{.(*i.)}. NB. ti=times index generator
ti 2 5 NB. Usage
I understand the previous term: 2(*i.)5 NB. 2 times 0 1 2 3 4
I can understand/imagine that }. takes the last element from the argument-list (above 2 5) to create (*i.)5. But what makes it clear/obvious that somehow the argument-list is also passed to {. to retrieve the 2 (in my current understanding the argument is already used by }.)?
I hope this question is understandable to J experts.
ti is actually a monadic fork with three tines that are all verbs. The way that this is executed is that the two outside tines {. and }. are executed on the argument 2 5 and the result is fed as left and the right arguments of the middle tine (* i.), which is itself a hook.
In J fork operations are often symbolized with f, g and h standing for verbs and x and y representing left and right arguments and forks are evaluated like this:
(f h g) y <-> (f y) h (g y) NB. <-> is a meta symbol for equivalency - not J symbols
In this case f y is {. 2 5 and g y is }. 2 5
{. 2 5
2
}. 2 5
5
The middle tine of a fork is always dyadic because it is fed from the two outside tines and the construct for the dyadic hook (* i.) in the centre is
x (f g) y <-> x f (g y)
2 (* i.) 5 NB. 2 * (i. 5)
0 2 4 6 8
Related
With a simple Haskell adder function
addTwo:: Num a => a -> a -> a
addTwo a b = a + b
and following expressions
addTwo 4 5 -- yields 9
4 `addTwo` 5 -- yields 9
(`addTwo` 4) 5 -- yields 9
I understand the first two expressions. However, how does the third one work? Does the expression (`addTwo` 4) become a function of one argument? What is the general principle here?
Does the expression (`addTwo` 4) become a function of one argument?
Yes, this is exactly what happens. This is exactly the same as any other operator section like (+4), just using backticks instead of some other infix operator. In general, (a `op`) is the same as \x -> a `op` x, while (`op` a) is the same as \x -> x `op` a.
Recently I have been learning about compositions in haskell and am now a bit confused concerning this example.
(const . min) 3 0 4
As a result I get 3, so internally it must be computed like:
const (min 3) 0 4
But I thought since min takes two arguments, it should look like this:
const (min 3 0) 4
So apparently the composition only takes this one argument, in this case 3, instead of all the arguments for min like I expected it to. Does that mean compositions only take one argument per default or what am I not getting here?
You can answer your question by manually evaluating the initial expression.
(const . min) 3 0 4
⇒ (\x -> const (min x)) 3 0 4 * defn of (.)
⇒ (const (min 3)) 0 4 * function application
⇒ ((\x y -> x) (min 3)) 0 4 * defn of const
⇒ (\y -> min 3) 0 4 * function application
⇒ (min 3) 4 * function application
⇒ 3 * because 3 is less than 4
It is worth noting that function application is left-associative, so, f x y means the same as (f x) y.
It is also worth noting that \x y -> z means the same as \x -> \y -> z.
How can I write the frame function tacitly? (From "Learning J" Ch 7)
I'm using the f x g y = x f#:g y composition scheme from Ch 8 , but it's not working. My guess is because <" has no natural rank?
x=.1
y=.i.2 3 4
f=.$
g=.<"
frame_e=.4 :'f x g y'
frame_t=.f#:g
x frame_e y NB. -> 2 3, which is the x-frame of y
x frame_t y NB. -> domain error
NB. No natural rank
g b.0 NB. -> syntax error
0 g b.0 NB. -> 0 0 0
I confirmed the pattern works as I expected with other functions.
x=.1
y=.i.2 3 4
f=.+/
g=.*
f x g y NB. -> equiv of 12+2*i.3 4
x f#:g y NB. -> same
Tacitly, I would do it using
framet=. {. $
2 framet i. 2 3 4
2 3
but that does not really get to the root of your question, does it?
The issue is really the way that g is defined:
g=.<"
This does not make g a verb, but an adverb. It does use the x in the explicit definition to create a verb, but it needs to do this before it uses that verb to evaluate y. As far as I know, J does not allow you to stage these processes. As you have seen the pattern does work when f and g are actually verbs.
I find tacit programming elegant, but it can be slower at some things and there are areas where it is limited.
I am hoping that someone can provide a better answer, so that I may learn as well.
I have a code
g :: Int->Int->Int
g x y = x*2 - y
then If i call foldl1 g [4,3,2,1] it returns 15, but i don't get how it returns 15, can anyone explain me why this is the case?
foldl1 first applies the function to the first two elements of the list, then takes the result and applies the function to it and the third element, then takes the result and applies the function to it and the fourth element, then to result and fifth element, then sixth element, and so on until the list ends.
So:
Step 1: g 4 3 = 4*2 - 3 = 5
Step 2: g 5 2 = 5*2 - 2 = 8
Step 3: g 8 1 = 8*2 - 1 = 15
I'm familiar with this way of doing an arithmetic mean in J:
+/ % #
But it's also shown here as
# %~ +/
Are these two versions interchangeable, and if not when should I use one versus the other?
Dyadic ~ reverses the arguments of a verb. x f~ y is equivalent to y f x. You use ~ when you, um, want to reverse the arguments of a verb.
One of its most common uses is for forks and hooks composition. For example, because y f (g y) is (f g) y you can use ((f~) g) y when you need (g y) f y.
In the reverse mean example I don't really see a reason that one way would be more effective than the other (V V V form of fork), but because forks in J can be non-symmetric (in the N V V form) I can see some reasons that reversing the middle tine of the fork would be an advantage. Take for example:
(5 # $) 1 2 3 NB. (N V V) form
3 3 3 3 3
(5 #~ $) 1 2 3 NB. (N V~ V) becomes effectively (V V N)
5 5 5
($ # 5) 1 2 3 NB. (V V N) is a syntax error
|syntax error
| ($#5)1 2 3
Dyadic ~ is the "Passive" adverb, which swaps the left and right arguments. Thus x f~ y is the same as y f x. +/ % # and # %~ +/ are equivalent. 2 % 5 gives you 0.4, but 2 %~ 5 gives 2.5.
Among the places this can be handy is checking the results of a line you are working with. While you would presumably be testing something more complicated, you can check yourself by repeating your last line and just adding to the left without rearranging anything or adding parentheses.
string =. 'J is beyond awesome.'
'e' = string
0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0
string #~ 'e' = string
eee
The monadic ~ is the "Reflex" adverb, which causes the modified verb to operate as a dyad, duplicating the single argument for both left and right. While this is another shortcut to arranging your arguments, it is quite different from the dyadic ~. *~ 4 is 16, because you are multiplying y by itself (y * y).