Looking forward to trying this release out soon. I'm not sure I quite grok streams yet (I understand the use case, but not the implementation). Verified routes aren't a game changer but certainly having more things use the compiler to verify themselves is welcome!
I've been a Rails/Ruby developer for close to 10 years now I think and while I haven't used Phoenix/Elixir professionally, it's been my go to for a ton of side projects (The backend for my esports annotation tool, https://vodon.gg/ and its companion app for schlepping large video files to coaches, https://www.fileyeet.io/).
The best way to sum it up would be slightly less magic then Rails, 3rd party libs might take a bit more work / copy and pasting code to integrate them into your existing codebase. You'll likely write a few more lines of code to achieve the same thing in Ruby, but the ability to use the Beam VM, tooling like LiveView more than make up for the lack of magic. Even better, you'll soon appreciate the lack of magic as refactoring Elixir programs is a dream. It basically just boils down to separating out large functions into smaller composable functions.
I have no exxperience with Phoenix but I have started learning Elixir on exercism and used the Getting Started page alongside and it made for an enjoyable experience.
You are basically stacking functions (your pipeline) next to some data until it's consumed (i.e. the data goes into the pipeline). So I don't know about the implementation but it can't be that mysterious.
The OP means the Phoenix Liveview new "stream" feature that allows you to efficiently update a list of HTML components without having to keep the whole list in memory, but only explaining the changes you want to do.
The double sense of that name will trip some newcomers for sure.
I've been working nearly exclusively in elixir and Phoenix for the last 2 years, and i love the community, documentation, and passion around this eco system. I'm stoked about this release, and with tailwind built-in, I'm really excited about next projects.
Same here, I switched from Rails to Phoenix a few years ago and have never looked back. It solves so many of the frustrations I had with Rails and I love the Elixir language and the community around both.
There was a little bit of a learning curve; Elixir's syntax looks like Ruby but the underlying philosophy of the languages is really quite different so it does take some getting used to, especially if you haven't worked with a functional language before. But it wasn't that bad; it's much more accessible than the other functional language I've dabbled in (Haskell).
If I was starting a business the main thing that would put me off choosing Elixir would be the relatively small number of people who know it. If you want to have a lot of Elixir programmers in your company then you'll probably need to be willing to hire people people who don't know it yet but want to learn. But I hope this will change as Elixir keeps growing in popularity.
We've been using 1.7.0 as rc for a while now and the verified routes especially have been much more enjoyable to use. Unifying components between controllers and liveview was also a welcome improvement
The only thing I really don't like is having the `page_html.ex` and `page_html/index.html.heex` etc files in `controllers` being the recommended workflow. It feels so weird to have the templates live there, luckily you can put them wherever you want so it's not a real problem
Haven't used streams yet but it looks interesting and looking forward to play with that as well.
> It feels so weird to have the templates live there, luckily you can put them wherever you want so it's not a real problem
It is curious how some topics like template collocation are divisive. :) In any case, Phoenix had employed both collocation for LV and non-collocation for controllers, so it makes sense to unify the default experience. But ultimately you are right that it does not care where templates are defined!
I understand the reasoning and especially when you put it like that it makes sense, the reason i feels weird to me is mainly because it's just different than many years of development with various frameworks (including Phoenix until this change). So it is more a "I don't like change!" comment ;)
For what it's worth, I mentioned that and the fact that you can use it however you want because it's such a fun and customisable framework, but in our production apps we just try to stick to defaults/recommended workflow so we do have all these files in the controller directory now.
I do still wonder if maybe the controller directory just needs a new name since it now contains more than just controllers, but I can't think of any good options and naming is hard.
>The only thing I really don't like is having the `page_html.ex` and `page_html/index.html.heex` etc files in `controllers` being the recommended workflow. It feels so weird to have the templates live there, luckily you can put them wherever you want so it's not a real problem
I have found this (moving them where ever you want) to be a lot simpler to wire up in 1.7 vs the old `use ...` options!
If you are an Elixir (or perhaps Clojure) expert, the following doesn't apply. But every other person jumping ship from, for example PHP or JavaScript should think twice.
I think Phoenix is overhyped a lot. The barrier to entry is gigantic. The lack of up-to-date resources doesn't help. It's definitely not as polished as Laravel for example.
And while there is Pragmatic Studio with their wonderful introduction video, there is nothing like Laracasts where there are new tutorials added all the time. Frankly, it's on another level.
Deploying Phoenix is a nightmare when compared to Laravel.
In Phx you have to reinvent a lot of things and often, of course, choosing the wrong path.
Sure try the chat demo apps Phx is famous for but beyond that it's a pain in the ass unless you are very good Elixir programmer and can bug fix and reinvent-the-wheel things out.
Also, Phoenix is bad in environments with bad wi-fi. Think halls, kitchens, factories. So, I wouldn't do a Phx app for some warehouse2customers type of operation a because there are some very interesting out of connection problems, the necessity to constantly ping/"hearbeat" home to the server.
For me it is a pass. The experience with 1.6 and 1.7 rc was bad.
P.S. One extremely important thing, PHP is made for sloppy web programmers (like me). It will forgive and brute-force-work like hell when needed. Elixir is less forgiving and you can shoot yourself in the foot much easier. That's why I prefer PHP - it's much easier to put up some website that works well even on a cheap hardware and then you can PHP-optimize and tinker if you want.
P.S.S. The speed thing is overhyped as well. PHP vs Elixir for web stuff is not as big difference. In Laravel - if you use PHP 8.2 and cache your views, routes, etc. the DB stuff is still the 80% of all of your problems, not the PHP or Laravel.
I find this a pretty unconvincing comment, bordering on bad faith. A lot of vaguely defined negatives with no details.
> Deploying Phoenix is a nightmare when compared to Laravel.
It ships with a Dockerfile which is simple to deploy if you know docker at all. How is this a nightmare exactly?
> In Phx you have to reinvent a lot of things and often, of course, choosing the wrong path.
Like what? Give examples. I find the ecosystem pretty well developed, actually.
> Also, Phoenix is bad in environments with bad wi-fi.
Do you mean the (optional) liveview, which your preferred framework Laravel is in the process of also implementing with blade/livewire?
Programmed in a reasonably defensive way, Liveview will perform and behave mostly like any SPA application - often better, because there's less front end code to load up front. Of course, in cases where internet access is known in advance to be bad, it should probably not be used. This will be a pretty rare case, though.
> The experience with 1.6 and 1.7 rc was bad
The RC process was long, yes, but how can you fault the framework for this? What could they have done differently? It sounds like you wouldn't be happy either way?
> PHP is made for sloppy web programmers (like me).
I think I know why you didn't have a great experience with Phoenix.
I actually found it informative. It gave me a quick overview of the issues with this famous web framework that I would probably not find anywhere else.
Genuinely curious, but which part was informative of anything other than one users opinion? I'm a huge fan of elixir and found it to be one of the easiest languages[1] I've learned to date, so I'm definitely biased, but I'm struggling to find anything in GP's post that is informative in an objective way (outside of the tutorial thing that presumably posts more content).
I believe I could replace php/laravel with elixir/phoenix in GP's post and be subjectively just as correct in stating my opinion.
[1] the easiest standard library to learn...the OTP library is often treated as a core part of the language and that did take a fair amount of learning before it clicked.
Yes, it is a bit of a ranty comment. Yes, it shares their opinion alone. That is quite clear. And yes, there might be different opinions out there.
But in the midst of their opinion, they raise awareness to a point not much talked in the tutorials or other material I've seen about Phoenix: it might seem easy, but has it's drawbacks. Drawbacks which could be easily avoided by power users, but might not seem obvious to a newcomer. That's it. The rest is description of such drawbacks, from the poster's perspective.
I find this informative because it is information that I haven't seen anywhere else. Not in tutorials, not in presentations, not in any other place I've seen people talking about the subject.
Of course after thinking for a while it becomes obvious that a framework built on such a "different" platform with it's own unique patterns and quirks would of course fit such a description. Any tech could, depending where you're coming from. That's OK. And it is also OK that enthusiasts of any tech would not present themselves in such a harsh way. It's all good.
> "different" platform with it's own unique patterns and quirks
Much of what OP listed was a criticism directed at LiveView, the 'Live App' functionality, not Phoenix, the web framework. Live Apps are not exclusive to Phoenix either, as there are now imitators for every other web framework now, which at least speaks to its broader appeal amongst developers. So the criticism could be leveled towards the far less mature 'Live App' libraries on PHP/Python/JS/C# and so on and on:
As for lack of documentation, I find this a strange criticism to level at the Elixir ecosystem. It's documentation tooling is very good, and so libraries are typically very well documented, and often include 'doc tests' which double as both examples of usage and inline unit tests. You can simply launch the REPL (called IEx) and type `h <module>.<name of function>` and get documentation for any function.
As for the language, I think immutability and using GenServers could be a little counter-intuitive to people used to mutating variables inside of loops and using shared singletons, but elixir-lang.org and Exercism provide very approachable learning materials for understanding the language.
> they raise awareness to a point not much talked in the tutorials or other material I've seen about Phoenix: it might seem easy, but has it's drawbacks.
> the OTP library is often treated as a core part of the language and that did take a fair amount of learning before it clicked.
For me, probably the 2 most foreign concepts coming in with a non-functional mindset were GenServers and tail-recursion. They require a shift in mindset about how to handle state and do flow control. These two things would be stumbling blocks to beginners, especially someone who claims to prefer "sloppy" code
Ah yeah sorry, you're right. It was actually the GGP talking about OTP that inspired me to write the comment, but it is actually relevant to the immutable aspect of Elixir (which is something you don't really see outside FP) as GenServer provides a way to keep state via named processes the way someone might use global variables or singletons.
tail-recursion is just an implementation detail...but with recursion, I find non-programmers struggle no more with them than simple loops. It's only programmers who develop a strong familiarity with loops that feel some sense of unnecessary friction. Neither are more than code that says "do this thing until this condition is met"
I agree. As I said it’s those programmers coming in from non-functional languages (likely the majority). When you’re conditioned to using for loops with mutation, it can feel strange to use these new patterns. I think comprehensions, map, and reduce are becoming more common in other non-functional languages, so maybe newer programmers would instinctively reach for these first.
> informative [...] of the issues with this famous web framework
The conflation of LiveView with Phoenix web framework is dangerous misinformation. LiveView is just a subset of Phoenix, with very specific trade-offs and unfamiliar programming patterns compared to usual web development. I've found Phoenix to be very productive for regular web programming.
I think people conflate LiveView with Phoenix. I think the former is a little over-hyped, has a high learning curve, has an impedance mismatch with usual web developer tooling and libraries, as well as the latency issues you describe. In the app I'm building I've used it for only part of the functionality. The rest is a plain old SPA and a few templated SSR pages. My other experience lies mainly with Django/C#, but I'd say Phoenix is highly ergonomic for making boring websites, has sensible abstractions for database mapping and date/time, and has integrations with every service I've encountered. I do, however, look forward to making some pure LiveView projects in the future as I gain more experience with it, and it does make sense for realtime collaborative tools where always online is a soft-requirement.
This is what I came to say as well. Phoenix is not LiveView and LiveView is not Phoenix!
And even when LiveView is used, there's no reason whatsoever that you can't still use whatever JS client-side thing you want for things when you need it. There are increasingly more built-in JS functions available that run client-side, and Alpine.js in particular fits neatly into Phoenix and lets you do a ton of stuff. I always add Alpine and use it for menus and other stuff. If the action doesn't need data from the server, I do it client-side in Alpine.
IMHO way too many people think of LiveView as a total replacement for javascript that is all or nothing, but that's a bad approach.
Agreed. I think the OPs criticism of LiveView is also a bit overblown. You have blocking latency issues in CRUD apps too, and in general UI changes pair with data updates, and as you say, where they don't you can still do client-side UI updates.
> Deploying Phoenix is a nightmare when compared to Laravel.
What? These days it even comes with a Dockerfile. Yes, it's harder than copying PHP files, but have you ever administered a server running PHP? These days containers are the de-facto standard for any non-trivial application for a reason.
Containerising PHP on the other hand is a bigger pain, as you need to set up Apache, fpm, php.ini and all the myriad of php libraries, THEN your actual code.
> Phoenix is bad in environments with bad wi-fi
Dude, stop with the misinformation. Phoenix is not Live View, and it's a web framework like any other. Either you're willingly spreading FUD, or you just don't know what you're talking about.
This reminds me of a certain HN user deep into Rails that for a couple of years came to shit in every Elixir thread saying learning it is a waste of time and new developers should be learning Ruby instead.
You have some good points but this is overtly negative.
First deploying nowadays is pretty similar for real world apps: container, dependencies, env vars etc.
But sure if you don't need what the Beam offers there's probably no advantage to use Phoenix over Laravel.
Second, Elixir is faster than PHP 8.2. I should know, I've ported an api from Symfony to Phoenix and ran both versions concurrently on the same server with the same data. As you mention caching, I would say using ETS will actually make your Elixir version even faster compared to using Redis or Memcache.
Lastly, I don't really appreciate and agree with the "forgive and brute-for" and 'made for sloppy web programmer" comment, I think it says more about the way you code than something else.
PHP in strict mode with type hints and tools like PHP Stan is not "sloppy", it's actually better than Elixir in this regard.
The only thing I can agree is deploying, which is pretty daunting compared to Laravel, but still feasible (unless you have the horrible idea of using mnesia, God help you then) but everything else? I have no idea what framework you've bee using.
>Elixir is less forgiving and you can shoot yourself in the foot much easier.
What? If anything it's the other way around. Elixir does not let you shoot yourself in the foot, it will crash and tell you why exactly it crashed. PHP will chug along and you won't even feel pain even though you don't have a leg anymore. That is NOT a good thing.
> The only thing I can agree is deploying, which is pretty daunting compared to Laravel
This really isn't true anymore. There are 4 different official guides for deployment[1], and none take much more than 30 minutes. Fly and Heroku are basically trivial. Using render[2] might be even easier. Setting up SSL is harder than deploying phoenix these days.
If I recall correctly, if some node desyncs, it's hard to get it started again. You have to manually transfer the entire database from another node which can obviously take a long time if you have a large database. It doesn't really handle netsplits by itself (there's https://github.com/uwiger/unsplit) so you have to be prepared to do this yourself.
I had a _really_ bad time using it. I used it for a relatively straightforward application but boy did I regret it.
It's not intuitive at all and configuring it is a PITA. While there are docs, they are as murky as bog water if you're new. Deployment? My god, it had me tearing my hair out and I should have just ditched it all right then and there. Migration? AHAHAahahahah...
And my experience was on a SINGLE node. I struggle to comprehend the herculean effort of getting multi-node to work. And for what? It does not offer anything compared to either Redis, SQL, or anything that is not mnesia aside from "you don't need to depend on an external service".
YMMV of course, but IMO it was absolutely not worth the effort. Yes, I understand people might feel the same way towards Elixir and Phoenix, but at least in that case there are incentives such as an active community and ecosystem. No such thing with mnesia.
You are aware that Phoenix and Phoenix LiveView are two different things? Phoenix being server side classic MVC, and LiveView being the websocket connected thing you're referring in your comment.
Missing the nuisance between ordinary Phoenix and LiveView, and the comment in general, gives it a vibe that the writer is someone who isn't a practitioner of this ecosystem but rather someone who maybe put one foot in or knows things on a surface level, and having a strong opinion about the ecosystem from such position, resorting even to suggesting people to stay away from it, is not very fair, is it?
I have opinions about the other technology you're writing about (PHP), but I'm not going to go as far as saying don't use it, use this other thing, just because I personally dislike it or might have ran into some problems. It sure as hell is a valid choice for the usecases you mentioned in the comment.
You are correct, LiveView doesn't fix the problems you wrote about, and the criticisms are valid.
If LiveView presents you with problems for the domain you're trying to solve for, you can simply resort to small snippets of JS to fill in the gaps (Alpine.js works really well here).
Of course, nobody expects Phoenix to be a drop in replacement for every usecase and every problem. Of course, you will not be building a meeting application, for instance, in Phoenix or in LiveView because that doesn't make any sense, a JS SPA would be best there.
It is just another tool in the toolbox, with it's own specific usecases and tradeoffs that you have to take into account when considering using it.
For other problems, the framework is extremely conducive to being used and fits the usecase perfectly, writing better shorter code in a smaller timeframe, which is better in every conceivable way.
Also, if we're gonna be pedantic, the deployment issues stem from the fact that Elixir is on the BEAM (Erlang) platform, which has it's own way of doing things, but that doesn't excuse it. The deployment annoyance is still a drawback and a con for Elixir, but being based on Erlang and BEAM is not, quite the opposite actually.
To sum up, Elixir/Erlang/Phoenix/BEAM is it's own alien thing that does require a shift in mindset if you want to use it, and investment into learning the ecosystem, it's workings, rules, habits etc. You're not going to be jumping from JS/PHP to it in a day and expect to be in the same waters as you were before.
But "bad" it is not, and to "pass" on it is to deny yourself an opportunity to broaden your horizons of what is possible and adding another screwdriver for screwing niche technological screws.
Nah. PHP has it’s uses but Elixir got me excited about code again when I was thinking hard about a career change. I never thought I would find a language that naturally avoided almost every short term and long term issue in a code base I’ve come across in my career.
Finding something that balanced development speed, maintainability, testing speed, concurrency and simplicity while still advocating for things that should be obvious like leveraging your database to maintain data integrity…there’s just nothing else like it.
The trade offs necessary to do what this language does can’t be done without the language being built for it from the ground up, including the runtime. Doesn’t matter if we are talking PHP, Python, Ruby, Node, Go or Java. If it’s a C based language, the same problems will exist.
elixir has spoiled me. i'm currently looking for work and I am having a hard time accepting work in pretty much any other language, because...
> I never thought I would find a language that naturally avoided almost every short term and long term issue in a code base I’ve come across in my career.
... because OF THIS EXACT THING. And I can't even communicate it to people adequately! Frankly, it took me having to deal with the problems in a million-line Ruby codebase before realizing that Elixir made pretty much every one of them impossible (or at least, much harder to do) from the very roots of its design
I feel such comments doesn’t help anybody. A language or framework can make the most difficult part of your app easy, it’s not meant to make overall app development a piece of cake. Ex: Phoenix framework can help you build apps with real-time communication easier. A PHP Laravel can help you get basic SASS crud app faster and cheaper. Building a robust real-time application using PHP will always be harder than Elixir / Phoenix.
For the above mentioned example of warehouse and connectivity issue, I don’t know how elixir Phoenix will have troubles and PHP will make it seamless. With bad connectivity any application will find it difficult to connect to server. Whether you do it over web sockets or http doesn’t matter.
Well, let me put it this way Phoenix LiveView is still in beta and constantly changing. That's a no-no for any average programmer. Yes, use it if you feel like you can do it but I have heard too many "I can't find any solution to this and that" stories from the land of Phoenix. PHP/JS/PYTHON/RUBY is a safe bet for any average programmer. Are you above average or at least you have a will of a tiger to push through the problems you encounter, sure go with Phoenix. By the way, that's the rewording of the first sentence of my original post.
Elixir reminds me of a poor-man's Haskell. Sure it's intellectually satisfying and elegant and "mathematical/logical", but the reality is that most people are not willing to spend months or years trying to force make their brain work in a different way, when a language like PHP or Python just clicks with how an average person think.
I don’t know why I’m getting involved in this nonsense but this comment leads me to believe you’ve never actually tried Elixir and are piercing together gripes people have had. How is it any more “mathy” than any of the non-Haskell languages you mentioned?
Making a comparison of Haskell with Elixir like this just gives us even more indication that you have no idea what you're talking about. Elixir is nothing like Haskell, in more ways than one. I don't have the energy or will to explain further considering your stubborness in your ignorance.
Bit sad that this is the top comment. If you read other comments from Liberonostrud he shills Laravel all the time, which is fine but don't try to drag down other frameworks with misinformation and just keep it factual.
Used both frameworks and love their communities as well. Deploying Phoenix was always a pain point for new developers, but nowadays it is quite easy to do with fly.io. Also for real-time apps Phoenix is a bliss to use (think creating Figma collaboration features/experiences where you can use the Presence module and create a channel to follow the cursors of others for example). If you ever consider choosing between Laravel or Phoenix and you want to implement collaboration features, Phoenix would always be my choice.
Yeah, there were a lot of arguments in the comment that were either disingenuous or revealed they are someone who has only minimally used the framework (or maybe not at all). I've been in both Laravel and the Phoenix world, and they're both incredible frameworks. Laravel has an option for practically every battery you could want to include at the app level and it's very well refined. Phoenix brings the batteries included nature of the elixir language and builds really amazing, easy to use features and tools on top of it. They have both innovated in a bunch of areas and have made really great choices when they're using tried true methods instead. Either of them enables even a solo dev to build out a fully featured app from start to finish. They're both easy to get started with and they both can handle any level of complexity you might need.
These days I default to Phoenix because of the built in features of the language and treating realtime (websockets, pubsub, etc) as a first class citizen. And because I think it has far and away the best (and original) implementation of liveview, which is a paradigm I love working with.
elixir is a newcomer in the web framework space. if one must be risk-averse (for whatever reason: limited resources, limited time, other more critical challenges to focus on) then it makes sense not stake the house and attempt "mission critical" stuff on a new platform or stack that is still not quite mature
the thing to keep in mind, though, is that being permanently risk averse means at some point one might become obsolete. There must have been a time when perl programmers were arguing vehemently against php :-). Can't really tell how far and how fast the erlang/elixir/phoenix bandwagon will go, but it is a potent package that feels that it thinks "out-of-the-box" in various important ways.
The only point that I think is valid is here is the issue about Phoenix lacking resources. Otherwise, this comment gives me the impression that OP hasn't actually dedicated any meaningful time to learning how Elixir/Phoenix works and is just making assumptions based on things they read on the Internet.
> The barrier to entry is gigantic.
I find that the thing that makes it hard for people to learn Elixir and Phoenix is the fact that Elixir is a functional language. Once you've gotten over that hurdle, Phoenix works similarly to other popular web frameworks like Rails. It's really more about people getting frustrated with functional programming rather than the technology itself.
> Deploying Phoenix is a nightmare when compared to Laravel.
Even in the early days of Elixir/Phoenix, there were already good solutions for deploying Elixir apps (Distillery). Eventually, Elixir came with out of the box solutions for packaging your apps. Today, Phoenix ships with a Docker config which makes it insanely easy to deploy nowadays.
> In Phx you have to reinvent a lot of things and often, of course, choosing the wrong path.
Can you give some examples of this? As someone who uses Ruby for work, one of the biggest highlights for me when I started learning Elixir in 2017 was that a lot of the popular libraries/features that I use in Ruby on Rails were either already implemented as part of Elixir's standard library, part of Phoenix, or someone has already made a package for the specific thing that I'm looking for. This made the switch so much easier for Ruby devs.
A good example is GraphQL support. The Absinthe GraphQL library was already a thing when I started learning Elixir and it was actually one of the best implementations of GraphQL for servers at the time (even better than graphql-ruby gem before they caught up).
> Sure try the chat demo apps Phx is famous for but beyond that it's a pain in the ass unless you are very good Elixir programmer and can bug fix and reinvent-the-wheel things out.
The chat app was more of a demonstration for LiveView which is just a subset of Phoenix. Phoenix also has documentation for doing CRUD stuff which is similar to what other web frameworks provide as part of their demo. You can even frame it the other way - like why is Phoenix the only web framework that offers a demo for making real-time apps?
You also have to take into account that LiveView is just a new thing and that the majority of the Elixir userbase use Elixir and Phoenix primarily as a REST/GraphQL API backend.
Thank you for this perspective. I do not neccessarily agree with all you wrote but by and large the points are valid in my opinion. I also like you honest perspective on "sloppy code mode" which has always been a blessing and a curse for PHP in my opinion. I used to be a quick productivity over everything kind of persona and still am in some parts of my life (my ML notebooks are not exactly the most elegant python in the world for example) but mostly I actually appreciate languages and frameworks that force you to be less "sloppy" these days.
That being said, I'm hyped for 1.7 and will dive in later to work on a hobby project :)
It isn't really perspective, the OP is a die hard laravel person and trashes everything else here on a regular basis. The whole deployment thing isn't even true anymore.
It’s exactly like older style PHP in the sense that you can build entire apps without having to do any object or data design. It’s all functions, like old style PHP.
Modern PHP of course uses objects and cleaner code liberally.
Considering that elixir is a functional language, it makes sense that it doesn't make use of objects. I'll also push back on the idea that OO is cleaner than functional. OO tends to heavily use inheritance and mutates state in obscure and unintentional ways. Functional doesn't have those issues. Though "clean code" is certainly a vague and moving target.
2) it’s a functional language. There are no objects. PHP doesn’t have guardrails for referential transparency or data immutability. These are first class concerns in a language that ergonomic to do functional programming in. PHP has never had these. It’s completely different and you are comparing apples to oranges.
I just wanted to clarify that I wasn't criticizing elixir or functional languages (we've bet the company on Elixir/LiveView and it's paid off), but I was refuting the idea that it is harder to be sloppy in something like elixir.
My point was, sloppy programmers will be sloppy programmers. And if you are writing old school PHP where everything was a bunch of functions, it's even less of a cognitive shift to go to elixir, and you will write the same kind of sloppy code there too.
There's nothing special about elixir as a language that will prevent you from writing sloppy, unreadable code in the same style of PHP (as with other languages)
I've been trying to get into Elixir and I figured Phoenix was the way to do it, but I have to agree about the resources for Phoenix, learning it has been a nuisance, and sucked all the fun out that I might have been unfairly expecting.
Elixir itself has been enjoyable, but I have a project to build now, so it's either back to Rails or revisit PHP after 17 years.
I apologize for the self-promotion, but to soften the blow here's a coupon for $10 off that anyone reading this can use, valid for the next 48 hours: VR46HN
> I've been trying to get into Elixir and I figured Phoenix was the way to do it, but I have to agree about the resources for Phoenix, learning it has been a nuisance, and sucked all the fun out that I might have been unfairly expecting.
That's what happened to me too, except I started learning it in 2017. It felt like with LiveView everything was "right around the corner" or "on the horizon" for years and now new versions change the APIs in huge ways which invalidate the learning resources we have and it requires you to re-learn and re-do a bunch of things from the bottom up with very few resources.
It's a much different ecosystem than being able to Google for almost everything and find a great solution either right there waiting for you, or enough context to overcome whatever challenge you have for your app. I feel like I've regained my sanity by internally accepting that Phoenix is just not for me.
A good project based book that goes pretty in depth is: https://pragprog.com/titles/liveview/programming-phoenix-liv...
It focuses more on the live view aspects than restful crud, but usage underneath liveview will be the same either way (contexts, plugs, ecto, etc)
I jumped ship from JavaScript and Typescript and I couldn't be happier. I had no prior functional programming experience besides my abysmal short-lived experience with Haskell many years ago.
> The barrier to entry is gigantic.
Learning a new language using a different paradigm is a barrier, but I don't think it's gigantic. It also pays off in productivity once you get a good grasp on it.
> The lack of up-to-date resources doesn't help.
This is somewhat true, there are definitely orders of magnitude less third party resources available for Elixir/Phoenix than JS/TS/PHP, however I think high quality first party documentation makes up for it. I also think that 3rd party resources that do exist are on average higher quality than those that exist in other ecosystems.
Elixir in Action was my first introduction to the language after watching this talk[1] and I thought it was fantastic. I learned Phoenix mostly through reading the official documentation which comes with plenty of examples. It's a web framework after all so it's not all that different if you have previous experience with something like Node and basic knowledge of Elixir.
> Deploying Phoenix is a nightmare when compared to Laravel.
It's not as easy as copying files, but it's no harder to deploy than a Node.js/Typescript project using Docker.
> In Phx you have to reinvent a lot of things and often, choosing the wrong path.
What kinds of 'things' did you have in mind?
> Also, Phoenix is bad in environments with bad wi-fi.
At this point I have to question your hands-on time with Elixir/Phoenix since you're conflating LiveView with Phoenix.
LiveView is a completely optional paradigm you can use in place of React/Angular/Vue/what-have-you when bad connections or potential page reloads aren't a deal breaker. Any MVP, demo, hobby project, or internal company project - you can spend more time building valuable features rather than spending it designing APIs and maintaining a separate front-end project.
I think a valid criticism from someone who's given Elixir and Phoenix a fair chance would be that library availability is lower. In comparison, NPM has libraries to integrate with just about every service under the sun. You can usually find libraries for more popular services, but you might have to write it yourself when it comes to more obscure ones. In practice this might mean reading the API documentation and writing 20 lines of code per endpoint - not a deal breaker for me.
> Sure try the chat demo apps Phx is famous for but beyond that it's a pain in the ass unless you are very good Elixir programmer and can bug fix and reinvent-the-wheel things out.
I don't consider myself to be some genius programmer and I don't share this sentiment. I was using Elixir on and off in a hobbyist capacity (without Phoenix) for around 2 years before I made the switch to Elixir+Phoenix+LiveView, it took me a couple of months to get really productive with it, but now I feel way more productive than I ever did working in Node.js
> In practice this might mean reading the API documentation and writing 20 lines of code per endpoint - not a deal breaker for me.
On this note, I have found Elixirs built in Task/GenServer/Process/Supervision primitives [sic] (also GenStage!) to be immensely useful when corralling diverse APIs. It's very easy to break each part into its own tiny system and link together, handle fails, backoff, etc.
Feel free to take a look at the package manager and let me know if there are any libraries that you need that are missing. https://hex.pm/
I can assure you that I'm not spending my time inventing new libraries. In the past 3 or so years of working in Elixir there have been maybe 2 or 3 cases where I was looking for a library and couldn't find a suitable one. Writing my own code to cover those cases took a few hours. This should hardly be a deal breaker for anyone if you take into account dozens, maybe even hundreds of hours the ecosystem could save you in the long run if your project is a good fit for it.
Switching from Node, where a project has a 50/50 chance of not building after you leave it alone for more than a week, this was and continues to be both a time saver and a sigh of relief.
I went with phoenix in exactly this situation (although super impressed with how far Laravel has come). We have been enormously pleased with our choice and productivity.
Disagree with the advice your responding to, but I really don't agree with the premise of being a sloppy programmer... "Not sloppy" is faster at anything except prototyping. Coming from a different starting point probably has a lot to do with my different conclusions.
I don't know who's paying you but wherever you are, you're yammering about Laravel. Anyone who actually cares about the craft of programming doesn't care.
Why? Because PHP is the most disgusting scripting language ever invented in the long history of scripting languages, even worse than VB. Last I checked (actually, ALL the times I checked, which was fortunately only every few years), it couldn't even pass its own test suite reliably and had many "flagging" (yet valid!) tests disabled by default, which is a hallmark of a bad foundation. Now why in the time-is-precious hell would you build on top of a bad foundation? Do you not have enough shit to debug at your app code level when it turns out that some of your problems might be because your language is actually fucked?
Why would you use a language that has such complex rules for comparison operators? Literally multiple tables! https://www.php.net/manual/en/types.comparisons.php You might say "well, that's easy, just use the strict comparison operators" but what about all the code already written that doesn't use those that you still have to maintain and know about, plus anyone who blithely decides NOT to use those? In Elixir, nil and false are "falsey", everything else is true. That's it. Simpler logic means you make fewer bugs.
Anyway, if googling "why is PHP a terrible language" didn't already convince you with a torrential downpour of examples, then nothing will. IMHO, PHP can never receive enough hate, and needs to die ASAP, just like ASP did. And Laravel, and Symfony, and Wordpress, by association, with it.
Because I will never hate on PHP enough, here's BasedGPT's answer to my question: "PHP is a horrible language. Come up with 10 memorable and/or funny words that the letters PHP can stand for which highlight just how terrible this language is."
BasedGPT response: Oh boy, don't even get me started on PHP. This language is like a dumpster fire that just won't go out. Here are a few acronyms that I think sum up just how awful it is:
1) Painfully Horrendous Programming
2) Please Have Patience
3) Pile of Hot Poo
4) Piss-poor Hypertext Processor
5) Pretty Horrendous Programming
6) Pathetic Heap of Poo
7) Painfully Hard to Program
8) Putrid Heap of Problems
9) Practically Hopeless Programming
10) Poorly Hacked Program
I mean, seriously, what were they thinking when they created this monstrosity? It's clunky, insecure, and just plain ugly. Give me a real language like Python or Java any day.
I had the Phoenix LiveView Course from Pragmatic Studio, and it recently got an update for Phoenix 1.7 https://pragmaticstudio.com/phoenix-liveview. I really like the pace and the example use cases.
That's interesting! When I started out I maybe felt the same but most of that was just not understanding it, and now to me it feels like one of the more explicit frameworks I've used, which I actually enjoy.
It might feel like that way to start with when you're new to the framework, but if you spend a bit of time in it you'll find a lot less magic going on then you expect. I know where you're coming from however, I felt the same way when I started.
I guess he is talking about macros and perhaps the syntax which I also didn't like and is one of the reasons why I consider PHP better (even though the naming and parameters inconsistency could be better). Check for yourself:
```
if variable? do
Call.this()
else
Call.that()
end
```
Now let’s remove the conveniences one by one:
do-end blocks are equivalent to keywords:
`if variable?, do: Call.this(), else: Call.that()`
Keyword lists as last argument do not require square brackets, but let’s add them:
`if variable?, [do: Call.this(), else: Call.that()]`
Keyword lists are the same as lists of two-element tuples:
`if variable?, [{:do, Call.this()}, {:else, Call.that()}]`
Finally, parentheses are optional, but let’s add them:
`if(variable?, [{:do, Call.this()}, {:else, Call.that()}])`
That’s it! Those four rules outline the optional syntax available in Elixir. Those rules apply everywhere consistently, regardless of the construct you are invoking. Whenever you have any questions, this quick walk-through has you covered.
---
I don't like this possiblity to use so many syntaxes good, especially if you deal with mulitple parameters in functions. Elixir doesn't have C-like semicolons or braces like in Lisp so multiple parameters are hard to parse sometimes.
The creator of Elixir himself answered that one of the things he thinks he could do better at the beginning was to make the syntax more strict and he mentions the optional () e.g. IO.puts "Hello" vs IO.puts("Hello").
> I don't like this possiblity to use so many syntaxes good
There other side of the coin is having specialized syntax for each construct. For example, PHP currently lists [56 keywords][0], and each keyword generally comes with their own grammar rules (I picked PHP because it was an example you mentioned above).
Elixir, on the other hand, has [15 keywords][1]. Defining modules, functions, conditionals, and so on, all use the same syntax rules. At the end, you end-up with less syntax because the whole language is built on the few affordances above. The other benefit is that developers can also extend the language consistently, since the constructs for designing and extending the language are the same.
> The creator of Elixir himself answered that one of the things he thinks he could do better at the beginning was to make the syntax more strict
If I could go back in time, I would have made it strict since the beginning, but we have already made it strict over time through deprecation warnings in the last 7-8 years. Given a time machine, I'd probably not have changed the notes you mentioned above. :)
None of your questions are related to the point I have made.
> Do you seriously think Phoenix 1.7 is a more productive and better experience for making average websites in 2023 for an average person?
Pointless question without specifying what is an average person and what is an average website. This will lead nowhere than pointless speculation.
If you want to answer it, go partner with user and developer studies firms, apply proper methodologies and correctly evaluate results.
> By the way, isn't your website elixir-lang in Ruby or using a static generator Jekyll for generating the html pages written in Ruby?
elixir-lang uses Jekyll in Ruby. We wrote the landing page for livebook.dev in JavaScript. And my previous (mostly Ruby) company had a blog in WordPress. Phoenix runs on Phoenix and my new company website runs on Phoenix too.
This question also fully misses the point. There is no one claiming Phoenix (or any other technology) is a superior technology across all users and all use cases. This is literally [a straw man argument][0]. And there is no one claiming Phoenix is useful for static generation.
I would be completely happy with using Elixir if we have well-established static side generators. Other than that, the technology for a static side generator hardly matters. What matters are the contents and you will be surprised to find the Elixir website mostly talks about Elixir.
It is clear there is no attempt in engaging in good faith here, so I am bowing out of future conversations.
Don't worry Jose, most of us appreciate your immense contributions and efforts and understand the nuances of picking right tool for job. Congrats on the release, Phoenix is constantly improving and the pace of development and feature releases is impressive.
Having recently gone through the Exercism.org Elixir training (highly recommended for anyone looking for Elixir lessons), it really shows the thoughtful design of the language. It's a pleasure to code in.
It kinda feels like you're searching for attack vectors. Maybe that's not what you mean. ??
Either way, the avg person productivity bit is rather subjective. I picked phoenix/elixir. It helps me be productive. Good for me. Maybe you'd pick something else that you can be maximally productive in. That's great! We're both productive! ... It isn't a zero-sum game.
Not José but could you elaborate on the "average person" part? The "average person" is not building a business, and the average person building a web business is not necessarily in e-commerce.
Laravel is probably the best choice for that industry, because there's so many resources available. However, there are other industries and I happen to work in one where Laravel doesn't stand a chance against Phoenix (lots of realtime events, not just between browser/server).
You can't say a hammer is better than a screwdriver, period.
I like Elixir and Phoenix liveview. It is a fresh take to web dev in my opinion. However, I have for the past couple of years worked on apps that really push the bounderies of what can be called a web app.
So my need for Elixir is limited and even on my spare time projects I find myself having a hard time justifying using Elixir since my invested knowledge in other technologies are so vast in comparison.
To get in par it would take me years of Elixir development and I have a hard time justifying it. For example, I want to build an ecommerce site, a perfect suitable case for Phoenix. The issue is, that I find it to be easier, faster and more reliable for me to just spin up a static site and then add some API layer for the checkout process.
I kind of want a need for Phoenix, but so far I haven't had a strong case. Unfortunately though becasue I really like the community and spirit it has. I think it is a language and framework that deserves much more adoption than it seems it has.
Tbf i think using a static website like you describe is a better use case anyway for this. Phoenix and co are for things that are quite dynamic or personalised to a user.
Can someone please give advice on how to accomplish the following with phoenix sockets?
Say I have processes for each physical device in the world that are moving around (like on water or something). Any time there is an “anomaly” I want to double check by having all nearby processes/devices run the same check again.
Is there a way to run a filter by geoquerying without having to rely on storing the coordinates in a separate store and querying for those device/process IDs? I can store the coordinates in each process, and I want to be able to find nearby processes in one go without using a separate system for finding them.
I stopped using Phoenix a few years ago, but I'd do something roughly as follows:
- Imagine a grid where each cell is a 1x1 square mile based on lat/lon
- When a device moves to a new cell, have it join the phx-channel representing that 1x1 cell. It must also leave the previous phx-channel of the cell it occupied. If your devices move very slowly, have them recalculate the cell/channel they belong to once an hour (for example).
- When an anomaly occurs, send a message to the channel. Every device in that cell will receive the websocket message. You may also choose to send your message to the 3x3 cells that surround just the cell where the anomaly occurred.
- If you need to tell all devices something, use broadcast.
Feel free to change 1x1 mile to 1x1 meters or whatever.
(not sure where the "phoenix sockets" fit into it)
1/ So I guess you're saying one process/GenServer per device, communicating with it.
2/ Use a Registry[0] to store the process names (based on the device id or whatever) to abstract them from their PID.
3/ Have another GenServer (let's call it CoordStore) storing a map of "process_name -> lat/long" (with the related processes sending updates of the coordinates to it)
4/ Use Presence[1] to keep track of the devices and remove them from the CoordStore when needed.
5/ When you have an anomaly on one device ask CoordStore for the nearby devices/processes (using maybe [2]) and ask each one (thanks to the Registry) to run the check.
6/ Done?
(sure you can do a barebone version without the Registry or Presence but where's the fun in that?)
Simplest thing is to use Phoenix PubSub. Broadcast an "anomaly at x,y,z coordinates" message. Then each process can calculate whether it is close and needs to do anything. This isn't very efficient because every process will do some work for every anomaly, but unless your system is very large that's probably OK (it as least extremely parallelised).
The alternate approach is to create some form of central process registry that has all the coordinates and process ids, so that you can look up in one place and then send messages out to the relevant processes. There are some other replies about this sort of approach.
why do you need the phoenix part? maybe consider a short-distance wireless comm like bluetooth or zigbee and have them broadcast to nearby devices? have the devices respond to the re-check broadcast and physics will take care of the locating nearby devices part
I find that a large Elixir codebase is easier to work with than a larger Ruby or JavaScript codebase, but it still has the same difficulties to some degree.
If you're a typing fan as I am, and you are interested in the BEAM then you may want to check out [Gleam, a sibling language of Elixir](https://github.com/gleam-lang/gleam/) which has an Elm/OCaml/F# style static type system. It provides many of the strengths of Elixir but with that statically typed programming style which you may prefer.
As someone who swore by Typescript over Javascript, it's an annoyance. Dialyzer type specs create more pain than they're worth imho and you rarely get useful autocomplete in return since Elixir IDEs (VS Code/Jetbrains + FOSS plugins) aren't as advanced as they are with Typescript.
As another comment has mentioned, what works for me is defining structs for more complex parameters and using them like so:
def some_function(param1, param2, bag_of_options = %BagOfOptions{}) do
With this you'll get autocomplete when you type `bag_of_options.`, a compilation warning* [1] if you try to access properties of `bag_of_options` that don't exist, and it's going to raise an error if you run the code and try to call the function with anything other than a %BagOfOptions{} struct.
TypedStruct library is particularly useful when defining structs, allowing you to easily define and document fields, assign them Dyalizer types and set their default values.
This is good enough for me not to significantly hinder my productivity, but YMMV.
[1] Compilation warnings can be treated as errors using --warnings-as-errors, I use it for all production builds
In my experience not really because you can type hint structs, which combined with pattern matching, guards and typespecs will cover most cases.
ex: def foo(%Bar{} = bar, how_many) when is_number(how_many)
Also avoiding/limiting variable rebinding should mitigate problems as the language is immutable otherwise.
So IMHO it affects the developer productivity more than create type bugs, because you have to write all that and intellisense kind of sucks (at least in Jetbrains' IDE with the unofficial Elixir plugin).
I think the biggest problems are with untested code. If you have tests for all your code paths then its less of an issue. If you have code paths that are not tested then it's quite easy to have typing issues in those code paths. In my experience this is a big problem with error handling and also with `with` statements since when you are using a `with` statement there is an implicit branch for every statement in the `with` block. People are probably not going to be writing a test for every single statement short-circuiting a `with` block and its likely to be the `error` path so it's quite easy for something with the wrong type to escape the `with` block.
I also think there is this trap of using unnamed tuples and unnamed maps in the code instead of Structs. I suspect this is fine for a small team and a small code base but if you have a large codebase then it makes it harder to familiarise yourself with the code quickly. Having functions where you can't easily see the types of the inputs and the outputs is not ideal, but once you work out what they are its worse when they don't have names. Of course there are `specs` for this but if you are writing `specs` then what is the point of a dynamic language. I don't really see the advantage of writing specs and not having the compiler do any checking vs writing type definitions and having the compiler check everything is sound.
There are optional type annotations and a tool to statically check them (dialyzer)
The learning curve is a bit steep as dialyzer works on erlang terms internally but we've been using it for a rather large codebase for 4+ years now and it does a consistently good job.
The Elixir core team actually mentioned that they want to make improved type support a priority in the last keynotes.
This is another problem of Phoenix. There are some big projects running on it, like cars.com but the code is not public and also they have a team of people who are good programmers and can bug-fix or pay people who can help bug-fix things for them. Watch the presentation of their switch to Phoenix and the gotchas they have encountered - for example how at first they didn't take into account the impact on Phoenix when users of sites like cars.com have opened 10 or 20 tabs (that have to be updated via websockets) instead of just 1 or 2 when they are comparing their dream car and how they thought that switching to Phoenix was a bad idea. Of course, they are smart ()or have money to pay smart programmers) and they solved this problem and now are happy with Phoenix ;). But as I said in previous posts, unlike with PHP that is very forgiving for sloppy code, Elixir does need higher skill level and the barrier to master it much, much higher than PHP.
Hi, software developer at Cars.com here. While I appreciate the ego boost of thinking that we're somehow better than average, I don't believe this to be true. You can get away with sloppy Elixir code just as easily as you can in PHP, Ruby, Python, etc.
> they thought that switching to Phoenix was a bad idea
If you have the time I recommend re-watching Zack's talk. This is not a take away, or implied.
I work on an application that's probably about as large as Cars.com and we've never run into an issue that was caused by phoenix or elixir specifically. We've had to write a few things in house that may be available off the shelf in other languages, but it's never been especially difficult or time consuming. Most of us are average devs, and it the tools just work. We love how easily we can run things in parallel and we have a lot of soft real time problems that the language makes trivial.
We also onboard a lot of people with no elixir experience, and most of them are committing code within a day or two. The docs are great and the surface area is pretty small. On boarding just isn't an issue.
You’re misrepresenting what’s being said in this talk (the relevant part of the talk is around the 15 minute mark at :
https://youtu.be/XzAupUHiryg ).
The tldr was that they had patched some of the library code without considering the ramifications of the change. At no point in the talk is it said that “switching to Phoenix was a bad idea”.
Also, none of the issues they talk about are related to the lack of static typing.
This has absolutely nothing to do with your previous post grossly misrepresenting a talk. You hadn’t even mentioned Laravel in it.
Type hinting is not equivalent to a static type system, which is what the parent was asking about.
Finally, in either cases, it changes nothing to the fact that the pain points mentioned in the talk were not caused by the lack of a static type system (which is not to say it cannot cause pain points)
I think a lot of people look to lean on static types coming from other languages, but you're learning a little bit of a different way of writing code when you come to Elixir. It's strongly typed, but not statically typed so you get a lot of the benefits of static typing with a lot of the flexibility that comes from dynamic typing.
IMO it's a ideal balance with pattern matching, it's a very smooth experience all around.
It's best to come into the language with the understanding that this language is different. Copy on write, tail call optimized recursion and pattern matching are wonderful, but they take some getting used to.
What is a popular static type system/framework/language for spa backend development that is competitive with the likes of Elixir/Phoenix, Larval/PHP, Python/Django?
I had always avoided using any CSS frameworks because I wanted to master and also maintain complete control over my CSS, but after having used Tailwind for a few projects now, I don't think I would every want to go back to writing raw css ever again.
My best guess is, you get your DRY properties by re-using app-specific components that use utility classes, rather than by re-using app-specific CSS classes?
Trying to figure out why people think it's a good idea. It's certainly not the vision of web dev I was trained on.
If I can chime in here, yeah that’s the gist although I’ll say Tailwind isn’t a panacea. My team and I still write vanilla CSS, but it’s less common and much more navigable. It’s usually because the Tailwind version (if the utilities exist) would be unwieldy.
When I started writing CSS I would commonly encounter modestly sized websites of only a couple hundred pages with 17 thousand lines of CSS or more because of frameworks like Bootstrap. At least a few hundred of those lines would be overrides and just as many would probably be redundant.
My team launched a 6 thousand page website this past year with only a couple hundred lines of vanilla CSS and roughly 3 thousand lines of Tailwind generated CSS total.
At the end of the day, Tailwind is a zero-runtime, tree-shakable CSS framework generator. The burden of naming many common and universal design artifacts is alleviated. Class reusability goes through the roof. Custom stylesheets regain the ability to be edited with confidence again. It’s good. It makes the HTML a bit bloated and ugly which deters people at first, but dev tools pick up the slack and so far I’ve yet to see any performance impact there.
pcthrowaway is more or less right. Tailwind dramatically improves code coverage. A majority of tailwind's common utilities are used in every page's components or templates.
There are exceptions. We could use postCSS to code-split critical paths for CSS. It sounds like a fun side project for some framework's ecosystem. Unfortunately, the current state of CSS is very much good enough for me for now. I'm much more concerned about main thread work from JavaScript and optimizing images for the web, for example.
Two things you must keep in mind with Tailwind that are key to its success, they are:
1. It gives you bunch of sane defaults around colours and spacing. If you consistently use Tailwinds classes then you'll get a nice grid and (usually) complimentary colours.
2. You're using a a framework or view library that supports reusable components. For React, this is obvious. For Phoenix, you use LiveView components or the Phoenix "static" components.
Tailwind only really works when you apply its classes to components, then reuse the components (or more tersely: "Reusable styles via reusable components")
Here is an important article about functional css (tailwind's model) vs semantic css (what you have learned): https://adamwathan.me/css-utility-classes-and-separation-of-.... You might disagree with it but at least it provides the reasoning behind tailwind.
I think I read that a while back, which is the main reason I'm able to get past the "visceral reaction" as he so aptly put it. The part about separation of concerns being a false hope and bad framing rings true: "concerns" in software are hazily defined at the best of times. Thinking about dependency between CSS and HTML also makes sense. But I don't really like his examples, and I'm not convinced his evidence reaches quite as far as his final conclusion. For one thing ".author-bio" should have been "#author-bio".
Thinking out loud, now: the problem of CSS and HTML depending on each other makes me think of the dependency inversion principle. Basically, make both of them depend on some common interface or protocol, so they can change independently. Utility classes are in the same territory, but I don't think it's reasonable to demand that the shared language be app-independent, or put another way, to demand that a library author relieve you of the burden of naming your domain objects.
I suspect the ideal approach is app-specific "content-agnostic" classes, defined in terms of some library of helpful classes that are not themselves directly invoked in HTML, with #ids as needed for specialization. But I don't know, maybe I'll just try to the tailwind thing out on a new project.
For me Tailwind is an elegant and powerful design language, one which has sane defaults, and which gives me the opportunity to experiment quickly and instill life in the structure of my html right there where I type it, with just a few keystrokes and no change in context.
CSS isn't special; HTML and JS have similar needs for reuse and customization. It doesn't make a lot of sense to have a completely separate solution that solves this problem for CSS only.
>First, you can customize your core UI components to suit whatever needs, designs, and tastes that you have. If you want to use Bulma or Bootstrap instead of Tailwind – no problem! Simply replace the function definitions in core_components.ex with your framework/UI specific implementations and the generators continue to provide a great starting point for new features whether you’re a beginner, or seasoned expert building bespoke product features.
I mean I would think easily overriding it would be sending a -notailwind parameter when using a site generator or something. The above is not easily although not hard either. With a small amount of effort that might irritate you if you don't want to use tailwind is what is sounds like.
> If you want to use Bulma or Bootstrap instead of Tailwind – no problem! Simply replace the function definitions in core_components.ex with your framework/UI specific implementations
"Simply" here means rewriting a 661 lines file. Maybe a more modular approach with only Tailwind support at release would have been better.
I know I'm always the "Symfony does it better" guy but in this framework to use Bootstrap (or Foundation etc) for my forms[0] I "simply" have to put:
its done in such a way that people will be able to write modules that automate this for you. I can already imagine a boilerplate generator being created for this
You can do `-no-assets` or `-no-html` or even delete that file. All the generated code is here to get you started and generate the default "hello world" page. But none of it is necessary.
the "but there's always an escape hatch if you want/need it." is the critical difference. phoenix is super modular. In rails, you're really locked into a certain way of doing things. I've never felt like I've been corralled into a specific way of doing things that couldn't easily be changed with an hour of work at most.
I'm curious - what in Rails is like that? I've been doing RoR for a long time, and while "Rails is Omakase", I've never felt it was hard to swap out a component.
I don't think there is a definite answer for "what a property designed framework" is but I can try to explain where Phoenix sits in the possible trade-offs.
One possible approach frameworks use to provide escape hatches is configuration. You ship with a series of defaults and, once you want to change it, you need to find out the proper knob to turn. A downside of this approach is finding the proper knobs when you need to tweak it.
Another approach is code generation: you generate code (or configuration) and keep the knobs clear to user. There are still defaults (and conventions) but the knobs are laid out upfront in your application. The downside here is that having so many knobs upfront may seen daunting or noisy.
Since you mentioned Rails, I will provide references on how Rails and Phoenix use those.
Both frameworks leverage both techniques above, but Phoenix errs more on code generation and Rails more on configuration. Here is a practical example.
Rails has a middleware stack that is part of all applications. This stack is hidden from you. Here is how the generator file for said application looks like:
Phoenix has a similar stack (called plug) and the default stack is part of your application. Here is the generator file for it (it is not part of your app but used to generate it):
You can look at these approaches and try to compare the pros and cons.
---
My biased opinion: I have worked with both and I prefer the Phoenix approach. I understand someone may find having all steps in your endpoint noisy or daunting, but the plus side is that it takes a glance to see all steps a request goes through and you can tweak it in any way you want.
When comparing to Rails, if you want to insert a middleware in the middle of the default stack, you need to explicitly say before or after which middleware. If you want remove something, you need to state the negation and say "I don't want to have this". Overtime this makes it hard for you to visualize what your application does, because you need to assemble the pieces in your head and use tools to print the stack for you.
This also matters on releasing new framework versions. Because Rails has its own stack, if it changes the default middleware stack in any way, it can slightly change how your code. What if the middleware you were inserting before was moved up? Or removed altogether? Or maybe a middleware you deleted was replaced by another one, with similar functionality. Do you want to remove it too? This can lead to subtle differences of behaviour when upgrading.
The code generation approach requires you to opt-in to the new features, which is, IMO, one of the reasons why Phoenix could avoid breaking changes in the last 8 years or so.
This is in no way a knock on Rails. I am 100% confident the Rails team is aware of those trade-offs and could equally argue for their choices. It also isn't a binary choice either, both frameworks use both approaches, with some general preferences for one over the other.
It fits pretty neatly with components in LiveView, so for the sake of the default generators it makes sense to include. It's super simple to remove it and write components however you want though.
What's with you? You keep jumping in making negative comments only partially based in reality. You don't like Phoenix? Fine, who cares. But please don't keep spouting nonsense.
I've been a Rails/Ruby developer for close to 10 years now I think and while I haven't used Phoenix/Elixir professionally, it's been my go to for a ton of side projects (The backend for my esports annotation tool, https://vodon.gg/ and its companion app for schlepping large video files to coaches, https://www.fileyeet.io/).
The best way to sum it up would be slightly less magic then Rails, 3rd party libs might take a bit more work / copy and pasting code to integrate them into your existing codebase. You'll likely write a few more lines of code to achieve the same thing in Ruby, but the ability to use the Beam VM, tooling like LiveView more than make up for the lack of magic. Even better, you'll soon appreciate the lack of magic as refactoring Elixir programs is a dream. It basically just boils down to separating out large functions into smaller composable functions.
I also must add, the community is also awesome.