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.
Robert Bennett via swift-evolution <[email protected]>于2017年3月11日周六 下午1:35写道: > 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. arr[idx.clamped(to: arr.indices)] looks amazing. > > On Mar 11, 2017, at 12:29 AM, Jaden Geller <[email protected]> wrote: > > > On Mar 10, 2017, at 8:04 PM, Robert Bennett via swift-evolution < > [email protected]> wrote: > > 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. > > 1. Is it truly a frequent operation? > > I think so. I've certainly wished for it on an occasion or two. I settle > for min(upper, max(lower, value)). > > 2. Is the helper more readable? Is the composed equivalent obvious at a > glance? > > 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. > > 3. Does the helper have the flexibility to cover all common cases? > > I see three cases: value < lower, lower <= value <= upper, and upper < > value. All are covered. > > 4. Is there a correctness trap with the composed equivalent? Is there a > correctness trap with the helper? > > I don't think so, if we limit to ClosedRange. > > 5. Is there a performance trap with the composed equivalent? Or with the > helper? > > 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. > > 6. Does the helper actually encourage misuse? > > I don't see how, if we limit its argument to ClosedRange. > > > 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. > > 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. > > > 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. > > > 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. > > 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). > > > 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: > > `arr[idx.clamped(to: arr.startIndex..<arr.endIndex)` > > We can even write this! > > `arr[idx.clamped(to: arr.indices)]` > > This seems like a useful enough feature to consider it IMO. > > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
