4 Principles for all programming languages
Sandro Maglione
Get in touch with meWeb development
21 February 2024
•4 min read
Sandro Maglione
Web development
Some coding patterns stay true regardless of programming language.
No, this is not about OOP, functional programming, design patterns, or anything like that 💁🏼♂️
This is all about shared problems with every codebase, and how to solve those problems:
- Error handling (
Either
/Option
)- Dependency management (Dependency injection)
- Debugging (Logging and observability)
These were the same when I started with PHP, with Java for Android, Dart, Typescript, and all.
Let me share this with you 👇
Tech stack
- Effect: I am exploring these principles and how to solve them with Effect lately. The same ideas can (and will) be applied to other programming languages
Setup
This week I explored more of the Effect API.
Principle 1: any usable language must provides tooling (documentation, IDE support, types, debugging)
This is why working with Typescript and Dart is great: the IDE support is next level 🚀
Get started
I rewrote some native Typescript code to Effect to learn the differences.
Principles 2: Error handling requires
Either
andOption
(try/catch is flawed)
Errors cannot be ignored: they must be explicit at the type level.
Effect collects all possible errors, you know exactly what can go wrong. You can then handle all the errors in one place.
"If it complies it works" 🪄
There is more.
Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 600+ readers.
Implementation
Solving error handling is as simple as this 👇
You only need to be explicit: sometimes things go wrong (Left
) and sometimes they work (Right
).
This removes any try/catch, throw, exceptions, or whatever.
Scale complexity: Dependency Injection
Second (major) problem: organize code dependencies to loose coupling and simplify testing.
Principle 3: interfaces and dependency injection
Effect uses services and layers: define interfaces, and only at the very end provide concrete implementations.
In the above code there is no mention of "how" this is implemented.
Nonetheless, we can still use the service, since the interface is enough to know what this does:
We can then "inject" the implementation only at the end:
This allows full control over each implementation, and more flexibility for testing ✅
Logging and observability
How do I make sure everything works as expected?
Principle 4: debugging/logging/observability are not afterthoughts, they are core to every codebase
Effect provides a full Logger
module for message reporting (fully customizable with dependency injection 🛠️).
Often times logging is not enough. We need full observability.
Effect provides APIs for Metrics and Tracing:
- Tracking a Value Over Time
- Request Counts
- Error Counts
- Memory Usage
I have still a lot to explore on these APIs 🤓
This is your starting point to start converting your codebase to Effect 💡
Takeaways
- Every programming language shares similar challenges
- Some principles stay true regardless of your programming language or framework
- The main problem is managing complexity: explicit errors and dependencies using types helps scaling
- Effect is spearheading a new paradigm, but this applies to other languages as well 💡
I am flying to Vienna this week for the Effect Days ✈️
Next week is all about the conference and all the new innovations, learnings, and takeaways from it.
Trust me: you don't want to miss this 🤝
See you next 👋