4 ms·
A function might take multiple integer arguments, each in different units. Separate types for each unit guarantees you won't pass the wrong integer into the wro
by kitd 5y ago
A function might take multiple integer arguments, each in different units. Separate types for each unit guarantees you won't pass the wrong integer into the wrong argument.
Eg
func transferRegularly(dollars(10000), days(30))
Meaning clear.
func transferRegularly(10000, 30)
Meaning obscure, error prone and potentially costly
- deleted 5y ago[deleted]
- necovek 5y agoWith some languages like Python, you can use keyword arguments too (even out of order). Eg. you could simply do transferRegularly(amount=10000, period_in_days=30) I am always amazed how new languages never pick up this most amazing feature of Python. Though obviously, this code smells anyway because 1. repetitive transfers are usually in calendar units (eg. monthly, weekly, yearly — not all of which can be represented with an exact number of days), so in Python you'd probably pass in a timedelta and thus a distinct type anyway, and 2. amounts are usually done in decimal notation to keep adequate precision and currency rounding rules (or simply `amount_in_cents`). Still, I am in favour of higher order types (eg. "timedelta" from Python), and use of them should be equally obligatory for unit-based stuff (eg. volume, so following the traditional rule of doing conversions only at the edges — when reading input, and ultimately printing it out).
- dotancohen 5y agoPHP got this property in PHP 8. One problem with this approach is refactoring. If you wanted to refactor your example with the parameter "amount_in_dollars" then you would either have to continue maintaining the legacy "amount" argument, or break existing code.
- necovek 5y agoSo you mean just like with, eg. renaming a function? I agree it's an issue compared to not doing it, but a very, very minor one IMHO, and legibility improvements far outweight it.
- dotancohen 5y agoRenaming a function comes with the explicit implication that the API has changed. But it might not be clear to someone maintaining a Python application that changing a parameter name might change an argument - that is not the case in any other language (until PHP 8). Guess how I discovered this issue :)
- necovek 5y agoWell, if the approach was more pervasive, you'd be used to it just like seasoned Python developers are. :)
- kitd 5y agoI see keyword arguments as slightly different though. The keyword is like the parameter name. The value is still a plain integer and (theoretically) susceptible to being given the wrong integer. In contrast, unit types allow for hard checking by the compiler. In practice, with good naming it won't make much difference and only shows up when comparing the docs (or intellisense) for an API with how it is actually used.
- steelframe 5y ago> transferRegularly(amount=10000, period_in_days=30) dollars(10000) is still better than this example, because: 10000 what? Pennies? USD? EUR?
- necovek 5y agoSomeone else caught me out on that too by suggesting making it `amount_in_dollars` elsewhere in the thread ;) Now you can say how there are also AUD, CAD... The point was simply that if units are needed due to lack of specific type being used, it's nicer to have that in the API when language allows it.