It's tough. Choices have to be made and decision taken.
After spending years experimenting (and even professionally working) with Node.js I think it's time to say farewell and thank for all the fish.
Why?
There's several reasons but the main for me are:
Asynchronous IO is tough. Really tough. Callbacks, Promises, Async/Await all that stuff. Sure, Async/Await will make this easier but under the bonnet it will still be async. I think the cause of this is that we think sequentially - do this, do that do something else. Not do this for user1, do this for user2, do this for user3, do that for user1, do that for user2 ... The fact that we serve several users at a time doesn't have to be reminded to us all the time.
Debugging and testing is pain with callbacks. As async functions are normally executed in their separate threads you lose continuity when your functions resumes. It's hard to track down where you'd been before the callback got called. And simulate callbacks in unit tests doesn't help either.
Dependency management. NPM everywhere. Node.js doesn't have its own packaging, module system and relies on NPM to do the hard work. Problem with NPM is, that if package A depends on package B and that depends on package C it's all nested and not reused. That means, you can end up with hundreds of packages C in your project. I still remember my Ghost blog project. It downloaded 500MB of NPM modules just to run!
Spartan core libraries. Node has very limited number of standard functions. It means that even for simple tasks like working with dates you have to turn to libraries like moment.js. Most of the stuff you can find in standard libraries in other languages needs to added as a dependency in Node. So you always facing decisions like `lib1 has these features but lacks some other` so you mix and match all the time to get basic stuff done.
No opinion. We all know that today's patterns and best practices are tomorrow's anti-patters. But this cycle is massively accelerated in the Node.js world. Grunt, Gulp, NPM. This is rapidly changing and there's no sign of consolidation. It's hard to operate in a world where tools are discontinued on a daily basis (with no replacement). Node needs something that would define and guarantee the basics so you can focus on programming and not worry if your code will be buildable in a year's time.
No explicit types. We can probably debate this for ages but as there's no way to enforce types (at least optionally) it's very hard to define contracts between libraries and their users. There's nothing that would warn you that a return value can't be assign to your variable. Or calling a function isn't possible because of incompatible types. That puts extra pressure on library authors to well document their code so the types are documented, somehow.
To sum it up. On front-end I'm left with no choice - it has to be JavaScript or transpiled JavaScript. For backend though, I stick to something else.
Friday, February 12, 2016
Wednesday, February 10, 2016
Striking the right balance
We all know that software can be really complex. Software solves complex problems and needs to be complex. Period. But when it comes to our toolkit we should always prefer simple, streamline solutions.
Software development can sometimes morph into some kind of competition. Some developers and sometimes whole development teams can turn into macho style super heroes producing pretty complex code just to show the world how good they are. So you want an example - look no further than AngularJs. That's what happens when smart guys over-engineer their solution.
Dependency injection for a functional language? Services, providers, factories? Parsing function bodies to figure our parameters? You get all this and more. The question is why? Functional languages always prefer explicitness before implicitness. Functional approach tries to eliminate auto-magicalness. And why have so many service types? Who needs to use magic string constants to describe what a directive can be applied to? Yes, we know the guys behind Angular are smart but do we need to worship them everyday?
Again the same story. All you get is something to learn. And once you learn it you the guys release version two do zero with no backward compatibility. And you start over again.
On the other end you have things like Hazelcast. You don't need a diploma to use it. You plug it in as a library or use it as stand-alone application and it just works. Don't be fooled. Hazelcast is far more complex than Angular. Both in terms of code and the problem area it covers. But the guys there don't try to awe you. And that's the trick. That's why React is so popular.
So the rule is - don't try to convince your users that you're a smart guy by writing complex difficult libraries - convince them (if you really need to convince anyone) with simplicity.
One rule of simplicity is to reuse whatever is out there or at least allow this existing tools/libraries/utilities to be used with whatever you're coding.
Don't be revolutionary - be evolutionary.
Software development can sometimes morph into some kind of competition. Some developers and sometimes whole development teams can turn into macho style super heroes producing pretty complex code just to show the world how good they are. So you want an example - look no further than AngularJs. That's what happens when smart guys over-engineer their solution.
Dependency injection for a functional language? Services, providers, factories? Parsing function bodies to figure our parameters? You get all this and more. The question is why? Functional languages always prefer explicitness before implicitness. Functional approach tries to eliminate auto-magicalness. And why have so many service types? Who needs to use magic string constants to describe what a directive can be applied to? Yes, we know the guys behind Angular are smart but do we need to worship them everyday?
Again the same story. All you get is something to learn. And once you learn it you the guys release version two do zero with no backward compatibility. And you start over again.
On the other end you have things like Hazelcast. You don't need a diploma to use it. You plug it in as a library or use it as stand-alone application and it just works. Don't be fooled. Hazelcast is far more complex than Angular. Both in terms of code and the problem area it covers. But the guys there don't try to awe you. And that's the trick. That's why React is so popular.
So the rule is - don't try to convince your users that you're a smart guy by writing complex difficult libraries - convince them (if you really need to convince anyone) with simplicity.
One rule of simplicity is to reuse whatever is out there or at least allow this existing tools/libraries/utilities to be used with whatever you're coding.
Don't be revolutionary - be evolutionary.
Subscribe to:
Comments (Atom)