I'm rather new to the J programming language and I have a question about equivalent tacit expressions in J.
I found two lines of J that were equivalent, but the conjunction in the code (^:)'s arguments were switched using the bracket operators.
I was mainly wondering how this expression:
u ^: x y
is equivalent to this expression:
x u #] ^: [ y
I would appreciate any J programmers to explain how the two are equivalent.
I think that the way to look at this is to look at the tacit expression u#] ^: [ as a verb formed by the conjunction ^: between the two verbs u#] and [ . u#] is going to take the right argument y (to the exclusion of the left argument) and apply the monadic form of u to y. [ is going to use the left argument x as the value that will provide the number of repetitions of u as an operator of ^: .
For the explicit version, u ^: x y replaces the [ and ] verbs with their associated left and right arguments and since x is an operator of ^: , u ^: x is effectively a monadic verb with y as its argument.
Let's set
a=. 3
b=. 4
vb =. +: NB. double
vb ^: a b
32
a vb #] ^: [ b
32
a (vb #] ^: [) b NB. expression within parenthesis is clearly a verb
32
Related
I have seen Haskell code like this:
infix 4 ~=
(~=) :: Double -> Double -> Bool
x ~= y = abs (x-y) < epsilon
where epsilon = 1 / 1000
Despite that I know what this code is doing, I would like to know what infix 4 means.
That is a fixity declaration:
A fixity declaration gives the fixity and binding precedence of one or more operators.
In particular the infix part of infix 4 ~= means that the operator ~= is not right or left associative, so x ~= y ~= z is not a valid expression.
And the precedence is 4 which means that it binds tighter than for example &&, so x ~= y && z parses as (x ~= y) && z, but less tight than for example ++, so x ~= y ++ z parses as x ~= (y ++ z) (but that fails to type check). In that respect it is the same as comparison operators like ==, so also x == y ~= z will give a parse error.
Here is a table of the fixities of standard operators (from the Haskell 2010 report linked above):
Precedence
Left associative
Non-associative
Right associative
9
!!
.
8
^ , ^^ , **
7
*, /, ‘div‘, ‘mod‘, ‘rem‘, ‘quot‘
6
+, -
5
:, ++
4
==, /=, <, <=, >, >=, ‘elem‘, ‘notElem‘
3
&&
2
||
1
>>, >>=
0
$, $!, ‘seq‘
I was trying to understand why n + k patterns were banned in Haskell. A famous post on StackOverflow gives an example of a function as follows:
f 0 = 0
f (n + 5) = 5
Haskell shows an error while matching f 1, f 2, f 3, f 4.
I cannot understand why (-1) cannot be matched with n. Firstly, I thought that integers only contain non-negative literals (0,1,..), but Haskell's definition of Int type includes negative literals.
Why can't -1 be matched? That's simply how n+k patterns were defined, presumably because it seemed like a good idea at the time. It's natural to use induction for natural numbers, so why not define our cool n+k patterns to work for naturals? From the Haskell report:
Matching an n+k pattern (where n is a variable and k is a positive integer literal) against a value v succeeds if x >= k, resulting in the binding of n to x - k, and fails otherwise. Again, the functions >= and - are overloaded, depending on the type of the pattern. The match diverges if the comparison diverges.
The fact that you found this surprising is probably one reason why n+k patterns were removed. Another is that there's no need for them: you can easily translate any n+k pattern into a pattern not using this feature.
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'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).
I am new to Haskell and this mixture of Infix and Prefix notation is confusing me.
What is the difference between an operator like '+' and a function like head? How do I write an operator 'c' which does this 1 c 1 = 2?
I found this definition a ! b = True. How does Haskell know that I am defining ! and not a function a?
In Haskell, to create an operator you must use the following "operator symbols":
! # $ % * + . / < = > ? \ ^ | : - ~
So, for example
($$$) a b = a+b
Defines an operator $$$ which can be used in the expression 1 $$$ 1 to yield a value of 2.
Conceptually, there is no difference between an operator and a function, and you can use backticks or parens to make one work like the other.
EDIT:
Just so it is 100% clear, let me demonstrate turning a function into an operator and vice versa:
For the operator '+', the following two expressions are equivalent:
1+1
(+) 1 1
Similarly, for a function, the following two expressions are equivalent:
foo 1 2
1 `foo` 2
Haskell knows you aren't defining a function called a because the ! wouldn't be valid in a function argument list. In order to use the ! not as an operator but just as a normal identifier, you need to enclose it in parentheses. If you wrote instead a (!) b = True, then it would define the function a :: t -> t1 -> Bool.
This is the entire difference between operators and normal identifiers in Haskell — there are special syntax rules for operators that allow them to be used infix without backticks. Otherwise, they're just functions.
Really, the only difference is syntax. Function names begin with a lower-case letter, followed by a series of alpha-numeric characters. Operators are some unique sequence of the typical operator characters (+ - / * < > etc.).
Functions can be used as operators (in-fix) by enclosing the function name in ` characters. For example:
b = x `elem` xs -- b is True if x is an element in xs.
Operators can be used as functions (pre-fix) by enclosing the operator in parens. For example:
n = (+) 2 5 -- n = 2 + 5, or 7.