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.
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.