A few important bits this left out (as far as I read, which wasn't too far). Note: I am not a J expert, just a dabbler.
J's tacit syntax can generally transparently take either a single argument on the right, or two arguments, one on the left and one on the right.
In addition to the fork described in the article, J defines a "Hook" for two verbs (instead of the fork's three). A hook applies the right verb to the right argument, then applies the left verb with the original argument on the left and the result from the right verb on the right. Meaning:
this gets the largest item from a list >./
this divides the left by the right %
so this scales every item in a list, so the largest becomes 1 and everything else becomes its ratio to the largest: %>./
J allows arbitrarily long strings of verbs: these get forked and hooked until you go insane trying to track it all in your brain.
Defining a function longer than a fork and using the same code inline can (often?) not give the same results. I think that's why the caps are needed in the magnitude function in the article.
I think the article is missing a trick on the magnitude-of-a-vector bit: J has a marvelous conjunction called "under" which, when applied to two verbs, first applies the first (right) verb, then applies the second verb to the result, and then unapplies the first verb.
So when you have the need to "sqrt the sum of the squares" you should immediately be noticing that sqrt and square are opposites, and be thinking "under".
Under is &.:
Sum is +/
Square is *:
So magnitude can be expressed more succinctly (and I think more idiomatically, but again I'm not an expert) as:
Thanks! I haven't touched J in about ten years -- and I never used dissect -- and I never did anything serious in it, just about thirty project euler problems for fun.
Fascinating article – a great example of J's array-processing power for concise, performant geometric computation.
It got me thinking about how different paradigms could complement this. I've been working on a Python project[0], which is a framework for quaternion-driven traversal of tree-like structures based on orientation rather than just position or order.
Essentially, J handles the low-level "how" of vector math at scale, while SpinStep-like concepts could provide a higher-level, more semantic "what" and "why" for decisions driven by explicit orientation sets and angular relationships.
It's an interesting thought experiment on combining the raw power of array languages for geometry with more specialized frameworks for orientation-based reasoning.
J's tacit syntax can generally transparently take either a single argument on the right, or two arguments, one on the left and one on the right.
In addition to the fork described in the article, J defines a "Hook" for two verbs (instead of the fork's three). A hook applies the right verb to the right argument, then applies the left verb with the original argument on the left and the result from the right verb on the right. Meaning:
J allows arbitrarily long strings of verbs: these get forked and hooked until you go insane trying to track it all in your brain.Defining a function longer than a fork and using the same code inline can (often?) not give the same results. I think that's why the caps are needed in the magnitude function in the article.
I think the article is missing a trick on the magnitude-of-a-vector bit: J has a marvelous conjunction called "under" which, when applied to two verbs, first applies the first (right) verb, then applies the second verb to the result, and then unapplies the first verb.
So when you have the need to "sqrt the sum of the squares" you should immediately be noticing that sqrt and square are opposites, and be thinking "under".
So magnitude can be expressed more succinctly (and I think more idiomatically, but again I'm not an expert) as:magnitude =: +/&.:*:
magnitude 3 4
magnitude 3 4 5J comes with a Qt IDE, which has a function "dissect" that displays a graphical parse tree of an expression.
load 'debug/dissect'
dissect '(+/ % #) ? 10 $ 100'
It got me thinking about how different paradigms could complement this. I've been working on a Python project[0], which is a framework for quaternion-driven traversal of tree-like structures based on orientation rather than just position or order.
Essentially, J handles the low-level "how" of vector math at scale, while SpinStep-like concepts could provide a higher-level, more semantic "what" and "why" for decisions driven by explicit orientation sets and angular relationships.
It's an interesting thought experiment on combining the raw power of array languages for geometry with more specialized frameworks for orientation-based reasoning.
[0] https://github.com/VoxleOne/SpinStep
Would have been interesting to see it deal with multiple different objects with different materials, the recursion and such.
Guess it shouldn't take that much to turn it into something like SmallPT.
[1]: https://kevinbeason.com/smallpt/