D has a keyword "pure", it's pretty useful. It also is part of the type signature so you can take a pointer to a pure function as a library.
If you don't want to use the GC it is customary to use a pure wrapper around malloc (even though you theoretically shouldn't, it works fine in practice).
https://dlang.org/library/core/memory/pure_malloc.html
https://run.dlang.io/is/xB0Qeu this RPN calculator (the one I wrote for the dlang.org page but ungolfed) is pure and checked as such by the compiler. It's also referentially transparent because "in" means the input parameter is constant and can't escape (and thread local fyi).