Flutter: Why generate code?
Code generation involves the use of annotations or configuration files to automatically create some other code. For example, when using a package like Freezed, you can annotate a class as shown in the example below
@freezed
class Person with _$Person {
factory Person({
required String firstName,
required String lastName,
required int age,
}) = _Person;
}
Freezed would then generate a mixin that adds a copyWith, equality operator, hashcode and toString method to the class Person. Pairing it with another code generation package like json_serializable would enable adding json serialisation (toJson and fromJson methods). So why would we use code generation?
Advantages of code generation
Less code to write
Code generation helps take care of parts of writing code that can be automated away. If you write flutter in a way that favours immutability, there’s a chance that you’ll be writing copyWith, equality, hashcode and toString methods for most of your classes. Using code generation helps you not need to think of these as your focus tends to be more on what properties the class should have.
Less errors
As humans, it’s not a matter of if but when we’ll make errors. An example is when, while changing the properties of a class (e.g. adding a variable), one might forget to change the references in other methods. Automating this away helps to prevent such.
A different example is in the v2 syntax of riverpod that depends on code generation. There are situations where you might want to override providers in different widgets (Granted, this is not a recommended approach, but it happens). It’s easy to make mistakes when you’re not very familiar with riverpod. Code generation helps prevent such mistakes without needing to think about them.
Easier maintenance
Since we’re writing less code in general, it’s easier to maintain the code. We have fewer pieces of code that we have to keep in mind when editing code. And the more consistent behaviour of automation also makes it more predictable.
More Flexibility for package authors
Code generation can enable package authors support simpler syntax. They can use code generation to do things that are not supported natively by dart e.g. syntaxes similar to function overloading. This can greatly simplify the API that other developers need to interact with when done well.
Disadvantages of code generation
Like most things in software development, there’s always a tradeoff.
May be slow
If you’re using an underpowered machine, or if your codebase is fairly large, you’re likely to face long build times as the code generation tool does its work. This may be frustrating enough to discourage developers from using code generation
Dependency on third party packages
Writing the tools for code generation is a difficult and time consuming endeavour. It makes more sense for most developers to use the tools that already exist. Doing so increases the number of third party packages you’re depending on. This is not a negative in and of itself, but one has to take time to evaluate the tools they would be using. Using third party packages is putting trust in the maintainers of those packages — both in their code and in their continued effort to maintain the packages.
The advantage of most packages being open source is that you’re also able to make contributions when needed. Therefore depending on the third party packages tends to not have as much of a downside.
End note
Having tried code generation for a bit, I would highly recommend it. Anything that simplifies developers’ lives is a welcome addition to the community. What’s your experience with it?