Contexts - a barrier too high for newbies?

About Phoenix is not your application. For me it means Phoenix is not your whole application. Don’t think of your logic being part of Phoenix application, but rather other way round. Phoenix is just a part of your application, call it a frontend, or UI, or whatever. But write your app in such a way, that it can live on it’s own without a phoenix, so that you can add a CLI for it easily or desktop GUI, or another interface for communication, like system bus, or other than HTTP network protocols. Because you newer now if you’ll need that and writing it like this does not cost anything, beside more thinking how to structure your interfaces well.

6 Likes

I think it happens in startups rather a lot, and startups also place the highest priority on a stack being quick and easy to get stuff built, which is one of Phoenix’s selling points.

Where did you get that from? On the frontpage of the framework I read the following:

A productive web framework that
does not compromise speed and maintainability.

The latter part is exactly what the recent 1.3 changes do address – not compromising maintainability for a notion of being “faster”. I’m certainly of the opinion that the new contexts are explained/marketed in a bit to complex fashion, but the general idea of moving business logic out of phoenix controllers is a much needed change.

4 Likes

I see a few issues/arguments that pop up and never get resolved in these Context threads.

  1. Real examples that have 20+ schemas, 20+ endpoints, real use cases and real business requirements. This is probably the number one thing that will help the community with this problem. It is still early, so I’m sure that this will come in time.

  2. Not acknowledging that a large part of web application development is simple crud. The problem is that contexts add ceremony with little value.

  3. Pretending that the mess made with contexts will be a better mess.

  4. Naming stuff is hard and now we have to name three things the Context namespace, the struct, and then add an interface from the context and the web world.

Most of these are just educational issues that would be better solved by publishing lots of code and blog posts :grin:

However, there is a very real need for a standard “I didn’t know what to name this thing, it doesn’t really matter, stop trying to make it matter, just tell me where to shove the thing so I can get back to shipping features.” I think that providing a good enough guideline for the community would yield the incremental change that we need to move forward.

12 Likes

The first word is productive, and not holding people’s hands isn’t compromising on maintainability. If people choose to build non-modular code (which they will still do with contexts anyway), that’s on them, not on Phoenix. Phoenix hasn’t compromised a thing by not trying to steer them to the right place. The right way to get people building better apps is through examples, tutorials, and best practices, not by adding a roadblock to them getting stuff done, even if that roadblock is a very minor one.

If you really feel the need to put something in the actual Phoenix code to encourage modularization, implement something like checking their code whenever a generator is used and spitting out a y/n message to the console along the lines of

Your app looks like it might not be following modular coding best practices.
Check out <some link> to learn more about modularizing your app.
Are you sure you wish to continue? Y/n

I am having a really hard time with this argument. So over everything they need to learn, code organization is the one thing we are going to move to the end of the queue?

Elixir never shied away of introducing concepts to developers: functional programming, pattern matching, immutability, etc. Since nobody seems to be questioning the merit of contexts, rather its accessibility, then the obvious answer is to make it as accessible as possible, as we did the concepts above.

The way to make this discussion productive is:

  • If developers are acting condescending, let them know about it. The fact different people in this thread have different understanding of what “Phoenix is not your application” means, indicates that you were spot on, and that the “meme” needs to be phased out

  • Developers need to bring cases and evidence of where contexts work and where contexts don’t. When someone says “contexts are terrible, you should remove it”, to me it feels the equivalent of going to the doctor and saying “my leg hurts, you should remove it”. You very likely want the people that lead the open source projects that you use to take informed decisions, so please help us with cases and evidences

In this thread, we have seen some examples of people having positive experiences with contexts and that’s great. But I have found struggles in other threads, such as when to split contexts, how to access data across contexts, what about umbrella applications, etc. Now is the time to collect those struggles and address this in the documentation, guides, books, blog posts, etc. If after a few iterations the concept is still not clear, then it means something more drastic needs to be done, maybe even remove the feature altogether.

So if you or someone you know are struggling with contexts, let’s talk about those cases, rather than jumping to the conclusion that the leg should be removed. Although I disagree with the premise that contexts are terrible for the future of Phoenix, I am always glad to hear about places we can improve.

13 Likes

But those things are all part of the language, rather than how you use the language.

I do agree that more conversation and knowledge sharing is key to all of this. Getting some more of that rolling was my main purpose in this thread, and I’m more than willing to be shown that I’m wrong.

4 Likes

I’m 100% with José on this.

I would argue that a large number of people came to Elixir and Phoenix for perhaps two reasons in particular:

  • Performance / scalability (which we get thanks to Erlang/BEAM)
  • A better way of doing things (which we get thanks to ideas and conventions that José, Chris and others are introducing and incorporating into core areas)

I also believe these are some of Elixir’s best selling points.

While there are quite a lot of early adopter ‘newbies’ (all power to them!) currently the language is most attracted to developers with a little more experience… but this is working out really really well, and not only bodes well for the future of Elixir and Phoenix but will ultimately benefit newbies in the long run.

So personally I am all for contexts and other best practices being incorporated or promoted so long as they are clearly explained; whether via books, guides, talks etc - which the community has already said it’s committed to… we just need a little patience :slight_smile:

Check Hex source code for an example application that is migrating from 1.2 to 1.3. It is a very interesting example because in some places it is in a mixed state, with logic still in the “models/schemas”, which is what you would expect a real world application to look like. We definitely need more examples though.

My intuition is that crud is actually nicer with contexts than without contexts. That’s because even when crud-ing, the resources are still related, and the context keeps this relationship together. In the scenario you are mindlessly generating stuff, then the only extra input that contexts require is the context name. CRUD still works.

I am confused. Aren’t those two? The context and the struct? Except by the context name, all names are inflected from the struct.

Isn’t that exactly the problem contexts are trying to solve? How do you go from pattern matching and functions to building actual software?

1 Like

I dunno. It just seems to me like it’s a situation for best practices. Should the code refuse to compile if a function is over X lines or uses nested ifs?

Contexts don’t go far enough IMO. They give you the worst of both worlds.

1 Like

Maybe not compiling it a bit too harsh, but a warning would be nice :wink: Still Phoenix do exactly nothing when you don’t use context, it does allow you to not use them. So it’s not comparable.

Please be more constructive. If you feel they have shortcomings, please explain what you feel those shortcomings are. If you feel they can be improved, please lay out your proposals on how that can be achieved, thanks.

8 Likes

That’s not the goal of the compiler. It is probably the goal of a framework though.

Even if we take this statement at face value one would hope that at a decent number of entities the decisions at least in part are driven by experienced developers so there is nothing wrong with having a framework that is better understood by people with some experience.

I could also point out that there are no technical reasons for endpoints, routers, controllers, and views. You could have all of this functionality implemented in a single module. Surely grasping a “hello world” web app powered by one module would be easier, due to less moving parts. If short-term productivity (which I personally like to call seductiveness) was the only goal, Phoenix would be failing consistently from the day 1.

Moreover, my experience is that one can frequently gain short-term productivity by sacrificing maintainability, so to some extent there are trade-offs here. As a bystander and merely a user of Phoenix, my understanding is that the Phoenix team is aiming to find a good balance between the two. So, while the productivity is certainly a goal of Phoenix, it’s not the only goal.

Personally, I think that the new version strikes a better balance. I base that conclusion on my team’s real-life experience with Phoenix 1.1/1.2 where the defaults proposed by the framework helped us produce a less maintainable code. The fault for that was ours, but contexts would have pointed us in the right direction. Given that the mental overhead of contexts is IMO very low, I think that the gain is well worth it.

10 Likes

I’ll be peeking at the hex example: GitHub - hexpm/hex: Package manager for the Erlang VM didn’t know that was a phoenix app :slight_smile:

For some things, absolutely it’s been super nice and clean to work with, credit where credit is due.

For other things, it feels like one layer too deep from the web app. It’s like I’m forced to wrap every call to Repo.update with NotARepo.update. It’s clean when it’s needed, but when it’s required it’s tad overly formal.

Get rid of create/update/delete/list/get/exists function names and replace them with names that are meaningful to the context. For example, Scheduler.meetings_this_month Post.submit_reply Calendar.add_reoccuring_event. By my count that is a context name, the database struct or whatever the context trying to abstract, and the function that defines the interface to the rest of the application.

It’s those none crud things which bring the most value to contexts, however, only a small percentage of my application really benefit from them.


The most concrete issue that I deal with is when the database table is just a database table.

In my little project, I have about 60 schemas and growing. 20 of them are purely just a schema/database table. The fun part is that any of those 20 schemas are fair game for any other part of the app to depend on, have reference to, and have collections of. I guess the app is the context for these things?

The second issue is when I start a new project that is when I know the least about it. It is pretty hard to divvy up an app into meaningful parts when you are not exactly sure where things fit. Some sort of blessed dumping ground like lib/core or lib/schemas and some tools to refactor to contexts would be very welcome.


Thanks for all of those participating in these threads. They can get heated but I know it’s because everyone deeply cares about the tools they are using. I’d be worried if everyone just went with the flow around here.

Cheers!

2 Likes

That one is an issue I noticed as well. While I feel it’s good to have people think before diving deep into details it surely feels like a blocker as well. But in the end everybody is free to simply use the context “Core” or “App” for as long as the contexts are not clear enough.

That’s one reason why I’m hardly using the generators anymore. Creating the modules manually is often as fast as (remembering the correct cli syntax and) deleting all the generated crud stuff.

4 Likes

I wonder how much cheating would it be to do something like mix phoenix.gen.html Posts Post "posts" ... for those cases. Although I can see that if you are going in this direction, then contexts definitely feel like boilerplate.