Live data from Hacker News

Twenty five thousand dollars of funny money

rachelbythebay.com

21–30 of 175 posts

Re: Twenty five thousand dollars of funny money

#21

I think I like the duck typing in TypeScript more than I dislike it. But I still wish I could say “this function accepts a type called RobotName. It’s a string, but so is RobotUuid, and we don’t want that. So only accept, strictly, objects typed as RobotName.”

In haskell this is done with newtype. Another example would be using km and miles, and making sure they are not mixed.

Here there is an interesting article about doing this in typescript (not affiliated)

https://kubyshkin.name/posts/newtype-in-typescript/

Re: Twenty five thousand dollars of funny money

#22

I'm confused how this was able to give out money before the new code was submitted to production. The author claims that both she and her coworker tested it before the code was submitted and they ended up with the extra $25k. Was this code only executed on the front end? Were there no checks in the backend to prevent employees from just pulling out whatever money they wanted?

Local was front end stuff, back end was still talking to production.

Re: Twenty five thousand dollars of funny money

#25

I'm gonna be honest, I had never understood the "strict type" argument until right now. Seriously, since everything I work in is denoted as "cents" from backend to frontend, I personally had never understood the need so I'm part of today's lucky 10,000th.

I'm also in the camp that believes that functions or methods that take more than 2-3 (positional) arguments should really take a structure with named keys to avoid this. Humans are bad at lists.

Seeing functions with 5-6 positional arguments makes my skin crawl even if they have strong types.

Re: Twenty five thousand dollars of funny money

#26

I think I like the duck typing in TypeScript more than I dislike it. But I still wish I could say “this function accepts a type called RobotName. It’s a string, but so is RobotUuid, and we don’t want that. So only accept, strictly, objects typed as RobotName.”

Way back in the 1990s I worked in a place where we had to use Ada and follow a strict style guide. The guide prohibited using raw numeric types (such as "unsigned int" or "double" in C-like languages) and required creating a new type (https://en.wikibooks.org/wiki/Ada_Programming/Type_System#De...) for each different quantity, such as temperature or speed. Then you couldn't assign a speed value to a temperature variable, or compare them to each other or do arithmetic, unless you specifically define what the operators mean.

It felt like a lot of busywork, but it did prevent some classes of bugs.

Re: Twenty five thousand dollars of funny money

#27
post #5

> This is yet another reason why I say bare numbers can be poison in a sufficiently complicated system. In Racket, I tended to use keyword arguments, and include the units in the keyword argument. For example, one library used `:velocity-mm/s`. (The `/` character is an identifier constituent, not some special operator syntax.) In Rust, I'm going to try out using language features for static checking of some units (wi…

Yes, the newtype pattern in Rust works very well, say to wrap a string. The somewhat annoying thing is that it is born without any properties so you have to teach it to be comparable, etc from scratch.

The newtype pattern in Go is easier to use, but isn't strict enough - your wrapped string can still appear directly in a string concatenation without a cast. Any wrapped integer can still be used to index a slice! Considering how careful the language is with mixed arithmetic (can't add uint8 to uint16 without casting) this feels like an oversight.

Re: Twenty five thousand dollars of funny money

#28

I think I like the duck typing in TypeScript more than I dislike it. But I still wish I could say “this function accepts a type called RobotName. It’s a string, but so is RobotUuid, and we don’t want that. So only accept, strictly, objects typed as RobotName.”

You can kind of do it: interface RobotName { value: string; type: "RobotName"; } Or if you don't want to make an extra wrapper around every object: interface RobotName { _phantomType: "RobotName"; } function makeRobotName(name: string): RobotName { return name as any as RobotName; } function getRobotName(robotName: RobotName): string { return robotName as any as string; } Presumably V8 is smart enough to inline the w…

Oh cool. So you basically lie about the runtime structure of the type, which works out fine during type checking at compilation.
Post reply on HN