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*
>
>

Reply via email to