5 ms·
This bug could easily happen in a typed language though. function deduct(int cents) { ... } int dollars = ... deduct(dollars); You need something like
by xg15 4y ago
This bug could easily happen in a typed language though.
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.
[1] https://en.m.wikipedia.org/wiki/Hungarian_notation https://en.m.wikipedia.org/wiki/Hungarian_notation
- snotrockets 4y agoI think you’re confusing expressiveness of types with static/dynamic typing (the latter are also typed!) 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).
- xg15 4y agoAh, my bad there. That was what I meant with subtypes, but you're right, things have moved further there already. Sorry for the misinfo!
- stavros 4y agoYeah, defining "dollars" and "cents" (and over units) types are actually a really good solution for this, it means that you can never pass a value of one unit when the function expects another.
- shepherdjerred 4y ago> The usefulness of this purpose not to be discussed here This is a fantastic bit to tack on for divisive topics, I'm stealing it.
- metafunctor 4y agoYou should define separate types for “cents” and “dollars”. And, probably operations to convert between the types.
- dragonwriter 4y agoYou can have a single type for “money” (or maybe just “us_money”) with separate cents/dollars/mills factories and accessors, and no access to a numeric value except through the accessors. 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.
- diarrhea 4y agoIn physics, dimensionality makes sense. How would one handle money? Can it be represented the same way? A new dimension, next to length, time etc? It would allow to express money per time, eg dollars per second, for example.
- dragonwriter 4y ago> How would one handle money? Can it be represented the same way? 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.)
- metafunctor 4y agoYes, good point. This in fact what I've done previously in an application that was dealing with monetary values. They were basically fixnums with a unit piggybacked on, plus some money-specific operations. The money type should be compatible with generic interfaces so existing sorting and aggregation functions, for example, can directly on them.
- acdha 4y agoThat’s a generic type, and that’s why they’re not enough. Here's a simple Python example: 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.