4 ms·
You cannot do any kind of Domain Driven Design with dynamic typing. In F# you can have a type email address and it will be impossible to pass an unverified stri
by tigershark 10y ago
You cannot do any kind of Domain Driven Design with dynamic typing.
In F# you can have a type email address and it will be impossible to pass an unverified string there.
It has to be a valid email address, and you will know it at compile time.
Good luck to try to achieve the same effect in python without writing tons and tons of useless tests just to check the type.
And if you can keep all the type of your system in your head I don't think you ever worked in a real system.
- orf 10y agoYou could make a property in Python that validates it's given value and throws a ValueError if it's not an email. 6 lines of code max, with maybe two tests.
- deleted 10y ago[deleted]
- tigershark 10y agoHow can this prevent you at compile time to pass a username instead of an email?
- jstimpfle 10y agoI have gone that route in Haskell and it was a mess. In the end you need to extract the string again (basically everytime you do something meaningful with it). All these pattern matches kill code readability/writeability. Also, in Haskell one needs to encapsulate the real constructor in its own module to make sure the data is only constructed through a sanitizing constructor. That's quite some overhead (and makes pattern matching impossible). What might be useful instead is first class "tags". In Perl6, you can subset types to values that match a condition (for example, strings that match an email regex (cough)). They are still strings so can be used unchanged with other functionality that does not need the tag. It seemed quite usable to me (applications are limited, though). However the creator said it's still expensive because they haven't figured out / implemented how to transfer invariants, so they are checked at each function boundary. In Python, you can use duck typing: subclass str, it's a dirty hack but works very nicely. The real world solution to the whole mess seems to me to be just to design a good dataflow into the system, so it's clear where you have a valid email address. Typically it's very easy: Just assert the invariant at the boundary to the external domain (for example, HTML form parsing). Now whenever there is a variable "email" in your program you "know" that it is a valid email address.
- deleted 10y ago[deleted]
- tigershark 10y agoIn python nothing can guarantee at compile time that you are not passing a username variable in a method that accepts an email address. You'll just notice at runtime when you realise that you have to rollback your last deployment because new users are unable to receive the activation email that is being sent to their username instead of their email.
- cabalamat 10y ago> In python nothing can guarantee at compile time that you are not passing a username variable in a method that accepts an email address Is there no reason you could not create an Email class and have the method require its argument to be of that type?
- minitech 10y ago> guarantee at compile time If you’re talking about runtime type checks rather than mypy, well, they’re just verbose static types with less safety. (May as well just embrace the duck typing at that point by accessing email.local_part and letting the AttributeError propagate.)
- minitech 10y agoI’ve gone that route in Haskell and it works great. Yes, you need to extract the string again. Not an issue unless you’re golfing all your code. You also don’t need to hide the real constructor if it’s a type your module should be working with. Subclassing str seems like the most horrible way ever to represent an e-mail address. I would definitely write a wrapper instead – exactly like Haskell.