If I were “new to programming” right now, I would pray that someone would point me towards How to Design Programs, 2e and convince me to stick with it [1]. Your immediate reaction would likely be “why Racket - never heard of it”? The short explanation is that Racket is a “family of languages”, i.e. Racket has multiple dialects from a very basic one for beginners up to advanced ones that support OO and static typing (it’s earlier name was PLT Scheme - so yes, at its core Racket is a functional language) that were designed to teach you many of the varying concepts that are important in programming/program design in general.
Now I understand that everyone wants to learn their first “useful programming language” as soon as possible [2] and that most people would prefer to work in just one, their favorite language but the reality is that software developers have to work in multiple languages, not only serially (in time) but also in parallel. The first language you learn is going to have a tremendous impact on how you are going to think about programming. For some time your mind is going to treat “programming” and “your first language” as equivalent.
Elixir may not be a bad choice as the first “applied programming language” but every “applied programming language” tends to have its own (domain) focus and its own quirks - both of which can get in the way of learning your next language whatever that may be. Racket’s goal is to teach you a general way of thinking about programming and program design - so that it will be easier to assimilate the languages that follow.
From The Structure and Interpretation of the Computer Science Curriculum [2004 PDF]
In general, we believe that the HTDP project has validated the usefulness of functional programming and functional programming languages in the first programming course. We have found that teaching Scheme for Scheme’s sake (or Haskell for Haskell’s sake) won’t work. Combining SICP with a GUI-based development environment for Scheme won’t work better than plain SICP. The two keys to our success were to tame Scheme into teaching languages that beginners can handle and to distill well-known functional principles of programming into generally applicable design recipes. Then we could show our colleagues that a combination of functional programming as a preparation for a course on object-oriented programming is an effective and indeed superior alternative to a year on just C++, Java, or a combination.
We are hoping that other functional communities can replicate our success in different contexts. We suggest, however, that using plain Erlang, Haskell, or ML and that teaching programming in these languages implicitly will not do. We all need to understand the role of functional programming in our curricula and the needs of our students.
FYI: back in 2004 OO was still seen as essential (rather than widely misapplied).
[1] Because it would save me from having to go through the agony of having to unlearn bad habits and ineffective / counterproductive mental models that result from the “quirks” that any applied programming language invariably has.
[2] Either because they already have something in mind that they want create or to become quickly “employable”.
See also: Why Racket? Why LISP?