Having worked with both to create the same system (building a game server) I've found Clojure actually sits better with the functional thinking style (1 data structure, 100 functions).
While Phoenix was the killer app for Elixir, and Elixir has far superior readability (using the Ruby syntax); there were couple of things that were off-putting and I struggled with them.
1. everything is inside a module was an unnecessary distraction
2. And then the separation between anonymous and named functions simply were unnecessary
3. And that I would have to declare the data / record inside a module (??)
Elixir felt like a functional language un-necessarily trying to look like a class based language.
I sometimes feel that had Elixir had only supported functions outside of modules... oh that freedom.
But some of the thought that went into Flow, Channels (which has become the de riguere now), mix (developer ergonomics ftw), those micro-second latency responses, distillery are still too classy and amazing.
> Elixir felt like a functional language un-necessarily trying to look like a class based language.
Not really. Named functions live in modules because that is how it is done in Erlang; Elixir is compiled to Erlang's abstract syntax. In practice does anyone define Clojure functions outside of a namespace? Haskell functions are always defined in modules too, do you think they got that from class based languages?
IEx will let you define a module at the REPL. Combine that with a macro (exercise for reader) in your .iex.exs which expands a function into a module definition and imports it and you're in business.
I agree Clojure has a better REPL experience than Elixir. But in Elixir REPL for a quick and dirty function you'd probably just do
>bar = fn x -> x + 1 end
The most unfortunate thing though is then you have to have a different calling convention. Its the greatest flaw in Elixir by far but they didn't have a reasonable alternative given the constraints of Erlang.
Still for defining a named function in the REPL its the same in Haskell and most other languages I believe that you can't define a new named function or add a function to a module in the REPL, though at least in Haskell the calling convention for a variable bound to a lambda is the same as for a named top-level function. LISPs have always had a different notion of how the REPL integrates into the development experience of a running program, and I don't think its really been replicated elsewhere.
You may be "playing code golf", but I generally just use the capture syntax where the compactness aids readability. For example, a function that takes two arguments and returns their product could be written as
fn x, y -> x * y end
or
&(&1 * &2)
When used inside a map or reduce or when the function is a direct mathematical operation on its arguments, it can be a bit quicker to parse the capture syntax than the fn ... end syntax.
I had most of these concerns when I was early learning the language. I found it annoying to have everything in modules. Now, however, I've come to appreciate the organization and structure that this forces upon the programmer.
It makes me structure my code and group related concerns at time of writing. I now code my functions as a working collective rather than individual items.
And with .exs files, you can have multiple modules in one file for quick scripting.[0]
You can just ignore modules/namespaces. While you have some procedures private to the file, you can expose them and they're just in the global namespace.
Maybe my enjoyment with Nim is partly due to the (awesome!) boringness of Elixir at times. I write Elixir code. It mostly just works with a few simple abstractions. Nim's more fun for MCU's and fast code where allocations count and I don't care about scalability of the application as much. I rather enjoy both.
Like others all of my Clojure code was in namespaces so I see it as a wash between the two. In practice I cannot imagine any real app not making use of such modularity.
I too found the "." syntax for anonymous functions a bit jarring at first. Why treat them differently? In practice I don't even notice it now. It's never been confusing, it's just a wart.
Also, I found the one-struct-per-module thing a bit odd to begin with but in practice it makes a lot of sense. Also since you can put modules inside modules it's no encumberance if you want to declare a number of related structs. Again, once I was used to it I apprecitated the simplicity.
I disagree with your characterisation: I perceive no "class-based"'ness about Elixir. Do you have some examples? Perhaps there is somethign I have missed. So far, given that it's not exposing a class based system underneath, Elixir has seemed even further from this than Clojure.
And I have, in general, found the tooling support friendlier for Elixir. The only thing that I really gripe about is the inability to communicate between editor and REPL.
While Phoenix was the killer app for Elixir, and Elixir has far superior readability (using the Ruby syntax); there were couple of things that were off-putting and I struggled with them.
1. everything is inside a module was an unnecessary distraction
2. And then the separation between anonymous and named functions simply were unnecessary
3. And that I would have to declare the data / record inside a module (??)
Elixir felt like a functional language un-necessarily trying to look like a class based language.
I sometimes feel that had Elixir had only supported functions outside of modules... oh that freedom.
But some of the thought that went into Flow, Channels (which has become the de riguere now), mix (developer ergonomics ftw), those micro-second latency responses, distillery are still too classy and amazing.