Search code examples
j

Assigning an inverse function at definition time


I've written a little toy hexadecimal converter; I have an encode and a decode function:

encode16 =: { & '0123456789ABCDEF' @ ((6 $ 16) & #:)
decode16 =: (16 & #.) @ ('0123456789ABCDEF' & i.)

I would like them to be inverses of each other, so I can write code and see something like this:

   119&+ &. decode16 '03A8D8'
03A94F

My first guess was to add this:

encode16 =: encode16 :. decode16

This creates recursion, so I settled on this instead:

encode16basic =: { & '0123456789ABCDEF' @ ((6 $ 16) & #:)
decode16basic =: (16 & #.) @ ('0123456789ABCDEF' & i.)

encode16 =: encode16basic :. decode16basic
decode16 =: decode16basic :. encode16basic

Is this the typical way to handle inverse functions? Do people typically assign inverse functions at definition time? And is it really necessary to assign the inverse to both the encode and decode functions? It seems like it is, since the documentation doesn't say otherwise.


Solution

  • One option for defining them might be:

       encode16=: ({&'0123456789ABCDEF'@((6$16)&#:)) :. ((16&#.)@('0123456789ABCDEF'&i.))
       decode16=: encode16^:_1
    
       119&+&.decode16 '03A8D8'
    03A94F
    

    You can inspect the obverse of a verb as follows:

       decode16 b. _1
    encode16
       encode16 b. _1
    16&#.@('0123456789ABCDEF'&i.) :.({&'0123456789ABCDEF'@(16 16 16 16 16 16&#:))
    

    Check out the wiki page for Obverse for more detail.