Earlier quoted context omitted.
Kotlin has type aliases. This means you can write something like: typealias Cent = Int and then use a type Cent just like you can an Int, with multiplication and everything else. More info: https://kotlinlang.org/docs/type-aliases.html
Yes, you can, but you shouldn’t to solve this problem, because typealiases aren’t new types, just–as the name suggests–aliases, so anything aliased to Int is interchangeable with Int and everything else aliased that way, so you still have exactly the same problem. Also, cents * cents shouldn’t be cents (though cents * unitless ints should be).
Twenty five thousand dollars of funny money
141–150 of 175 posts
Re: Twenty five thousand dollars of funny money
#142One of the things I really like about f# is thar you can tag even raw numbers with types. And even multiply/divide on those types. https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
Kotlin has type aliases. This means you can write something like: typealias Cent = Int and then use a type Cent just like you can an Int, with multiplication and everything else. More info: https://kotlinlang.org/docs/type-aliases.html
typealias Cent = Int
typealias Euro = Int
SomeEuro = SomeCent
In f#, measures aren't bound to any specific numeric type either.Re: Twenty five thousand dollars of funny money
#143Just to say it, for measurements that take a unit I am hardcore that you should include the unit in the variable time: `timeSeconds` `distanceMeters` `amountDollars` Have unit tests and everything, but also write your code so that when someone reads it they know as precisely as possible what's going on without other documentation.
Using types that encode the units, as suggested in OP, is strictly better.
Re: Twenty five thousand dollars of funny money
#144Instead, provide types for length, time, currency, age, angle, count, etc. And provide suitable operations on those types. Then inadvertently passing a pennies as dollars, or adding a time to a length, would be flagged as an error early.
(To my mind, the only languages that should provide a "number" type are systems specialised for mathematical use, where it's the mathematicians' fault if they shoot themselves in the foot.)
Re: Twenty five thousand dollars of funny money
#145Makes a good case why most programing languages should not provide simple numeric types - being the types we're so used to using that we don't even think about it. Squashing everything into one or two numeric types leaves us wide open to misinterpretation and confusion. Instead, provide types for length, time, currency, age, angle, count, etc. And provide suitable operations on those types. Then inadvertently passing…
Re: Twenty five thousand dollars of funny money
#146Type systems are to programmers what dimensional analysis is to physicists.
Dimensional analysis is to data in other domains what dimensional analysis is to data in the domain of physics.
Type systems are a tool in which dimensional analysis can be done, or, alternatively, which with which you can restrict data to be being dimensionally aware, allowing dimensional analysis to be done outside of the type system.
Re: Twenty five thousand dollars of funny money
#147Earlier quoted context omitted.
Seriously, since everything I work in is denoted as "cents" from backend to frontend, I personally had never understood the need This matches my experience. Obviously actual strict typing has its benefits, but as far as developer ergonomics are concerned, IME you can get about 95% of the benefits just by following a convention of including unit names in identifier names. It's easy to see why this Ruby code might fail…
here it is with Go: package main type km int func (distance km) launch_rocket() {} func main() { distance_miles := 42 // type int has no field or method launch_rocket // distance_miles.launch_rocket() // this works, but is obviously wrong: km(distance_miles).launch_rocket() }
Re: Twenty five thousand dollars of funny money
#148Earlier quoted context omitted.
Nope, this will lead to the same problem that the OP has discovered, viz., that a dependency update creates silent errors. Unless the argument is a keyword, but everyone is too lazy for that.
Yeah, to me the moral of the story was write more tests.
Re: Twenty five thousand dollars of funny money
#149Earlier quoted context omitted.
> [follow] a convention of including unit names in identifier names. appending units to identifiers helps, but it relies on a developer's eyeballs to spot any errors. It would be infinitely preferable if the type system would simply enforce this for you and developers not have to expend cycles reasoning about this stuff themselves.
If you stick to just a few units throughout the system (ideally, use a consistent base unit everywhere and convert any external measurements to it), you can avoid the rest of the problems. Static typing is great, of course, I just don't agree that this can't be solved to almost the same level with languages with dynamic typing.
Re: Twenty five thousand dollars of funny money
#150Had exactly that bug in production, was using ruby on rails & active merchant, and some version change in ActiveMerchant switched from cents to dollars for one of the integrations. Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. Shortly thereafter I get an anxious customer call that we'd charged their debit card $2500.00 instead of $25.00 a…
> Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. This is why I'm pretty dogmatic about variable comparison in tests. This is dangerous and stuff like this has caused a lot bugs to slide though in my experience (and maybe ops): expect(account1.balance).to eq account2.balance This is safe and specifc: expect(account1.balance).to eq 2500 expe…