Imagine you have a function called g
g(5) #returns 10
Now imagine you have another function which undoes whatever happened in g.
undo-g(10) #returns 5
Not too impressive on the face of it. You could guess that g just multiplies by 2 and undo-g divides by 2. The J language comes with some of these built in. Which it calls obverse functions.
4 + 4 8 4 +^:_1 (4) 0In this function +^:_1 effectively means apply the + function -1 times. You could do it twice:
4 +^:_2 (4) _4 (In J _4 means -4)Seem crazy? Stay with it...
How many times do you see this sort of pattern in your code?
OpenFile ReadData CloseFile OpenSocket SendData CloseSocketLook familiar? Well, because J has the idea of obverse functions you get a lovely little syntax that J calls Under which covers this pattern. In J it looks like this
f&.g xWhich means apply g to x. Then apply f. Then apply the inverse of g.
obverse(func(verb(x))) #J calls functions verbsThe J documentation lists loads of cool definitions you can build using under.
Here's the idea in clojure using the under pattern to construct a new definition of multiplication and addition.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;Will Suffer from rounding errors - but ok for an example | |
(defn under [verb, obverse, func x y] | |
(obverse (func (verb x) (verb y)))) | |
(defn log [x] | |
(Math/log x)) | |
(defn exp [x] | |
(Math/exp x)) | |
(defn my-multiply [x y] | |
(under log exp + x y)) | |
(defn my-add [x y] | |
(under exp log * x y)) | |
(println (my-multiply 2 3)) | |
(println (my-multiply 2 2)) | |
(println (my-add 1 2)) | |
(println (my-add 3 3)) | |
(println (my-add 3 4)) |