Some notes:
Keywords are not simply "another pragmatic solution that won over finding a more elegant way to support named arguments" and they are inherently different than maps and serve different purposes. Maps are unordered hashes, keyword lists are constant time, ordered list that can have duplicate keys. For example, in the language core, duplicate keys are used:
import Foo, only: [bar: 1, bar: 2]
Ecto's query syntax makes use of both duplicate keys and ordering: from q in query,
join: t in assoc(q, :table),
on: q.table_id = t.id,
join: o in assoc(t, :other),
on: t.other_id = o.id
Everyone complains about the f.() syntax. It's necessary as explained in the guides in the Anonymous Functions section [0]. There is also a nice little parallel to Erlang in that a regular function call looks like `f()` whereas an anonymous function call looks like `F()`.Contexts can be confusing, unfortunately. They're based off of bounded contexts from Domain Driven Design. I wouldn't say there is one right way to use Phoenix contexts, though reading up on DDD's bounded contexts really helps. I already had DDD experience before I learned Elixir, though, so it's easy for me to say and maybe more of a pain for others who don't want to do that.
Comprehensions can be much more concise in certain situations. You can certainly get away with avoiding them, but they can really come in handy sometimes. Not gonna give examples as this is getting too long. A short example would be Cartesian products.
Finally, I don't quite understand the gripe with `on_mount` or even `live_session` but that's been addressed in another comment.
[0] https://elixir-lang.org/getting-started/basic-types.html