DEV Community

Pete Corey
Pete Corey

Posted on • Originally published at petecorey.com on

Obverse and Under

#j

I previously wrote about plotting an “amazing graph” using the J programming language. The solution I landed on looked something like this:

require 'plot'
f =: ] - [: #. [: |. #:
'type dot' plot f"0 p: i. 10000

Our verb, f, is taking a very explicit approach by making judicious use of “capped” ([[:](https://www.jsoftware.com/help/dictionary/d502.htm)) verb trains. We’re essentially saying that f is (=:) the given number ([]](https://www.jsoftware.com/help/dictionary/d500.htm)) minus (-) the base two (#.) of the reverse (|.) of the antibase two (#:) of the given number.

Several members of the J community pointed out to me that this verb could be simplified with the help of the “under” (&.) conjunction. Let’s dig into what “under” is, and how we can use it.

Under What?

The best way to think about “under” (&.), as explained by the NuVoc page on “under”, is to think in terms of domains and transformations in and out of those domains.

Verb v defines a transformation of the argument(s) (x and) y into the v-domain. Next, verb u operates on the transformed argument(s). Lastly the result is transformed back from the v-domain to the original domain.

In our example, the domain of our input is base ten, but the transformation we want to apply (reversal) needs to happen in the base two domain. “Under” (&.) can be used to transform our input into base two (#:), apply our reversal (|.), and transform the result of that reversal back to our original base ten domain with the obverse, or opposite, of our base two verb, anti base (#.):

f =: ] - |. &. #:

Notice that we’re not explicitly stating how to transform the result of our reversal back into our original domain. J knows that the obverse of #: is #., and automatically applies it for us.

Out of the box, J comes with many obverse pairings. “Open” (>), for example, is the obverse of “box” (<), and visa versa. This pairing is especially useful when applying transformations to boxed values:

1+&.>1;2;3
┌─┬─┬─┐
│2│3│4│
└─┴─┴─┘

Check out a full listing of obverse pairs at the end of this Shades of J article.

Inferred Obverses

Even compound verbs built up of verbs with well-defined obverse pairings can be used with “under” (&.). J will correctly infer and apply the compound obverse without any intervention or instruction.

For example, if we wanted to unbox a list of values and then work with them in the “square root domain” (whatever that means), we could do something like this:

1+&.([:%:>)1;2;3
┌────────────────┐
│4 5.82843 7.4641│
└────────────────┘

J takes each value, opens it and finds its square root ([:%:>), adds one to the result, and then squares and boxes up ([:*:<) the incremented value.

Explicit Obverses

Even more interestingly, if an obverse pairing isn’t defined or inferable for a given verb, J lets us define our own pairing using the “obverse” (:.) verb.

As an example, imagine that we have a JSON string holding an array of values. We want to parse our string, perform some operation on those values, and then serialize the resulting list back into JSON.

We can use the dec_json and enc_json verbs provided by the convert/json package, and tell J that the obverse of dec_json is enc_json:

json =: dec_json :. enc_json

Running dec_json on a JSON array like '[1, 2, 3]' will return a list of boxed numbers, so we’ll want to open each of these boxes, perform our operation, and box the results back up. This sounds like another job for “under” (&.):

transform =: 1&+&.>

All together, we can perform our transform “under” (&.) the json domain:

transform &. json '[1, 2, 3]'
[2,3,4]

And our result is the JSON string '[2,3,4]'!

“Under” is definitely a very powerful conjunction, and I can see myself using it extensively in the future. Thanks to everyone in the J community who was kind enough to point it out and teach me something new!

Top comments (0)