Hi Julien, You are right, Float intervals are not to be encouraged! But if a knowledgeable person wants to use it, why forbid it? Why not forbid Float alltogether then?
In the same vein, I saw C compiler warning me about using Float = (== in C). Great! Now I cannot use -Wall -Werror, though I perfectly know where I can use == and where I cannot... I understand the intentions, but in french, don't we say that hell is paved with good intentions? Warning about = and not warning about < <= > >= != is kind of stupid common knowledge not very well assimilated... Like telling me that I should use a tolerance (a-b) abs < eps, as kind of miraculous workaround. Err... The problem is now to choose eps and deal with false positive/negative, and bad news, there's no such thing as a universal eps. So in this spirit, I would restrain from forbiding anything. Rather, you could add a rule checking for that construct for the purpose of educating. And please, if activating the rule on some continuous integration Cerberus bot, then provide a way to explicitely bypass it in exceptional conditions! Last thing, Interval enumeration is not performed via cumulative additions start + step + step + step + .... But rather with a multiplication which performs well better wrt loss of accuracy: start + (index - 1 * step) See Interval>>do: since http://bugs.squeak.org/view.php?id=6456 Unfortunately, #to:do: #to:by:do: and their inlined versions do not follow this pattern, but use cumulative additions (at least in Squeak, to be confirmed in Pharo...) If I would change something, that would be that. Remember, "You can cheat as long as you don't get caught", I think I caught the inliner with this snippet: | eps count | eps := 1.0 timesTwoPower: -52. count := 0. 1 + eps to: 2 do: [:x | count := count + 1]. (1 + eps to: 2) do: [:x | count := count - 1]. ^count = 0 Beware, most loops are for Integer and should not be de-optimized too much (cheating can be a tough problem)... Le mar. 18 sept. 2018 à 17:18, Eliot Miranda <[email protected]> a écrit : > > > On Sep 18, 2018, at 2:52 AM, Guillaume Larcheveque < > [email protected]> wrote: > > Maybe #to:by: should convert its parameters in Fraction to avoid Floats > problems (not sure, just an idea) > > > There is no need to convert. One can simply write > > 0 to: 1 by: 1/10 > > The issue with 0 to: 1 by: 0.1 is a problem with floating point > arithmetic, not with intervals, and one does not cure disease by putting > band aids on symptoms. Instead we should teach the pitfalls of floating > point arithmetic representations so that people are not astonished by > 1/10.0*10. Avoid simplifying language. Teach literacy. > > > 2018-09-18 11:25 GMT+02:00 Esteban Lorenzano <[email protected]>: > >> >> >> On 18 Sep 2018, at 11:13, Guillermo Polito <[email protected]> >> wrote: >> >> >> >> On Tue, Sep 18, 2018 at 11:06 AM Julien <[email protected]> >> wrote: >> >>> Hello, >>> >>> I realised that it is possible to create an interval of floats. >>> >>> I think this is bad because, since intervals are computed by >>> successively adding a number, it might result in precision errors. >>> >>> (0.0 to: 1.0 by: 0.1) asArray >>> #(0.0 0.1 0.2 0.30000000000000004 0.4 >>> 0.5 0.6000000000000001 0.7000000000000001 0.8 0.9 1.0) >>> >>> The correct (precise) way to do it would be to use ScaledDecimal: >>> >>> (0.0s1 to: 1.0s1 by: 0.1s1) asArray >>> #(0.0s1 0.1s1 0.2s1 0.3s1 0.4s1 >>> 0.5s1 0.6s1 0.7s1 0.8s1 0.9s1 1.0s1) >>> >>> I opened an issue about it: >>> https://pharo.fogbugz.com/f/cases/22467/Float-should-not-implement-to-to-by-etc >>> >>> And I’d like to discuss this with you. >>> >>> What do you think? >>> >> >> Well, I think it's a matter of balance :) >> >> #to:by: is defined in Number. So we could, for example, cancel it in >> Float. >> However, people would still be able to do >> >> 1 to: 1.0 by: 0.1 >> >> Which would still show problems. >> >> >> Nevertheless, I have seen this a lot of times. >> >> 0.0 to: 1.0 by: 0.1 >> >> Is a common use case. >> >> >> And moreover, we could try to do >> >> 1 to: 7 by: (Margin fromNumber: 1) >> >> And even worse >> >> 1 to: Object new by: (Margin fromNumber: 1) >> >> I think adding type-validations all over the place is not a good >> solution, and is kind of opposite to our philosophy... >> >> So we should >> - document the good usages >> - document the bad ones >> - and live with the fact that we have a relaxed type system that will >> fail at runtime :) >> >> >> yup. >> But not cancel. >> >> Esteban >> >> >> Guille >> >> >> > > > -- > *Guillaume Larcheveque* > >
