This paper was written in 01991. Garbage collection is from 01959. Message-passing (aka object-orientation) is from 01972. C is from 01973. If by "generics" you mean parametric polymorphism, those were added to Ada and C++ in the mid-80s, after having been invented in ML in 01973; in a sense they're an attempt to bring the virtues of dynamically-typed languages like Lisp to statically-typed languages. Even today, I don't think there's a Common Lisp implementation with any kind of parametrically-polymorphic static type system, not even as an optimization. First-class functions are also from 01959, or, arguably from 01936, in the untyped λ-calculus, or 01920, in combinatory logic.
Some of these things were brand spanking new in 01973, but none were in 01991.
There were Lisp systems for minicomputers like the PDP-11; BSD included one (which I think was ancestral to Franz Lisp) and XLISP ran on CP/M. And of course Smalltalk was developed almost entirely on PDP-11-sized minicomputers. But to my recollection virtually all "serious" software for microcomputers and minicomputers was written in low-level languages like assembly or C into the late 80s, not even PL/M—though Pascal did start to win in the late 80s, in significant part by adopting C's low-level features. Nowadays, microcomputers are big enough and fast enough that Lisp, Haskell, or even Rust is viable.
I don't think "the right thing" is mostly about what features your system has. I think it has more to do with designing those features to work predictably and compose effectively.