<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        Hi Nicolas.<div><br></div><div>No worries. And the URL is behind the badge. Click on it and it will be copied to your clipboard:</div><div><br></div><div><img id="d76bf511-3549-4e18-8cb4-fd3991a4ce01" src="cid:8963ba54-338b-4f00-9de8-912c0a5db710" width="315" height="191"></img><br></div><div><br></div><div><img id="4c4cb4d8-613d-4343-93f9-e0c6c8c07d59" src="cid:b4d83faa-8dc6-4910-8e18-7e6d21117ba9" width="376" height="91"></img><br></div><div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div>
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 04.03.2021 18:55:51 schrieb Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:</p><div style="font-family:Arial,Helvetica,sans-serif">Hi Marcel,<br>yes sorry, I will fix it.<br>I saw the red updateStream and failed to find the address of our CI.<br>It should be more visible on squeak.org...<br><br>Le jeu. 4 mars 2021 à 17:13, Marcel Taeumel <marcel.taeumel@hpi.de> a écrit :<br>><br>> Hi all!<br>><br>> This breaks subclassing for Interval. TextLineInterval is an example. Yet, it is used only in ST80, so I will change it there.<br>><br>> What about #species? Or something similar? Do we really want to break subclassing on Interval?<br>><br>> Best,<br>> Marcel<br>><br>> Am 03.03.2021 02:14:24 schrieb commits@source.squeak.org <commits@source.squeak.org>:<br>><br>> Nicolas Cellier uploaded a new version of Collections to project The Trunk:<br>> http://source.squeak.org/trunk/Collections-nice.925.mcz<br>><br>> ==================== Summary ====================<br>><br>> Name: Collections-nice.925<br>> Author: nice<br>> Time: 3 March 2021, 2:14:13.09562 am<br>> UUID: ee92856e-98d1-3a41-a3f2-3529927e7a02<br>> Ancestors: Collections-jar.924<br>><br>> Distinguish questionable LimitedPrecisionInterval (those with Float bounds or step) from ordinary Interval of Integer, Fraction or ScaledDecimals.<br>><br>> The main interest of having a specific class is to avoid crippling Interval with Float workarounds, for the rare use case.<br>><br>> Explain some of the pitfalls of LimitedPrecisionInterval, and encourage alternatives in class comment, which is a second advantage of having a separate class.<br>><br>> Abandon fuzzy inclusion logic, which is considered to introduce more discrepancies than it tries to solve<br>> See http://bugs.squeak.org/view.php?id=6455.<br>> and method #testSurprisingFuzzyInclusion<br>><br>> Fix two other failing tests for Interval of Floats.<br>><br>> Fix size so that (0.3 to: 1.2 by: 0.1) includes: 1.2.<br>> See https://github.com/dolphinsmalltalk/Dolphin/issues/1108<br>> This makes size a bit less performant than super, a 3rd reason why a specific class is neat.<br>><br>> Huh, that's more comments than code ;).<br>><br>> =============== Diff against Collections-jar.924 ===============<br>><br>> Item was changed:<br>> ----- Method: Interval class>>from:to: (in category 'instance creation') -----<br>> from: startInteger to: stopInteger<br>> "Answer an instance of me, starting at startNumber, ending at<br>> stopNumber, and with an interval increment of 1."<br>><br>> + ^((startInteger hasLimitedPrecision or: [stopInteger hasLimitedPrecision])<br>> + ifTrue: [LimitedPrecisionInterval]<br>> + ifFalse: [Interval]) basicNew<br>> - ^self basicNew<br>> setFrom: startInteger<br>> to: stopInteger<br>> by: 1!<br>><br>> Item was changed:<br>> ----- Method: Interval class>>from:to:by: (in category 'instance creation') -----<br>> from: startInteger to: stopInteger by: stepInteger<br>> "Answer an instance of me, starting at startNumber, ending at<br>> stopNumber, and with an interval increment of stepNumber."<br>><br>> + ^((startInteger hasLimitedPrecision or: [stopInteger hasLimitedPrecision or: [stepInteger hasLimitedPrecision]])<br>> + ifTrue: [LimitedPrecisionInterval]<br>> + ifFalse: [Interval]) basicNew<br>> - ^self basicNew<br>> setFrom: startInteger<br>> to: stopInteger<br>> by: stepInteger!<br>><br>> Item was changed:<br>> ----- Method: Interval>>indexOf:startingAt: (in category 'accessing') -----<br>> indexOf: anElement startingAt: startIndex<br>> "startIndex is an positive integer, the collection index where the search is started."<br>> - "during the computation of val , floats are only used when the receiver contains floats"<br>><br>> + | index |<br>> - | index val |<br>> (self rangeIncludes: anElement) ifFalse: [ ^0 ].<br>> + index := (anElement - start / step) rounded + 1.<br>> - val := anElement - self first / self increment.<br>> - val isFloat<br>> - ifTrue: [<br>> - (val - val rounded) abs * 100000000 < 1 ifFalse: [ ^0 ].<br>> - index := val rounded + 1 ]<br>> - ifFalse: [<br>> - val isInteger ifFalse: [ ^0 ].<br>> - index := val + 1 ].<br>> - "finally, the value of startIndex comes into play:"<br>> (index between: startIndex and: self size) ifFalse: [ ^0 ].<br>> + (self at: index) = anElement ifFalse: [ ^0 ].<br>> ^index!<br>><br>> Item was added:<br>> + Interval subclass: #LimitedPrecisionInterval<br>> + instanceVariableNames: ''<br>> + classVariableNames: ''<br>> + poolDictionaries: ''<br>> + category: 'Collections-Sequenceable'!<br>> +<br>> + !LimitedPrecisionInterval commentStamp: 'nice 3/3/2021 01:47' prior: 0!<br>> + A LimitedPrecisionInterval is an Interval whose bounds or step haveLimitedPrecision.<br>> + Due to inexact arithmetic, special precautions must be taken in the implementation,<br>> + in order to avoid unconsistent and surprising behavior as much as possible.<br>> +<br>> + Despite those efforts, LimitedPrecisionInterval is full of pitfalls.<br>> + It is recommended to avoid using LimitedPrecisionInterval unless understanding those pitfalls.<br>> + For example, (0.2 to: 0.6 by: 0.1) last = 0.5.<br>> + This interval does not includes 0.6 because (0.1*4+0.2) is slightly greater than 0.6.<br>> + Another example is that (0.2 to: 0.6 by: 0.1) does not include 0.3 but a Float slightly greater.<br>> +<br>> + A usual workaround is to use an Integer interval, and reconstruct the Float inside the loop.<br>> + For example:<br>> + (0 to: 4) collect: [:i | 0.1*i+0.2].<br>> + or better if we want to have 0.3 and 0.6:<br>> + (2 to: 6) collect: [:i | i / 10.0].<br>> + Another workaround is to not use limited precision at all, but Fraction or ScaledDecimal when possible:<br>> + (1/10 to: 7/10 by: 1/10).<br>> + (0.1s to: 0.7s by: 0.1s).<br>> +<br>> + Yet another pitfall is that optimized to:by:do: might differ from (to:by:) do:<br>> + In the former case, repeated addition of increment is used, in the later, a multiplication is used.<br>> + Observe the differences:<br>> + Array streamContents: [:str | 0 to: 3 by: 0.3 do: [:e | str nextPut: e]].<br>> + Array streamContents: [:str | (0 to: 3 by: 0.3) do: [:e | str nextPut: e]].<br>> +<br>> + There are many more discrepancies, so use carefully, or not use it at all.!<br>><br>> Item was added:<br>> + ----- Method: LimitedPrecisionInterval>>copyFrom:to: (in category 'copying') -----<br>> + copyFrom: startIndex to: stopIndex<br>> + startIndex = 1 ifTrue: [^super copyFrom: startIndex to: stopIndex].<br>> + stopIndex < startIndex ifTrue: [^self copyEmpty].<br>> + ^Array new: stopIndex - startIndex + 1 streamContents: [:stream |<br>> + startIndex to: stopIndex do: [:i | stream nextPut: (self at: i)]]!<br>><br>> Item was added:<br>> + ----- Method: LimitedPrecisionInterval>>last (in category 'accessing') -----<br>> + last<br>> + "Refer to the comment in SequenceableCollection|last."<br>> +<br>> + ^start + (step * (self size - 1))!<br>><br>> Item was added:<br>> + ----- Method: LimitedPrecisionInterval>>reversed (in category 'converting') -----<br>> + reversed<br>> + "There is no guaranty that super reversed would contain same elements.<br>> + Answer an Array instead"<br>> +<br>> + ^Array new: self size streamContents: [:stream | self reverseDo: [:each | stream nextPut: each]]!<br>><br>> Item was added:<br>> + ----- Method: LimitedPrecisionInterval>>size (in category 'accessing') -----<br>> + size<br>> + "Answer how many elements the receiver contains."<br>> +<br>> + | candidateSize |<br>> + candidateSize := (stop - start / step max: 0) rounded.<br>> + step > 0<br>> + ifTrue: [candidateSize * step + start <= stop ifTrue: [^candidateSize + 1]]<br>> + ifFalse: [candidateSize * step + start >= stop ifTrue: [^candidateSize + 1]].<br>> + ^candidateSize!<br>><br>><br>><br><br></commits@source.squeak.org></marcel.taeumel@hpi.de></div></blockquote></div>