6 ms·
Pipelining looks nice until you have to debug it. And exception handling is also very difficult, because that means to add forks into your pipelines. Pipelines
by amai 2y ago
Pipelining looks nice until you have to debug it. And exception handling is also very difficult, because that means to add forks into your pipelines. Pipelines are only good for programming the happy path.
- mpalmer 2y agoAt the risk of over generalized pronouncements, ease of debugging is usually down to how well-designed your tooling happens to be. Most of the time the framework/language does that for you, but it's not the only option. And for exceptions, why not solve it in the data model, and reify failures? Push it further downstream, let your pipeline's nodes handle "monadic" result values. Point being, it's always a tradeoff, but you can usually lessen the pain more than you think. And that's without mentioning that a lot of "pipelining" is pure sugar over the same code we're already writing.
- bergen 2y agoDepends on the context - in a scripting language where you have some kind of console you just don't copy all lines, and see what each pipe does one after another. This is pretty straight forward. (Not talking about compiled code though)
- bsder 2y agoPipelining is also nice until you have to use it for everything because you can't do alternatives (like default function arguments) properly. Rust chains everything because of this. It's often unpleasant (see: all the Rust GUI toolkits).
- w4rh4wk5 2y agoYes, certainly! I've encountered and used this pattern in Python, Ruby, Haskell, Rust, C#, and maybe some other languages. It often feels nice to write, but reading can easily become difficult -- especially in Haskell where obscure operators can contain a lot of magic. Debugging them interactively can be equally problematic, depending on the tooling. I'd argue, it's commonly harder to debug a pipeline than the equivalent imperative code and, that in the best case it's equally hard.
- deleted 2y ago[deleted]
- eikenberry 2y agoPipelining simplifies debugging. Each step is obvious and it is trivial to insert logging between pipeline elements. It is easier to debug than the patterns compared in the article. Exception handing is only a problem in languages that use exceptions. Fortunately there are many modern alternatives in wide use that don't use exceptions.
- switchbak 2y agoThis is my experience too - when the errors are encoded into the type system, this becomes easier to reason about (which is much of the work when you’re debugging).
- rusk 2y agoEstablished debugging tools and logging rubric are not suitable for debugging heavily pipelined code. Stack traces, debuggers rely heavily on line based references which are less useful in this style and can make diagnostic practices feel a little clumsy. The old adage of not writing code so smart you can’t debug it applies here. Pipelining runs contrary enough to standard imperative patterns. You don’t just need a new mindset to write code this way. You need to think differently about how you structure your code overall and you need different tools. That’s not to say that doing things a different way isn’t great, but it does come with baggage that you need to be in a position to carry.
- hnlmorg 2y agoPipelining is just syntactic sugar for nested function calls. If you need to handle an unhappy path in a way that isn’t optimal for nested function calls then you shouldn’t be nesting your function calls. Pipelining doesn’t magically make things easier nor harder in that regard. But if a particular sequence of function calls do suit nesting, then pipelining makes the code much more readable because you’re not mixing right-to-left syntax (function nests) with left-to-right syntax (ie you’re typical language syntax).
- EVa5I7bHFq9mnYK 2y agoI think they are talking about nested loops, not nested function calls.
- hnlmorg 2y agoNested loops isn’t pipelining. Some of the examples make heavy use of lambda so they do have nested loops happening as well but in those examples the pipelining logic is still the nesting of the lambda functions. Crudely put, in C-like languages, pipelining is just as way of turning fn(fn(fn())) Where the first function call is in the inner, right-most, parentheses, into this: fn | fn | fn …which can be easily read sequentially from left-to-right.
- EVa5I7bHFq9mnYK 2y agoPipelining replaces several consecutive loops with a single loop, doing more complex processing.
- hnlmorg 2y agoPipelining doesn’t do anything with iterating. It’s entirely about linking nested functions. What you’re looking at is loops defined inside lambda functions. Pipelining makes it much easier to use anonymous functions and lambdas. But it doesn’t magically solve the problem of complex loops.
- jim-jim-jim 2y agoI don't know what you're writing, but this sounds like language smell. If you can represent errors as data instead of exceptions (Either, Result, etc) then it is easy to see what went wrong, and offer fallback states in response to errors. Programming should be focused on the happy path. Much of the syntax in primitive languages concerning exceptions and other early returns is pure noise.