I work with Akka streams, actors and http every day and and while I agree that Akka is really well documented, incredibly powerful and as you say polished, it is also the bane of my existence. It has made what could have been a simple application a rather painful experience for newcomers and even very senior engineers. The complexity of a framework like Akka is a huge barrier of entry for engineers and hinders development more often than it helps.
This is all obviously very subjective.
They get big, but it is not right to confuse size with complexity. A huge state machine (size measured by the number of states) can be quite simple. Both in the whole, and each state transition can be isolated and considered independently
I’d much rather deal with a large state machine than something that does the same thing, but implicitly or inconsistently.
That difference in the odds of success increases by an order of magnitude again once you start talking about distributed data.
Can you share a use case please?
For me personally I'm using Akka to mangage the processing and reprocessing of a lot of entities through some algorithms where the processing time can't be known upfront and the data is unbounded.
In terms of wanting something to tinker with then I guess building a chat application backend is probably the easiest one to demonstrate the complexity of trying to manage that (and there are also some demos in the docs as well)
Would be interesting to compare Akka based solution to your problem with a hand rolled alternative.
So many undocumented hooks everywhere.
> A framework with strong primitives makes it easy to create custom
> functionality that is still consistent with the framework's conventions.
> But a framework thatrelies too much on magic makes this much harder.
This is what Laravel got right. It uses "Facades" (which differ from the Facade pattern) for the magic, but you don't have to use them. So socpers (Stack Overflow Copy-Pasters) can copy and paste their Facades without understanding them, but when I need to fix some edge case or write some functionality the framework designers did not anticipate, I can do it by reaching for the lower-level objects.I've got tons of criticism of Laravel, but this is one thing that was done really really well.
I don't have very good explanation what I mean by heavy/light framework, this is the best I can do at the moment:
Heavy frameworks in my understanding are the ones that force constraints on your development process, application design, choice of other technologies and frameworks, on the types of products you can make with it, etc.
On the other hand light frameworks are like extensions of your fingers. They don't pretend to know better than you what you are trying to achieve. They just make a particular task easier for you.
The issue here is that heavy frameworks do not compose together very well.
You can safely have one heavy framework in your application.
When you start putting multiple heavy frameworks, they start colliding with each other and you start spending more and more time on resolving various problems that are not inherent to the domain problem that you are trying to solve but rather are completely accidental due to the technology choices you have made.
I don't agree that it's useful (not sure if you were being ironic). All of the "frameworks" I've used were determined to make my cog their subject. I haven't come across a framework that was content to be a cog in my machine.
[Edit] Subject, as in royal or imperial subject.
I say this point of view is useful because it seems like an elegant/simple way to distinguish them.
But what I’ve seen many times is that by the time you finish adding all the missing bits you end up with something as heavy as Rails, but non-standard. So now maintaining it is a huge burden.
If your code describes what is to be done without making the motions itself, you're using a very heavy framework or, honestly, DSL. These types of frameworks have lots of magic built into them and favor convention over configuration.
If your code performs actions imperatively, and moreover if it's explicit rather than implicit, then it can be easy to wrap or replace the framework. It's like a library.
Light ones: if I have a problem with the framework, I am guaranteed to have a local solution without getting rid of entire framework. For example, if Spring Framework does not let me create an object in a particular way, I can write my own function to create the object. If the way configuration is being located does not suit me, I can replace the mechanism without getting rid of Spring Framework or even configuration -- just by implementing couple of interfaces.
Heavy ones: if I want to do something that has not been planned for by framework creators I can potentially run into problems that I have no way out of without getting rid of it all.
An example would by systemd: it is built in an unnecessarily heavy way by insisting on you using it all. For example, if you don't like journald or can't use it for some reason -- tough luck. The only way to get rid of journald is to get rid of entire systemd.
I agree but, Isn't that almost a library...?
React does one thing. It’s arguably not a framework at all.
Maybe this was so in 2013-2015, but React today does a lot of things (module loading, component rendering, basic state management, scheduling, memoisation, caching), and will soon do even more (server components in some custom json format, rendering server). Gone are the days when React was a simple "view library"
> React does one thing. It’s arguably not a framework at all.
But that's React's failure, too. The lack of officially-supported libraries for common things such as routing leads to the horrible situation of having multiple competing, each-with-different-inconsistencies implementations of routing and moving from one React project to another transfers very little skills compared to other libraries such as Vue.And also my experience, very few libraries and frameworks are built on reusable internal primitives. I just tide time until those frameworks die so I don’t have to learn them.
If the framework needed a completely different abstraction to make it easy to work with, dropping down to a lower level will be incompatible, difficult and confusing.
Ruby on Rails...
A framework with strong primitives makes it easy to create custom functionality that is still consistent with the framework's conventions. But a framework that relies too much on magic makes this much harder. It's like all of a sudden you're surrounded with old Mainers saying "you can't get there from here" while you desperately try to cobble some kind of solution using ancient lore documented once long ago in a forgotten scroll.