8 ms·
Something like Phoenix? Elixir is a newer language, with a lot of similarities to Clojure. Phoenix even made the most loved web framework in the Stack Overflow
by suprfnk 4y ago
Something like Phoenix? Elixir is a newer language, with a lot of similarities to Clojure. Phoenix even made the most loved web framework in the Stack Overflow 2022 survey.
Why did they converge on something so, apparently, great, in such a low amount of time? And why is this so hard for Clojure?
Not taking sides or trying to be negative, just honestly curious what the driving factor is.
- weavejester 4y agoI haven't used Elixir enough to be particularly confident in an opinion about it. However, Phoenix appears to have a similar design to many other MVC frameworks, and if a conventional design works for a language, there's less need to experiment. Initial development can converge around something that's tried and tested. A conventional framework doesn't fit Clojure particularly well, so the community has been forced to tread new ground to figure out what works with the language.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- jmcgough 4y agoElixir is a functional language as well, and borrows inspiration from Clojure in particular. I haven't dug into Clojure enough, but I'm curious why you think a conventional MVC-style framework wouldn't be a good fit (not that the article is making this argument).
- didibus 4y agoElixir is still Actor based though, and relies on modeling behavior through something very akin to objects. You could even call it OOP if you went back to the more original message passing/late binding roots of OOP.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- bcrosby95 4y agoKinda? I guess it depends upon what exactly you mean. If you mean behaviours, structs, protocols, modules and maps, then I can kinda see that, although Clojure has most of these too. But if you mean actors? Well... I view Elixir as two languages in one: an actor language, and a functional programming language. Sometimes you gotta use the actor language (processes) to model behavior, but it's far better to leave that to the FP aspects. The problem with using processes is there are a lot of concerns that only they can handle. To be fair, I'm only a hobbyist Elixir dev. But there's lots of misinformation about how easy Elixir makes certain things. In my experience, it's not easy to build a process tree that factors in concurrency and synchronization, much less fault tolerance on top of that. Nevermind performance and gc isolation. Adding modelling on top of that just makes the job way harder. The only real thing processes have in common with objects is they both hold state. Messages are kinda similar to methods if you squint hard enough, but there's more differences than similarities. Everything else listed above has nothing in common with any given object in your average object oriented programming language.
- didibus 4y ago> If you mean behaviours, structs, protocols, modules and maps, then I can kinda see that, although Clojure has most of these too. But if you mean actors? Well I kind of implied all of that, but I was specifically referring to the concept of modules and all its feature-sets, which together, in my opinion, does lead to a more OO like style of programming, especially structs, processes, behaviors and use, those things I feel are really similar to classes and inheritance. And there's also the dotted syntax for both map and struct access. While yes, it's different than your common OO, in practice, you end up using these things similarly. In Pheonix, simply put, almost all extension points relies on the __using__ macro, __MODULE__ compile time macro and use keyword. So it ends up very similar to an OOP framework, you basically extend classes, but you do so by using `use` instead of using `extend`, and a macro that copies over code and dynamically set the module name, instead of having an inherited lookup table. How it's achieved is very different, but as a user of Pheonix, the ergonomics end up very similar. Look at this: defmodule TodoWeb.ItemsController do use TodoWeb, :controller alias Todo.Items def index(conn, _params) do items = Items.list_items() render(conn, "index.html", items: items) end end Yes, this isn't exactly a class, but like: package TodoWeb; import Todo.Items; class ItemsController extends TodoWebController public index(conn, params) { var items = Items.listItems(); this.render(conn, "index.html", items); } } How similar is the user experience? And TodoWebController similary uses Phoenix.Controller, etc. It gives you a very similar feel to an inheritance tree, and pluging-in behavior in the framework by class extension. Namespaces in Clojure really don't have this feel to them at all, now maybe you could shenaningan something similar with some similar macro convention over namespaces in Clojure, but it definitely isn't encouraged by the language or community the way it is in Elixir. So in general, I feel modules in Elixir have a much closer feel to them to classes/objects in OO languages, and you end up using them similarly, where-as that's not the case for Clojure namespaces.
- weavejester 4y agoThis is a topic that I think requires a more in depth article, but I'll attempt to justify myself as best I can in the limited space of a comment. In most languages, related data is generally represented by some manner of closed record, struct or object. In Clojure, this data is represented by open maps instead. This distinction may seem minor or even irrelevant, but in my view it's the key difference between Clojure and other languages, and the reason why the MVC pattern has never quite fit comfortably in Clojure. In a language that uses closed records, complex data tends to align itself in terms of fixed hierarchies. Think of how the models in Rails are typically laid out. You have a few dozen models, with a handful of fields each, arranged in some sort of static tree or graph. In Clojure, data doesn't tend to align itself in the same way. Data doesn't need to be artificially grouped if there's no benefit in doing so; its structure can be much more amorphous. There's a similar problem at the "view" end. REST tends to assume a hierarchy of resources, when that may not be the best way for the client to get the data it wants, or for the server to represent the data.
- jb1991 4y ago> Data doesn't need to be artificially grouped if there's no benefit in doing so; its structure can be much more amorphous. I'm curious, just because Clojure offers that flexibility to a developer when writing the logic in their app, why does this flexibility need to "interfere" (for lack of a better word) with the design of a web framework?
- weavejester 4y agoFor the same reason you wouldn't design a web framework in Ruby that doesn't use classes. Technically possible, but you'd be fighting against the design of the language.
- ithrow 4y agoIn Clojure, this data is represented by open maps instead. Is Clojure unique here? seems this is the norm for Javascript applications too, that are done mostly with a FP style, instead of open clojure maps you have open JS objects. Most JS SDKs and libraries I have work with is just passing JS objects between them and your code.
- refset 4y agoMaybe it's because Clojure has typically attracted a demographic who are more shy about self-promoting and marketing their new ideas and tools. Photon is an exciting (and relevant) example defying that trend though: https://www.hytradboi.com/2022/uis-are-streaming-dags https://www.hytradboi.com/2022/uis-are-streaming-dags Also relevant as a Phoenix-like alternative for Clojure: https://github.com/tatut/ripley https://github.com/tatut/ripley
- cutler 4y agoCase in point. Ripley looks promising but it's just one dev and his single page Github doc. Useless to a newcomer or business looking for a framework for the long haul. Clojure has dozens of these projects.
- didibus 4y agoBecause there's no alternative in Elixir. In Clojure, you can make a website many other ways, use any existing Java server, implement your own server quickly, use any templating language you want, implement your own quickly, use whatever routing lib you want, implement your own quickly, etc. Not only are there existing options from Java, but implementing your own is approachable to your average dev, and can be done in a reasonably short amount of time. Maybe it's a bit of the Lisp curse afterall. A language too productive, that no one bothers settling for the one framework. I also think Elixirs Ruby friendly syntax brought in a lot of Rubyists with Rails experience, and that attracted people who used Rails to Phoenix, giving it that inertia. Chris McCord used to be a Rails developer, so he came directly from Rails, so it made sense to rebuild a similar framework for Elixir, and a lot of people followed from Rails to Elixir as a better ruby with better scaling.
- lvass 4y agoElixir is close to a different syntax for Erlang/OTP. It has high quality built-in alternatives since it came into existence.
- didibus 4y agoErlang is not commonly used for web applications though, with Clojure, you had existing Java shops with Java web app who transitioned to using Clojure, simply keeping their Java web framework and writing their business logic in Clojure instead. If you adopted Elixir, you most likely were starting from scratch, a green field project. Since Erlang is already great at concurrent distributed systems, Elixir's niche became web application development, and it didn't have much existing libraries or frameworks to leverage, so I think it makes more sense for an initial popular framework to come to existence and rally others around. It still built on Erlang fundamentals, its web server is Cowboy for example, but there wasn't much on top to help with other parts of a web app.
- jb1991 4y ago> In Clojure, you can make a website many other ways, use any existing Java server, implement your own server quickly, use any templating language you want, implement your own quickly, use whatever routing lib you want, implement your own quickly, etc. The thing is, many (most?) developers are interested in building the end product, not building or heavily researching the ideal framework/library/stack itself. Without something easy to use, widely understood, and that has all the pieces hooked together, a lot of developers will get frustrated and seek different pastures so they can just concentrate on a product. That's why Rails and other similar libraries in other languages are so successful and make those languages successful, because a key layer is handled for you so you can just get higher-level work done. I used Clojure many years full-time and liked so many things about it, but the myriad ways to do the same thing does not appeal to everyone. This also extends to other aspects of the language -- the many different development environments and tooling, hooking together all the various ways to actually write, develop Clojure code. Many developers also don't want a lot of their time spent building a development workflow.