How about writting modern and proper Python first? Not to mention designing a decent API?
Let's examine the README example for a minute:
user: Optional[User]
if user is not None:
balance = user.get_balance()
if balance is not None:
balance_credit = balance.credit_amount()
if balance_credit is not None and balance_credit > 0:
can_buy_stuff = True
else:
can_buy_stuff = False
I don't know if it's been deliberatly twisted, but that's not what I would called idiomatic or realistic for a Python program:
- one should probably never reach this part of the code if there is no user. But I'll indulge the author.
- don't put can_buy_stuff in an else close, what's the point?
- using type hints for no reason, but not other modern facilities like the walrus operator?
- do we really want users without a balance? Let's indulge this, but it seems a bad design.
- what's with all those unecessary conditional blocks?
- credit_amount should never be None. It's a Balance object, put a sane default value. But ok, indulging again.
So, you get down to:
user: Optional[User]
can_buy_stuff = False
if user and (balance := user.get_balance()):
can_buy_stuff = (balance.credit_amount() or 0) > 0
I don't think the solution the lib offers is superior:
Checking the user should not be part of this algo, credit_amount should be 0 if never set. We could even remove return False, I keep it because I like explicitness.
You could even that as a method or raise NoBalance depending of your case.
That doesn't mean we should not experiment with other paradigms in Python, and I do think this lib is an interesting experiment, but I don't find it conclusive.
Comments
How about writting modern and proper Python first? Not to mention designing a decent API?
Let's examine the README example for a minute:
I don't know if it's been deliberatly twisted, but that's not what I would called idiomatic or realistic for a Python program:- one should probably never reach this part of the code if there is no user. But I'll indulge the author.
- don't put can_buy_stuff in an else close, what's the point?
- using type hints for no reason, but not other modern facilities like the walrus operator?
- do we really want users without a balance? Let's indulge this, but it seems a bad design.
- what's with all those unecessary conditional blocks?
- credit_amount should never be None. It's a Balance object, put a sane default value. But ok, indulging again.
So, you get down to:
I don't think the solution the lib offers is superior: And that's if we are using the rules of the README, which are not fair.If we have a well designed API, and we use a function (more testable, and hey, are we doing FP or not ?), then:
Checking the user should not be part of this algo, credit_amount should be 0 if never set. We could even remove return False, I keep it because I like explicitness.You could even that as a method or raise NoBalance depending of your case.
Bottom line, if you really feel that strongly about None, don't jump on the bazooka to kill this fly, go to https://discuss.python.org and advocate for PEP 505 (None-aware operators): https://www.python.org/dev/peps/pep-0505/
It's been deferred since 2015.
That doesn't mean we should not experiment with other paradigms in Python, and I do think this lib is an interesting experiment, but I don't find it conclusive.
I'd like to know what happens to can_buy_stuff and the rest of the code when user is Not None and balance_credit is -1.
user can't buy stuff and one unfortunate developer will hunt the bug that charged someone with negative credit.
can_buy_stuff is then False.