I would also say that the error management is also beyond fantastic. Say you run a function, and deep inside the call stack there is an error. In CL you can actually update the faulty function and just continue executing at the point of the error.
For someone like me without any intellectual rigour at all, this lends itself to a kind explorative programming I really like.
You don't need to reload the full module like in BEAM languages like Erlang or Elixir, you can modify a single function or a form without the need to make a version upgrade to the processes running your code - the next time any thread, including e.g. an already running game loop, ends up calling the new function, it's the new version of the function that will end up being called.
Once that's done any external call (`MyModule.add(1,2)`) will go to the new version of the code, while local calls (`add(1,2)`) stay on the same version.
The Phoenix web framework will also auto-reload any module that has changed on disk when handling a web request in dev mode.