3 ms·
Unidirectional data flow is what i see Simplicity, bidirectional is not. returning a [data, error] is simpler than a Try...catch. Simplicity means it's easier
by revskill 5y ago
Unidirectional data flow is what i see Simplicity, bidirectional is not.
returning a [data, error] is simpler than a Try...catch.
Simplicity means it's easier to test and debug it, it's not about easier to read or to write, or to compose.
- Jtsummers 5y agoIt can be simpler, but it isn't always. Returning a [data, error] could necessitate passing that error back an arbitrary distance in the call stack until it's handled. This necessarily complicates every procedure between where the error is handled and where it is generated. try/catch bypasses that complication of the code, but complicates the static tracing ability of the system to identify the actual control flow. Neither approach is strictly simpler as both approaches have distinct complications they add to the system. Your opinion is that simplicity is around debugging and testing, others have different ideas about it because they value different aspects of programming differently than you do. EDIT: To expand on my point, passing errors back directly integrates the error control flow into the "happy path" control flow. It's for a similar reason that I consider programs written to take advantage of concurrency to be "simpler" than straight linear programs, at least in many cases though not all. Even when the concurrency includes blocking statements that make the two versions equivalent in actual execution time (that is, no parallelism). The reason being that concurrency permits a separation of concerns rather than a tight integration. Real world programs often have a structure like this, where actions on different contexts are interleaved: create graphics context get some data construct a renderable version of data pass renderable version to graphics context repeat with variations The graphics context could sit in its own thread/process which only deals with the rendering, while the data processing sits in its own process. Separating out the two concerns may create a complication to the code (we now have at least two processes) but it also simplifies each block of code as they are more clearly describing their specific responsibility: graphics: create context loop: receive data render data data (graphics context): loop: get data construct renderable version of data transmit data to graphics context More moving parts, but the programmer is no longer having to manually interleave them. It's exactly the same program in performance (modulo context switching overhead, which may be too much in some cases) on a single core computer but a simpler program to maintain in other regards thanks to the improved clarity the now separated processes provide. Having a single control flow that integrates both error handling and happy path data handling can produce a similar kind of obfuscated interleaving of code which makes the actual program intent (both the error handling and the happy path data handling) harder to understand or maintain in the long run. Again, not always, there are always trade offs. But neither [data, error] nor try/catch are obviously "simpler" than the other in any universal sense.