I am reading Oleg Kiselyov's tutorial on tagless final interpreters. When implementing a DSL, what is the advantage of tagless final style over plain old datatypes (or say, GADTs)? I know when using normal datatypes, when you add new variants, you need to modify existing functions that operate on these types, and then you lose separate compilation. But does that really pose a huge problem in pract