In my Lisp-esque language I use a temporary macro to automate the creation of some similar standard library procedures. This happens at runtime in the stdlib source file that is loaded:
# Define procedures named int? float? etc that test the type of a value.
(def def-type-predicate (mac (type-name)
`(def ,(string-to-symbol (join "" $type-name "?"))
(proc (x) (eq? (type x) ',type-name)))))
(def-type-predicate int)
(def-type-predicate float)
(def-type-predicate bool)
(def-type-predicate string)
(def-type-predicate symbol)
(def-type-predicate file)
(def-type-predicate nil)
(def-type-predicate pair)
(def-type-predicate procedure)
(def-type-predicate macro)
(zap def-type-predicate)
The crucial thing about what happens there being that the (def foo? ...) value produced by each macro invocation then gets evaluated in the root/top-level environment and so results in a "global" procedure definition. Using them:
But it's nice to have single-parameter ones for FP list stuff. I suppose that 2-parameter version could have their order swapped and do partial application on top of it.
Anyway, was just sharing something I had fun making. No language wars intended.