I hope you'll give me the opportunity to try to convince you otherwise.
I understand the context of this is that io-ts puts an onerous emphasis on FP concepts and data structures. But FP principles, when applied in an effective and usable way, are quite good. The make it easier to reason about and maintain code.
One such principle is that a "function" with no parameters is a good sign that it will cause some kind of side effect. I sort of hinted at this when I questioned the design, when I said that it wasn't clear to me whether calling these functions was producing new instances and whether those new instances affect behavior.
I would also argue that leaving room to parameterize primitive types is leaving room to make a drastically more complicated API in the future. A `string` with "options" suddenly becomes its own sub-API.
While io-ts is more complicated, once learnt its API is more predictable. A `Type` is a value. An `interface` (or similar) type is a `Record<string, Type>`. Always. `Type`s can be augmented/composed/etc (and you may provide a function that accepts one or more `Type`s as parameters to accomplish that), but they always resolve to a value. The value can be reused without concern about side effects.
Very strongly agreeing with this assessment and hoping Colin will come to agree.
A zero-argument function is either a constant, or a side-effect. Given we don’t want a side-effect, exposing a constant instead of an effectful-looking function is preferable.
I understand the context of this is that io-ts puts an onerous emphasis on FP concepts and data structures. But FP principles, when applied in an effective and usable way, are quite good. The make it easier to reason about and maintain code.
One such principle is that a "function" with no parameters is a good sign that it will cause some kind of side effect. I sort of hinted at this when I questioned the design, when I said that it wasn't clear to me whether calling these functions was producing new instances and whether those new instances affect behavior.
I would also argue that leaving room to parameterize primitive types is leaving room to make a drastically more complicated API in the future. A `string` with "options" suddenly becomes its own sub-API.
While io-ts is more complicated, once learnt its API is more predictable. A `Type` is a value. An `interface` (or similar) type is a `Record<string, Type>`. Always. `Type`s can be augmented/composed/etc (and you may provide a function that accepts one or more `Type`s as parameters to accomplish that), but they always resolve to a value. The value can be reused without concern about side effects.