Is there a way to mark with @available(*, deprecated, message:) methods generated by compiler without manual reimplementation of them?
I have several large structs that conform to Hashable. This is needed for diffable algorithms and keeping them in Set<> or Dictionary. But it is not correct for programmers to directly compare two instances via == because of some reasons.
Possible solution is to mark such method as @available(*, deprecated, message: "some message that guide user"), but it requires to implement manually == function, which is error prone.
these are structs backed with float point numbers, and it is not safe and correct to make all kind of operations. Like with Clock.Instant and Duration
these are structs with a large numbers of fileds, which are made Hashable for using in diffable datasources. But it is not valid to compare them with ==. Typical mistake that users do is trying to find an element in collection by comparing instances with ==. Instead, they should compare instance's IDs.
So what I need is to keep structs Hashable, but prevent users from comparing via ==.
these things tend to be money-like in the sense that they have fixed increments, eg. 0.001 lbs. Double is for when you want to represent things that have wildly different magnitudes, like if you wanted to represent 1,000,000,000,000 lbs and 0.0000001 lbs in the same schema. so unless you are doing that, Double is probably the wrong tool for the job.
i’ve long wished swift had modern decimals. but sadly it does not. (this probably isn’t very helpful, i know.)
this is a different problem than the “large structs = slow equality” problem you mentioned earlier:
my non-actionable advice is to use a proper decimal type to model the product quantity. but this type doesn’t exist, we only have NSDecimal. arggghhh!!
Using a decimal type or not does nothing to change this situation; generally speaking if you should be comparing with a tolerance when using binary floating-point, you should also be comparing with a tolerance when using decimal floating-point or integers for the same computation.
You can construct trivial examples where one happens to work out "correctly" and the other does not, but these are not the norm, and code that assumes such behavior is buggy code.
i don’t think this is true at all, if you are using decimals instead of binary floating point, it is probably because you care about exactness. e.g. an account balance either matches exactly, or it doesn’t match at all. interpreting $1.000001 as equivalent to $1.000000 is a very fast way to go bankrupt.
Right. Which is why you would not compare with a tolerance, whether you were using Double or a decimal type or UInt64 or anything else. If it's appropriate to use a tolerance with one, it is appropriate to use a tolerance with the other. If not, it is not appropriate in either case.
I know that Dictionary compares them with == internally, and it is totally correct. But this should not be done in app logic. We can get from server two almost equal values: "5.4999999999999991118215802999" and "5.5000000000000008881784197001". In app logic we should treat them as almost equal. Lats say it is a quantity of bananas user wants to buy. In user cart we have "5.4999999999999991118215802999", but in another response server returned us "5.5000000000000008881784197001". Comparing them with == is a programmer's error.
Finally, in app logic we should use special math and compare funcs, but for Hashability == should be used.
As I wrote in example AmountValue can only be constructed if rawValue .isNormal || .isZero, .sign == .plus, so NaN is impossible.
So I agree generally it's not safe. But after all checks and validation it is.
Which one? Decimal is not suitable as I wrote.
To be focused: float point value that is used as underlying value is not a problem.
The real task is to make possible only special math and compare funcs and impossible to use < > == because it is a programmer error, no matter what underlying type is. For Hashability == should be used.