I was thinking about exceptions recently too. But I don't consider them an anti-pattern only the support in IDEs and type systems is not very good. And somehow I see it also in your example with pipeline/safe decorators. Where is the difference? Because I see a lot in the comments that you have problem with the second exceptional flow but doesn't have your solution the same problem? And isn't it even worse because you don't a see a big stacktrace with the info about the exception? Let me describe what I see.
So when the function two returns error the flow jumps to grand_pipeline exactly the same. And without the decorator with the proper exceptions the situation is also the same but with extra boilerplate of checking the result and returning upwards ala Golang. Rust has nice syntax sugar like two()? but still.
If I rewrite the code to use exceptions I see the same but without extra @safe and .unwrap() boilerplate. So where is the difference? If you read my article you will see I agree with that exceptions are hard to notice but I believe they can be fixed. By typesystem. Or even maybe by IDEs. What do you think about that? Still consider them anti-pattern even if they were upgraded?
I am still researching how the exceptions work under the hood and how stack unwinding affects the flow to complete my article but the idea there should be clear.
Well, @pipeline actually had multiple problems. And it is now removed from dry-python.
It is actually imperative compared to declarative function composition. Why so? Because @pipeline is an partial implementation of do-notation, which is imperative by definition.
But. The difference is still visible.
Now exceptions can be visible in the funtion's signatire (let's use the same example from your post, even knowing that @pipeline is removed):
I was thinking about exceptions recently too. But I don't consider them an anti-pattern only the support in IDEs and type systems is not very good. And somehow I see it also in your example with pipeline/safe decorators. Where is the difference? Because I see a lot in the comments that you have problem with the second exceptional flow but doesn't have your solution the same problem? And isn't it even worse because you don't a see a big stacktrace with the info about the exception? Let me describe what I see.
So when the function
two
returns error the flow jumps togrand_pipeline
exactly the same. And without the decorator with the proper exceptions the situation is also the same but with extra boilerplate of checking the result and returning upwards ala Golang. Rust has nice syntax sugar liketwo()?
but still.If I rewrite the code to use exceptions I see the same but without extra
@safe
and.unwrap()
boilerplate. So where is the difference? If you read my article you will see I agree with that exceptions are hard to notice but I believe they can be fixed. By typesystem. Or even maybe by IDEs. What do you think about that? Still consider them anti-pattern even if they were upgraded?I am still researching how the exceptions work under the hood and how stack unwinding affects the flow to complete my article but the idea there should be clear.
Well,
@pipeline
actually had multiple problems. And it is now removed fromdry-python
.It is actually imperative compared to declarative function composition. Why so? Because
@pipeline
is an partial implementation ofdo-notation
, which is imperative by definition.But. The difference is still visible.
@pipeline
is removed):Here it is! We know that something happens! And we can express it with types.
Result
s in development. See returns.readthedocs.io/en/latest/p...