In Part 1, we defined a place-of macro and a value-of function. The code from Part 1, as originally written, was not an importable module. I have modified the code from Part 1 to be portable.
;; Module from Part 1
;; Save this code into a file called part1.hy and then use it with:
;; (import [part1 [value-of]])
;; (require [part1 [place-of]])
(setv +place-dir+ ".places/")
(defmacro/g! place-of [code]
`(do
(import [hashlib [md5]] os pickle)
(setv ~g!type-dir (os.path.join ~+place-dir+ (str (type '~code))))
(if-not (os.path.exists ~g!type-dir)
(os.mkdir ~g!type-dir))
(setv ~g!place
(os.path.join
~g!type-dir
(+ (.hexdigest (md5 (.encode (str '~code))))
".pickle")))
(if-not (os.path.exists ~g!place)
(with [f (open ~g!place "wb")]
(pickle.dump (eval '~code) f)))
~g!place))
(defn value-of [place]
(import os pickle)
(assert (= (type place) str)
(+ (str place) " is not a place"))
(if-not os.path.exists
(raise (FileNotFoundError (+ "Could not find place " place))))
(with [f (open place "rb")]
(pickle.load f)))
The value-of function works fine. The place-of macro has no way to accept parameters. We will define a macro for constructing place-based functions, which can accept parameters.
defnp
Hy's built-in function declaration macro is defn. We will call our place-based function declaration macro defnp. Our place-based function will hash its own code as before. We also need a unique identifier for its parameters. In data science, the values of our parameters are often gigantic. It takes a long time to hash a big data structure. Hashing big data structures takes many computations. The whole purpose of a persistent memoization system is to reduce how many computations we have to perform. Passing values to our place-based function is a wastes compute. Instead we pass places, which are always easy to hash. A place-based function takes places as parameters and then returns another place.
In Part 1, we defined a
place-of
macro and avalue-of
function. The code from Part 1, as originally written, was not an importable module. I have modified the code from Part 1 to be portable.The
value-of
function works fine. Theplace-of
macro has no way to accept parameters. We will define a macro for constructing place-based functions, which can accept parameters.defnp
Hy's built-in function declaration macro is
defn
. We will call our place-based function declaration macrodefnp
. Our place-based function will hash its own code as before. We also need a unique identifier for its parameters. In data science, the values of our parameters are often gigantic. It takes a long time to hash a big data structure. Hashing big data structures takes many computations. The whole purpose of a persistent memoization system is to reduce how many computations we have to perform. Passing values to our place-based function is a wastes compute. Instead we pass places, which are always easy to hash. A place-based function takes places as parameters and then returns another place.