Live data from Hacker News

J Notation as a Tool of Thought

hillelwayne.com

21–30 of 60 posts

Re: J Notation as a Tool of Thought

#21

Earlier quoted context omitted.

I have want to chime in. Agree, it is great that ideas from APL have made it into the language... But there is, fortunately, a long and fruitful path still to explore... I love that J is like an alternative path to functional approaches like Haskell and how it plays in terms of providing expressive power. Still, I will not create code in J that is maintained jointly with other users from other domains (which is the c…

I like how APL made it into Common Lisp wholesale . There's a library that compiles APL to Common Lisp, allowing you to mix APL and Lisp code, working on the same data structures with both languages. https://github.com/phantomics/april Example session I just did, copying APL code from https://aplwiki.com/wiki/John_Scholes%27_Conway%27s_Game_of_... : CL-USER> (april:with-april-context ((:space *lifespace*)) (april:apr…

Regarding the keyboard, I use something like this https://unix.stackexchange.com/questions/547705/finding-apl-... and well, a picture of the mappings, but somehow they kind of end sticking in your head...

Re: J Notation as a Tool of Thought

#22

Earlier quoted context omitted.

I have want to chime in. Agree, it is great that ideas from APL have made it into the language... But there is, fortunately, a long and fruitful path still to explore... I love that J is like an alternative path to functional approaches like Haskell and how it plays in terms of providing expressive power. Still, I will not create code in J that is maintained jointly with other users from other domains (which is the c…

I like how APL made it into Common Lisp wholesale . There's a library that compiles APL to Common Lisp, allowing you to mix APL and Lisp code, working on the same data structures with both languages. https://github.com/phantomics/april Example session I just did, copying APL code from https://aplwiki.com/wiki/John_Scholes%27_Conway%27s_Game_of_... : CL-USER> (april:with-april-context ((:space *lifespace*)) (april:apr…

Beautiful that it can get actually compiled... I dreamt of that, but in particular, with J, it'd be very hard as the actual implementation is data driven, i.e., lexical analysis alone would require building a kind of interpreter for chained operations to work efficiently under all circumstances or compile all possible variants of execution.

Re: J Notation as a Tool of Thought

#23

Earlier quoted context omitted.

Rank Is actually implicitly done by numpy using a mechanism called broadcasting. For example: >>> np.array([10, 20, 30]) + np.array([[1,2,3], [4,5,6], [7,8,9]]) array([[11, 22, 33], [14, 25, 36], [17, 28, 39]]) Sieves exist in numpy, called masks: >>>np.array([10, 20, 30]) > 15 array([False, True, True]) Of course they can be operated on just like any other numpy array. Grades exist in numpy: >>>np.array([5,4,3,2,1])…

> Rank Is actually implicitly done by numpy using a mechanism called broadcasting. Numpy's broadcasting is scalar conformability, to which the rank operator (and general conformability) provides a general case. Example in j: ] x =. i. 2 3 4 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ] y =. i. 3 4 0 1 2 3 4 5 6 7 8 9 10 11 x + y NB. this will error because + expects that, if its arguments' shapes ar…

What is prefix/suffix agreement? Could you give a simple example of why prefix beats suffix?

I'm curious and have never heard these terms before, and googling didn't help.

Re: J Notation as a Tool of Thought

#24
This was a nice tour of how concise J can be. To see more of this stuff I highly recommend the Concrete Mathematics Companion[0], which uses J as an algebraic tool to reason about the correctness of derivations in that excellent book by Knuth.

[0] https://www.jsoftware.com/books/pdf/cmc.pdf

Re: J Notation as a Tool of Thought

#25

Earlier quoted context omitted.

> Rank Is actually implicitly done by numpy using a mechanism called broadcasting. Numpy's broadcasting is scalar conformability, to which the rank operator (and general conformability) provides a general case. Example in j: ] x =. i. 2 3 4 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ] y =. i. 3 4 0 1 2 3 4 5 6 7 8 9 10 11 x + y NB. this will error because + expects that, if its arguments' shapes ar…

What is prefix/suffix agreement? Could you give a simple example of why prefix beats suffix? I'm curious and have never heard these terms before, and googling didn't help.

To broadcast operations (such as addition) between arrays in NumPy, trailing dimensions have to be equal (or be of length 1).

In the example given above the 3D array and 2D array have shape (lengths of dimensions):

   (2, 3, 4)
      (2, 3)
That is - the suffixes do not agree (4 != 3 and 3 != 2) and NumPy raises an error.

However, for the same operation in J the prefixes agree:

   (2, 3, 4)
   (2, 3)
and the addition gives the expected result.

To add the arrays with these shapes in NumPy, one method is transpose each array (reverse order of the dimensions), add these arrays, and then transpose back:

  (a.T + b.T).T

Re: J Notation as a Tool of Thought

#26
The article has the footnote

> APL was the first language to use “monad” as a term. The popular FP meaning only appeared thirty years later.

in its, to me odd, use of the word "monad". This is incorrect. The "popular FP meaning" arose because it's a very special case of the standard concept from mathematics [1]. The mathematical terminology harkens back to the 1950s, and thus predates APL.

In Haskell, a monad is precisely a monad in the mathematical sense in the special case of the category of Haskell types (which, due to technical complications isn't exactly a perfect model for the actual Haskell types, but it's pretty close). It thus seems dishonest to me to refer to this use of the word "monad" as somehow being newer than APL's use.

[1] https://en.wikipedia.org/wiki/Monad_(category_theory)

Re: J Notation as a Tool of Thought

#27
I agree with most of this article, except that - for me - grouping by table columns is a more intuitive and flexible way to control subset application than 'rank'.

k9 is in development, but blending k7 and k9 we'd get something like:

   t: [[]sensor:  1 2 1 2 1 2
         day:     1 1 2 2 1 1
         reading: 1 2 3 4 5 6]
  
   0 1 1 0 * select by sensor, day from t
  sensor day|             
  ------ ---|----------------
  1      1  |[[]reading: 0 0]
  1      2  |[[]reading: ,3]
  2      1  |[[]reading: 2 6]
  2      2  |[[]reading: ,0]

Re: J Notation as a Tool of Thought

#28
post #8
post #6

Earlier quoted context omitted.

Comparing numpy to J is like comparing a dirty rag to a designer suit. The examples you've listed are trivial; the power of J and other array languages cannot be appreciated from afar. The philosophy behind array languages runs much deeper than adding two arrays or transposing matrices.

Can you give an example of something that can be done in J that can't be done easily in numpy?

It is not about "cannot be done". Most high-level languages are Turing complete, hence every program in one can be written as some program in another.

The real clincher is expressiveness: shorter code is better, modular code is better, and languages which avoid unnecessary repetitiveness of boiler plate code is better. Different languages provide advantages along one or more of these parameters.

Re: J Notation as a Tool of Thought

#29
post #28
post #8

Earlier quoted context omitted.

Can you give an example of something that can be done in J that can't be done easily in numpy?

It is not about "cannot be done". Most high-level languages are Turing complete, hence every program in one can be written as some program in another. The real clincher is expressiveness: shorter code is better, modular code is better, and languages which avoid unnecessary repetitiveness of boiler plate code is better. Different languages provide advantages along one or more of these parameters.

So can you give an example of something that can be expressed simply in APL/J/K that can't be expressed simply with numpy?

And to be clear I don't think "less characters" makes the expression more simple. Maybe "less statements" or "less operators"

Re: J Notation as a Tool of Thought

#30
post #25

Earlier quoted context omitted.

What is prefix/suffix agreement? Could you give a simple example of why prefix beats suffix? I'm curious and have never heard these terms before, and googling didn't help.

To broadcast operations (such as addition) between arrays in NumPy, trailing dimensions have to be equal (or be of length 1). In the example given above the 3D array and 2D array have shape (lengths of dimensions): (2, 3, 4) (2, 3) That is - the suffixes do not agree (4 != 3 and 3 != 2) and NumPy raises an error. However, for the same operation in J the prefixes agree: (2, 3, 4) (2, 3) and the addition gives the expe…

Thinking about these as a "verbose imperative language" programmer, I'd say suffix agreement seems to make more sense to me at first glance, and I'd like to hear more about why it might be worse.

For why I think it makes sense: I think of multidimensional arrays as being arrays of arrays, and "normal" index lookup operating on the first dimension. If I have a

    float[100][3]
in some context I might think of it as 100 vec3s, and I might want to do some vec3 operation on each of them. I might want to dot them all with my some other vector, or add them all to some other vector. I almost never have 100 scalars and want to apply one scalar to all elements of the corresponding vec3.

But I guess maybe this is all widely agreed on, and maybe the contentious part is just index order? Like, maybe you'd say "100 vec3s" is actually

    float[3][100]
in which case prefix agreement would make more sense.
Post reply on HN