Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I love explaining +/%#

Based on the one thing I remember in APL I'm guessing the first two characters are "sum over some data structure" and the data structure is what the next two mean. What does it mean entirely?





avg=: +/ % #

+/ sums the items of the array.

# counts the number of items in the array.

% divides the sum by the number of items.


delightful, ty. How does it handle empty arrays? Throw? Average is zero? Average is infinity?

Average is zero

     empty =. 0$0 NB. zero length array
     +/empty
  0
     #empty
  0
     0%0
  0

Further validation for n / 0 = 0 in Elm and Pony and a couple other places! TYSM

I'd call that code obfuscation.

   a.sum() / a.count()
you would not need an explanation.

There's an initial learning curve as there is with any new programming paradigm (which everyone who works exclusively in C-like languages forgets that they paid a long time ago) but there are only something like 100 primitives, and then once you understand how they interact, the world opens up and the volume of a sphere being

Vs=: 4r3p1"_ * ] ^ 3:

just reads normally. It's been over ten years since I did anything in J and I can almost explain that now...


> Vs=: 4r3p1"_ * ] ^ 3:

What's the "_ for?


Vague recollection, could be wrong -- in J, you can apply a "rank" to verbs, which determines how the verb applies to its arguments. So for example, if we define that average verb:

avg =: +/%#

then we can say

avg 2 4

and get 3

We can also say:

x =: i.2 3 4

and that makes an array like so:

   0  1  2  3
   4  5  6  7
   8  9 10 11

   12 13 14 15
   16 17 18 19
   20 21 22 23
And then we can do things like:

      avg"1 x
   1.5  5.5  9.5
   13.5 17.5 21.5
      avg"2 y
   4  5  6  7
   16 17 18 19
      avg"3 y
   6  7  8  9
   10 11 12 13
   14 15 16 17
In this instance I believe the "_ is just giving back 4r3p1 = 4.18879 for each of the arguments handed to the rest of the verb. This is one of those things that is second nature once you internalize J, but so so foreign until you do.

Right, thank you!

I recognised the " as rank but got confused by the _ reading https://code.jsoftware.com/wiki/Vocabulary/under, it seemed to be 'rank negative' and didn't see what that did.

> second nature once you internalize J, but so so foreign until you do.

Indeed!


> I'd call that code obfuscation.

we call them "trains". since this one has a descriptive name, `avg a`, is not cryptic at all. just a bit fewer of absolutely meaningless parens and duplication.

but it doesn't end there:

1. imagine you wanted a moving average instead. i need to change one character in this train to get `mavg`. what would you need to do?

2. imagine you want to compute moving averages for each of 1000 arrays using both instruction-level parallelism and all available cores? while you'd be writing your unobfuscated code for that, i'd be done way before you're back from your lunch break. in two keystrokes.

once you'd be done with your solution, there would be no need to discuss productivity, or so i hope, but to discuss performance would be interesting.


K et al. can look like that, but this example doesn't require any explanation to someone who has any familiarity.

the thing about tacit programming is that it wouldn't use 'a' in the above. if you wrote average in j without it being tacit, it would probably be more readable to you. the question of how to thread data around without naming it is an interesting one to me.

> without it being tacit, it would probably be more readable

definitely. tacit can be taken a bit too far sometimes, but when a certain discipline is observed (just like in any language, really) it is no less readable than... let me see. oh, lets take some typical pandas/polars heroics - no, those things don't give me brain aneurisms and not too shocking either. they just make wanna vomit no less than the poor people who were forced to write it and contemplate what they've done.

> tacit is "bad"

not at all. it takes one time to see how avg looks in explicit notation to understand that the idea of trains is totally justified.

> the question of how to thread data around without naming it is an interesting one to me.

good question. see above - yes indeed, things can be taken to extremes. when an apl/k program is a oneliner 80 chars long, that's just not cool. there is no reason not to break it down a bit into moving parts with names (and ample space on the right margin for annotations). in no way APL and friends are somehow exempt from commenting their code. but that's not really endemic to array languages, you'd agree.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: