This book describes the ideas of programming paradigms and how they’re built up using the lisp (racket) programming language to work out the examples.

This is probably one of my favourite books to introduce someone to the fundamental concepts that shape modern programming languages. Unsurprisingly perhaps, this understanding is a significant boon in many areas of cs, including vulnerability research.