On to Elixir
thraxil.orgAfter 20 years trying All The Frameworks, Phoenix is the first that excites me in a long time. Both the community and the coding experience remind me of Rails's early days in 2004/2005.
Same for Elixir in general. Different philosophies, but same energy, some craftsmanship, some welcoming attitudes, same hubris about what can/can't be done by revisiting from first principles.
LiveView is quite elegant, and is something that could only exist with such elegance in a language/runtime/community that values and supports long-lived processes with functional semantics.
Broadway builds on the shoulders of giants to provide robust data ingestion and processing... as a library, rather than the cobbled-together set of independent systems that is usually needed to do this.
The architectural concepts underlying Livebook put it on a path to surpass Jupyter, if only we can get critical mass adoption.
The stuff emerging in the Elixir + ML space thanks to Nx and Axon gives me some hope that Elixir will find a place as an all-in-one home for all things ML. Livebook makes it easy do to incremental experimentation. Bumblebee makes it stupidly simple to use pretrained models.
It's all so magical.
What we need, though, is better marketing!
> The architectural concepts underlying Livebook put it on a path to surpass Jupyter, if only we can get critical mass adoption. > > The stuff emerging in the Elixir + ML space thanks to Nx and Axon gives me some hope that Elixir will find a place as an all-in-one home for all things ML. Livebook makes it easy do to incremental experimentation. Bumblebee makes it stupidly simple to use pretrained models.
Totally. My current employer does a bunch of data science and ML stuff and I'm hoping those give us a path off Python. Right now, it's hard for me as a non-data science, non-ML person to just be like, "here, use this Elixir thing instead of $tool_theyve_been_using_daily_for_10_years, I swear it's probably better or at least will be eventually"
Totally. I support a team of 40+ and even I have a hard time proposing this. Very hard to go against the herd.
There's so much progress happening in existing Python-powered ML community that, unless there are very good interop tools and protocols (e.g. ONNX and the like), then even if you gain productivity gains w/your local team by moving to Elixir, you risk losing your ability to draft off that larger community's progress.
Very hard trade-off unless you're sufficiently funded to invest in the gaps.
I agree with the code generation of libraries in Phoenix being a drawback.
I think it maybe a reaction to there being too much magic in Rails dependencies, but it makes upgrades much harder.
I've found the code gen approach to be very positive. Most of the generated code is minimal app-specific modules that in turn `use` Phoenix modules. This gives you a handy place to insert your customization w/o having to resort to dynamic metaprogramming contortions the way you used to have to in Rails.
I also like the philosophy of magical experiences, without magical code. Everything is very traceable. And most of the time you don't even need to use the generators - just make your module, register in the right places, and you're done.
Jose has written about this before https://news.ycombinator.com/item?id=34935952
After reading that, I understand exactly where he’s coming from - I too have overridden a bunch of Devise in a bunch of different ways in various projects.
But, unlike the rest of Elixir and Phoenix, this approach doesn’t feel like an elegant solution - it feels like a moderately ok trade off.
A lot of that code generation is to facilitate macros. Personally, I don’t like macros when a little extra code to make a function call would work just fine.
Might be misunderstanding code generation. This means literally writing code into your project via a script. It has nothing to do with macros.
The point about code generation into the project is unfair. The only library I'm aware of that does this is phx_gen_auth, everything I've used works exactly as described. phx_gen_auth takes this approach due to José's experience working on Devise for Rails, which mirror's mine as a user. I overrode almost everything in Devise, often in very messy ways. While the difficult-to-upgrade argument is a sound one, once you've over-written a massive chunk of a library anyway, upgrading is no easier.
Otherwise, great article about Phoenix!
(Author here). Yeah, it may be unfair. phx_gen_auth is definitely one of the main ones that I encountered and struggled with (compared to, eg, django-allauth or django-social-auth). Even just the basic approach to working with Phoenix seems to be much heavier on using code gen (`mix phx.gen.`, `mix phx.new.`, etc) than Django. Maybe that's my newness and the books and documentation I encountered, but it seems like a lot more of the code in a Phoenix project ends up being code that was originally generated compared to an equivalent Django project). Even from the very beginning, there's a lot of code generated when you do `mix phx.new`. Eg, this exists for a reason: https://www.phoenixdiff.org/
Ya, it's fair, it's a common complaint! Though the size of the generated files is nothing compared to Rails :D
You're right that phx_new does count too. It's a bit misunderstood that Phoenix is actually closer to a micro-framework like Flask than it is a full-fledged solution like Django or Rails. What takes it up to their level is `mix phx.new`, so your argument is more on point than I initially thought. The LiveView issue tracker even provides a single-file version of a Phoenix app to re-create your issue in [0]. As you can see, it's not as simple as something like Flask, but not as complex as the generator does.
Again, great article and happy to have you aboard ;)
Also, if you want an auth solution without code generation, there is Pow [1]
[0] https://github.com/wojtekmach/mix_install_examples/blob/main...
You forgot
ecto.gen.migration!
You’re right! I still haven’t read up on how Django does it, but I’m assuming it must make a migration file? Obviously I shouldn’t assume but how else would you add things like indexes and whatnot?
All right, I've read! I'm sort of referencing two different threads I'm involved in here but from the Django docs:
> Your models will be scanned and compared to the versions currently contained in your migration files, and then a new set of migrations will be written out. Make sure to read the output to see what makemigrations thinks you have changed - it’s not perfect, and for complex changes it might not be detecting what you expect.
So it's not different other than it can scan the changes in models to help create the migration which is a nice little convenience.
I’m surprised to see that the OP, as a Django user, does not call out the lack of an out of the box admin tool that’s not there in Phoenix. Django’s admin is amazing and super useful in production. I love phoenix but I miss an admin tool :(
Author here. I do love me some Django admin, but I find that I tend to use it a lot early on in a project and then slowly move as much away from it as possible as we build up more specific admin/management-type functionality in the app itself.
I also would probably include Django Admin in the "app ecosystem" stuff that I do call out. I think if Phoenix had a similar ecosystem, there could easily be something like Django Admin that you could just drop into a project.
There is! Andy Glassman talked about this at Empex NYC (that I help organize btw!) https://www.youtube.com/watch?v=3c9kMmxeSA0
The tool Andy uses is called kaffy https://hexdocs.pm/kaffy/0.5.0/readme.html
As a Phoenix user, I Call out!
Something like the Django admin in phoenix would be like taking the actual USP of Django away … and it could even be real-time and collaborative by default :-)
Not interactive, but I hear good things about kaffy
The Django admin has unfortunately stayed stagnant for 15 years. We built a replacement admin in iommi first almost as a joke, but now it's a serious part of the framework. Our admin is 645 lines of code (54 of which are imports!) while djangos admin is 5307, and still our admin is way more customizable. Not only that, but you can easily reuse all those customizations if you want to lift stuff out of the admin to your own stand alone view, unlike with the Django admin.
It's all about great abstractions. Django never extracted the table/filter stuff from the admin into a usable stand alone component, and it really shows.
Could you consider releasing it into the open source?
Django admin is stagnant mostly because of lack of uptake in support from companies. Everyone makes their own admin solution rather than collaborating.
It is open source. https://docs.iommi.rocks/en/latest/
There's several plug-and-play admin tools for Phoenix.
Last time I looked Ecto didn't have automatic migrations I think. Does it now? I can't imagine working without this feature after many years of Django...
It takes the more Rails-like approach where you run a mix command to generate a migration (and that potentially writes out an elixir module with the Ecto schema, eg, when defining a whole new table) rather than Django's approach of updating your `models.py` and then having `manage.py makemigrations` introspect the DB and generate the migration code from that. I do slightly prefer Django's approach, but it's an easy adjustment to make.
On the other side, `mix ecto.migrate` essentially works the same as `manage.py migrate` for bringing your database in line with the set of migrations in your code.
I don't know why this is always talked about as if it's some killer feature. You still have to review the migration its generated, don't you? Don't get me wrong, it's a nice feature that I would use if were available, but certainly not even on a list of dealbreakers for me when evaluating a framework.
Ash framework [0] does have this feature, though.
The people who talk about it consider it to be a killer feature. I certainly do. There's considerably less ass pain and fear involved in Django migrations.
As I said, I would use it if it existed. But I have never experienced anything close to fear when writing migrations, that sounds insanely hyperbolic. The most I've experience is very mild pain.
There's also the thing that schemas are not 1-to-1 with tables in Ecto (I realize it's possible in ORMs too, but not as ergonomic). Sure, you don't have to do this, and many don't, but it's very useful.
I don't know about fear. The Django migrations are a bit stupid in some ways so introduces some fear.
It's more about the speed of development. I sometimes make many migrations per day. It's just so fast I don't really think about changing models at all.
The fear isn't when writing migrations, it's when executing them in production. And please don't lecture me on how you should always be confident that your migrations work as expected before they go out.
It's okay if it doesn't solve a problem you have.
Dangit, Bobby, please don't assume I'm going to lecture you ;)
But I'm very curious how this solves that problem. I've only ever had problems with migrations when misusing them to do data migrations. And of course when renaming and deleting columns... does it somehow create a multi-step deploy plan in these scenarios!?? If it did that then I'd change my tune. I can do reading on my own, though.
> It's okay if it doesn't solve a problem you have.
Once again, I'm not, repeat NOT, saying it's a bad feature. I even said I'd use it sometimes if it were available. I'm saying it's unfortunate when I hear people writing off an entire framework because it doesn't have this.
Executing them in production by running `mix ecto.migrate` is essentially equivalent to running `manage.py migrate`. That part of the two approaches is really the same.
Oh, ya, if DangitBobby is thinking there are no auto-mated migrations in production then we're talking about two different things. I just meant the ability to infer migrations from models.
I haven't looked at an auto generated migration in years. So no.
No and it is not on anyone roadmap. So far we have not had anyone that found a way to make it work well.
You just need to cover the easy 80%, and nicely tell you to go to the documentation for the other cases.
Django migrations have been doing this for a long time...
Ash has automatic migrations. They are great when they work. When they don't...
When they don't you just write them yourself. All we do is generate migration files to provide a good starting point. Its a convenience tool.