<div dir="ltr">Hi, I think a func such as clamped would be helpful. to be frank, I had made some mistakes when trying to compose min and max correctly.<div><br></div></div><br><div class="gmail_quote"><div dir="ltr">Robert Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>于2017年3月11日周六 下午1:35写道:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">I can't argue with that. I guess I was really only opposed to using the half-open range for Double and other theoretically non-discrete types, for the reasons I listed. I have no objections to clamping with a half-open Integer range; I just hadn't considered further restricting the Bound of the Range in use. <span style="font-family:HelveticaNeue" class="gmail_msg">arr[idx.clamped(to: arr.indices)] looks amazing.</span></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Mar 11, 2017, at 12:29 AM, Jaden Geller <<a href="mailto:jaden.geller@gmail.com" class="gmail_msg" target="_blank">jaden.geller@gmail.com</a>> wrote:</div><br class="m_-3798344836792316594Apple-interchange-newline gmail_msg"><div class="gmail_msg"><blockquote type="cite" style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="m_-3798344836792316594Apple-interchange-newline gmail_msg">On Mar 10, 2017, at 8:04 PM, Robert Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg"><br class="gmail_msg">I really like this proposal, and think that it does have a place in Swift 4. Two quick notes in light of the discussion: first, I think it should be called clamped, not clamp; second, I think it should only take ClosedRange. More on those later, but first I'll respond to the six questions raised by Xiaodi.<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">1. Is it truly a frequent operation?<br class="gmail_msg"></blockquote>I think so. I've certainly wished for it on an occasion or two. I settle for min(upper, max(lower, value)).<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">2. Is the helper more readable? Is the composed equivalent obvious at a glance?<br class="gmail_msg"></blockquote>Definitely (or I imagine it will be once we get the details figured out). There are two equivalent forms of the min-max version, the other being max(lower, min(upper, value)), not to mention the commutativity of the arguments themselves. I am under the impression that Swift is not a big fan of having multiple equivalent ways to do the same thing — that was part of the reason ++ was nixed. value.clamp(to: closedRange) is clear and is not interchangeable with any one thing in the language.<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">3. Does the helper have the flexibility to cover all common cases?<br class="gmail_msg"></blockquote>I see three cases: value < lower, lower <= value <= upper, and upper < value. All are covered.<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">4. Is there a correctness trap with the composed equivalent? Is there a correctness trap with the helper?<br class="gmail_msg"></blockquote>I don't think so, if we limit to ClosedRange.<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">5. Is there a performance trap with the composed equivalent? Or with the helper?<br class="gmail_msg"></blockquote>I don't know, is there a significant cost associated to constructing a ClosedRange solely for the purpose of using its bounds? I would imagine not, but someone who knows more about Swift can answer.<br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">6. Does the helper actually encourage misuse?<br class="gmail_msg"></blockquote>I don't see how, if we limit its argument to ClosedRange.<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">Going back to my earlier points — I think that to keep things in line with Swift's naming conventions, this function should be called clamped, as it returns a modified version of the calling object. Alternatively, we could follow the standard set by other numeric types and provide the non-mutating clamped and the mutating clamp, like multiplied/multiply for Double.<br class="gmail_msg"><br class="gmail_msg">Finally, I don't think it makes mathematical sense to clamp to a non-closed range. Refer back to the original definition proposed, `min(upperBound, max(lowerBound, value))`. ClosedRange was proposed as a convenience for providing those bounds. This makes sense because a ClosedRange contains its bounds. Since (mathematical) non-closed ranges don't contain their bounds, it doesn't make sense to use a non-closed range to provide those bounds.<br class="gmail_msg"></blockquote><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">I think open ranges should be supported, but not for all `Comparable` types. It would however be reasonable to support it for types with discrete ordered values, all `Integer` types for example. I think we might be able to provide it for `T: Strideable where T.Stride: Integer` even. We definitely cannot provide it for all types though; it’s nonsensical to clamp a real value to a closed range.</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="gmail_msg">Also, the above notwithstanding, I have a hard time figuring out when you would actually want to constrain a number to be strictly less than an upper bound, violating Question 1 above. If this behavior were really desired, better to be explicit and subtract the appropriate delta — 1 for Int, Double.epsilon (or whatever it's called) for Double. I definitely foresee a correctness trap with the non-closed Range.<br class="gmail_msg"><br class="gmail_msg">Another reason not to allow half-open ranges is because of their asymmetry. Half open ranges are only open at their upper end, so you would have the ability to open-clamp from above but not from below. Seems arbitrary (see Question 3).<br class="gmail_msg"></blockquote><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">We already have this asymmetry. Adding a clamp function doesn’t worsen it. Besides, we have half-open [above] ranges because they are useful for indices:</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">`arr[idx.clamped(to: arr.startIndex..<arr.endIndex)`</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">We can even write this!</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">`arr[idx.clamped(to: arr.indices)]`</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><span style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="gmail_msg">This seems like a useful enough feature to consider it IMO.</span><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><blockquote type="cite" style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="gmail_msg"><br class="gmail_msg">_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></blockquote></div></blockquote></div><br class="gmail_msg"></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>