I'm building my first non-toy app in LiveView. I'm blown away by how quickly I can move with it and love how Phoenix encourages DDD practices.
I'm a bit saddened that Elixir isn't bigger than it is. It's such a great entry into the world of BEAM and functional programming yet I've read more than once that people aren't interested because "it looks like Ruby and I don't like Ruby". There are some more legit reasons as well like it's dynamic, but I wish people would stop getting so hung up on syntax and actually focus on what the technology can do.
What turned me off about elixir was not the syntax, it was the flexibility in designing new syntax. It felt like each library had its own idioms and syntax rules, which just adds a huge amount of variety and difficulty in a codebase. It was hard to have consistent architectural patterns across a team. I've seen an elixir/phoenix backend rewritten completely in python/django and it was a big improvement in developer productivity. I think elixir may work better for small teams. The learning curve and the "consistency enforcement" of languages really does make a difference on big teams.
Can you give an example of what you mean by “idioms and syntax rules”?
I’ve been using Elixir for a long time and I don’t know what this could refer to. Even with macros, all code still has to follow the same Elixir syntax. You can’t actually change that syntax nor can you extend it for the most part unless you are using libraries that are somehow writing their own control structures they are forcing you to use or something? I’ve never heard of that.
Also, if you are just talking about enforcing consistency style wise, there's https://github.com/rrrene/credo which is very popular, and the build tool Mix comes with a formatter by default which can standardize your codebase.
> It felt like each library had its own idioms and syntax rules
This sounds like the way software should be. No? Domain-driven design? Or are you saying that they don't follow industry nomenclature?
> It was hard to have consistent architectural patterns across a team
Is this a symptom of everyone being new the language on the team or the language itself? Elixir is a very simple language compared to Python and Ruby in my experience. There are certainly way more people that have done the latter two. What's comfortable isn't always better.
I'm wondering how aware of the trade-offs you are in using an imperative language as compared to one that's functional. If the nitpick/gripe you're having is around readability and syntax, I'm sure there are enough counters in other languages that you've worked with where the code was just spaghetti and hardly testable
Have you considered that productivity comes more with time? I get the sense that you've worked in a team with very few experienced developers that have either worked with Elixir/Erlang or functional languages. My experience has been that those with extensive experience in OO or imperative languages w/o ever treading into FP have had a much harder time adopting Elixir and it has resulted in slower development early on, but those willing to learn, march much faster after ramp-up.
But if you value correctness, less bugs, and easily testable code, it's hard to beat functional languages in this area, and I'm not even talking about just Elixir
> I've seen an elixir/phoenix backend rewritten completely in python/django and it was a big improvement in developer productivity.
Is this really a better idea? If you're mentioning "consistency enforcement", why not use Golang? Elixir also has a formatter built into its toolchain.
Take my responses with a grain of salt -- because if you're just doing a CRUD app and not buying into what the BEAM gives you from an operational perspective, it's probably not that worthwhile?
As in the whole project was rewritten in Django or some kind of transpiration going on there?
I haven't gotten to the point where I'm adding a lot of libs yet and certainly can't speak to using it in a big team.
In terms of syntax flexibility, Ruby has a similar issue where a lot of popular libs implement their own DSLs. I've never fully bought that that is a problem—a library is going to have an API that will require reading documentation. Maybe the one example that goes off the wire is RSpec (I'm really used to it now but I'm really enjoying going back to good ol' `assert` in `ExUnit`). In terms of keeping it idiomatic with the business logic, library can (and in my opinion always should) be wrapped. I may be missing the point or being reductive here, though, and I would be interested to hear more about your particular pain if you're willing to share!
...and of course if you are talking about using meta-programming to write business logic, that's not a thing anyone should ever do for any reason ever, period (IMO).
For me the raw speed of writing a highly interactive app in LiveView is unlike anything I've ever experienced. My primary experience is with Rails and React.
> In terms of syntax flexibility, Ruby has a similar issue where a lot of popular libs implement their own DSLs.
Of course in ruby, nobody is actually adding new syntax, although that's a common misconception. Ruby DSL's are still just ordinary syntax for method calls and block parameters, there's no new syntax at all. Sometimes it can look like it, maybe because ruby method calls don't require parentheses? But no library truly adds syntax to ruby, they just define methods that can be called.
I am not familiar with elixir, I am curious if what we're talking about is an ability in elixir to truly add new syntax, or something more like Ruby so-called "DSLs".
Correct. You can't add new syntax to Elixir either.
FWIW, the meta-programming models are very distinct. Elixir's is based on AST and it works at compile-time (like Lisp but without reader macros). For example, imagine you want to do your html markup in Elixir, you could do this (but don't!):
html do
title "hello world"
body do
...
end
end
In the above, `html` would be a macro that looks at the structure of the code and transforms it into something at compilation time. The macro must exist before being invoked and it has to literally surround the code it changes. Once the code compiles, you can't change it.
Ruby's meta-programming is runtime-based. So the same example above would likely be implemented by calling methods on an object, either pre-defined ones or using method_missing, as you execute the code. In Ruby you can also define (or redefine) methods at any time and it affects the whole runtime.
Both languages also have a similar ability to meta-program a class (in Ruby) or a module (in Elixir). Think Rails' resource macro in a router. But Elixir modules are closed, in contrast to Ruby classes. Many times this is what people refer to as DSLs, even though the term DSL in itself is more general. Python has similar abilities too.
PS: you are certainly aware of the Ruby bits but I went for completeness to be a reference for others. :)
> Of course in ruby, nobody is actually adding new syntax, although that's a common misconception.
This is the argument I usually use for anyone who has a problem with it yet if they've already decided they don't like it, it doesn't do much to pursued them. On the other hand, being able to rewrite operators in Ruby does take it a bit in that direction—While not strictly new syntax, changing the meaning of an operator can really throw people off. As an example in the standard library, there is `Dir[]`. `Dir[]` is a shortcut to `Dir.glob`. Sure, it's technically doing some kind of access, but everyone knows it as hash access and certainly aren't accustom to passing a pattern to it. Elixir libs do stuff like this.
And I'm sorry, I don't know if can actually add new syntax in Elixir, but you can certainly change the meaning of existing syntax (as in Ruby).
Yes there is a formatter built into Mix, the Elixir build tool. There is also https://github.com/rrrene/credo which is not as extensive but does the same thing as ESLint.
That's the exact reason why I won't be doing anymore Ruby development and haven't for almost 2 years. It's an awesome language, but everything's got to be a DSL and metaprogrammed with those people. Eventually I realized all that added complexity isn't worth it, though I suppose if it makes your company depend on you if you're the only person who understands the Eldrich abomination you've written.
I'm a bit saddened that Elixir isn't bigger than it is. It's such a great entry into the world of BEAM and functional programming yet I've read more than once that people aren't interested because "it looks like Ruby and I don't like Ruby". There are some more legit reasons as well like it's dynamic, but I wish people would stop getting so hung up on syntax and actually focus on what the technology can do.