1. 23
  1.  

  2. 13

    This one feels like he forgot to keep going. The explanation of hooks and forks is fairly lucid and useful, but he forgets to justify or even mention the apparent thesis: how the qualities that lead to J being extremely difficult to read actually lead (allegedly) to some other level upon which it’s easier to understand than otherwise.

    1. 6

      Author of OP here. Did you continue reading past the newsletter signup block? I should probably make that less conspicuous. If you read to the bottom and still feel like I left you hanging, I apologize for not being clear. My goal was to explain that verbs and hooks can be read linearly as sentences, rather than having to consciously consider argument routing through each of the hook/verb’s verbs.

      1. 3

        I read until the paragraph after tacit, and I agree with /u/zdsmith here. If your goal was to explore hooks and forks, perhaps it would have been better to title the article something different.

        1. 1

          Wow, yeah. I didn’t know there was more article. My eye immediately stops when it hits that kind of thing. My apologies for jumping the gun, though yes, as you say, it may also be a lesson in growth hacking :)

      2. 11

        This is interesting! In the language of functional programming, one way I look at this is that J automatically lifts functions into what Haskell considers to be the applicative functor of single-argument functions. What the OP writes in J as

        mean =: +/ % #
        

        can be written in Haskell as

        mean = (/) <$> sum <*> length
        

        which basically means “divide the result of sum by the result of length, with the argument kept implicit throughout.” It’s pretty cool that it’s implicit in J (a lot of powerful language features amount to implicitly lifting code into monadic / applicative contexts; see exceptions, coroutines, continuations, backtracking, and even state and IO in a fundamental sense), and it’s also pretty cool that Haskell can model it as a library feature!

        Pedantic note: strictly speaking, to make the types in the above code work out, you have to replace length with (fromIntegral <$> length) or equivalently (fromIntegral . length), but that’s incidental.