Yes, memoized pure functions are commonly referred to as pure. This is especially common in languages like Haskell, in which memoized, lazily-evaluated, immutable results are a built-in feature.
There is one important caveat: the memoizing function must be thread-safe, or else you might get a race condition when two threads both try to call it.
One example of a computer scientist using the term “purely functional” this way is this blog post by Conal Elliott about automatic memoization:
Perhaps surprisingly, memoization can be implemented simply and purely functionally in a lazy functional language.
There are many examples in the peer-reviewed literature, and have been for decades. For example, this paper from 1995, “Using Automatic Memoization as a Software Engineering Tool in Real-World AI Systems,” uses very similar language in section 5.2 to describe what we would today call a pure function:
Memoization only works for true functions, not procedures. That is, if a function’s result is not completely and deterministically specified by its input parameters, using memoization will give incorrect results. The number of functions that can be memoized successfully will be increased by encouraging the use of a functional programming style throughout the system.
Some imperative languages have a similar idiom. For example, a static const
variable in C++ is initialized only once, before its value is used, and never mutates.
funcx(){sleep(cached_time--); return 0;}
returns the same val every time, but will perform differently