function deduct(int cents) { ... }
int dollars = ...
deduct(dollars);
You need something like (Apps) Hungarian notation [1] as a minimum - or even better, subtypes of primitives like in Go to represent units in a typesafe way. function deduct(int cents) { ... }
int dollars = ...
deduct(dollars);
You need something like (Apps) Hungarian notation [1] as a minimum - or even better, subtypes of primitives like in Go to represent units in a typesafe way.An expressive type system would allow you to define both a cent and dollar types, s.t. assignments of those types to each other without conversion would fail.
In a way, it is a way to have the computer validate apps Hungarian rather than trusting the programmer (well, it’s more, but for this argument).
Go’s type system is anachronistic, compared to what modern language provides (but then, all of go is anachronistic on purpose. The usefulness of this purpose not to be discussed here).
Sorry for the misinfo!
This is a fantastic bit to tack on for divisive topics, I'm stealing it.
class Cents(int): pass
def send_money(amount: Cents):
print(f"Sending ${amount / 100}")
send_money(42)
That’ll immediately fail validation without you needing to make sure you have tests which would catch every possible problem like that.expected "Cents" [arg-type] Found 1 error in 1 file (checked 1 source file)
In a language which has strict typing, you wouldn’t even be able to compile it.
You can do similar things with other dimensions like “length”.
Or you can go whole hog, and have a single “type” for unit-aware values from which you can only successfully extract a unitless number by specifying a unit which is dimensionally compatible.
But most projects won’t do any of these because they will start out thinking they don’t need it, and by the time they realize the value they’ll think the cost of converting existing code is too high.
Any particular currency can be modelled simply as a single dimension; “money” more generally is more complex. You can either use a single currency of account, track exchange rates for other currencies with it over time, and convert other currencies into it based on the time applicable to the event, or you can track each currency as a separate domain and convert based on the applicable exchange rate for a particular purpose ad hoc based on the specific situation. (There’s probably other approaches that work, but those seem to be, in outline, the most obvious.)
The money type should be compatible with generic interfaces so existing sorting and aggregation functions, for example, can directly on them.