<div dir="ltr">On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
on Sun Jan 15 2017, Xiaodi Wu <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
<br>
> There _may_ be value in recognizing the distinction between rings and<br>
> fields, perhaps? Just as the FP protocols make room for people to implement<br>
> their own decimal FP types, and just as you're trying to make Arithmetic<br>
> accommodate complex numbers, the distinction would allow someone to write<br>
> algorithms generic over rationals and reals (i.e. fields). Being able to<br>
> represent exact fractions isn't so terribly niche, and I think the design<br>
> wouldn't be terribly complicated by its accommodation:<br>
><br>
> ```<br>
> // rename Arithmetic to Ring<br>
> // it's acceptable to omit `.one` from Ring, though some may call that a<br>
> Pseudoring<br>
> // consider omitting division from Ring and pushing it down to<br>
> BinaryInteger and Field<br>
><br>
> protocol BinaryInteger : Ring { ... }<br>
><br>
> protocol Field : Ring {<br>
> static var one { get }<br>
> static func / (Self, Self) -> Self<br>
> static func /= (inout Self, Self)<br>
> var inverted: Self { get } // default impl: .one / self<br>
> }<br>
><br>
> protocol FloatingPoint : Field { ... }<br>
> // rational number types and complex number types<br>
> // would also conform to Field<br>
> ```<br>
<br>
</span>What generic algorithms would this enable?</blockquote><div><br></div><div>For one, anything to do with dividing into equal parts could be generic over floating point, rational, and even complex numbers, but you probably wouldn't want to include integer types in such an algorithm.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Would they be appropriate<br>
for the standard library (as opposed to some more specialized numerics<br>
library)?<br></blockquote><div><br></div><div>The issue is that it's not terribly ergonomic to relegate `Field` to a specialized library because one cannot retroactively conform `FloatingPoint` to `Field`.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
> On Sun, Jan 15, 2017 at 09:14 Dave Abrahams via swift-evolution <<br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
><br>
> on Sun Jan 15 2017, Anton Zhilin <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
><br>
>> What about taking a mathematical approach to numbers?<br>
><br>
>><br>
><br>
>> protocol Group : Equatable {<br>
><br>
>> static var zero: Self { get }<br>
><br>
>> static func + (Self, Self) -> Self<br>
><br>
>> static func += (inout Self, Self)<br>
><br>
>> static func - (Self, Self) -> Self<br>
><br>
>> static func -= (inout Self, Self)<br>
><br>
>> static prefix func - (Self) -> Self<br>
><br>
>> }<br>
><br>
>><br>
><br>
>> protocol Ring : Group {<br>
><br>
>> static var one: Self { get }<br>
><br>
>> static func * (Self, Self) -> Self<br>
><br>
>> static func *= (inout Self, Self)<br>
><br>
>> func tryDivide(by: Self) -> Self?<br>
><br>
>> func tryInvert() -> Self?<br>
><br>
>> }<br>
><br>
>><br>
><br>
>> protocol Field : Ring {<br>
><br>
>> static func / (Self, Self) -> Self<br>
><br>
>> static func /= (inout Self, Self)<br>
><br>
>> var inverted: Self { get }<br>
><br>
>> }<br>
><br>
>><br>
><br>
>> protocol VectorSpace : Group {<br>
><br>
>> associatedtype Scalar : Field<br>
><br>
>> static func * (Self, Scalar) -> Self<br>
><br>
>> static func *= (inout Self, Scalar) -> Self<br>
><br>
>> static func / (Self, Scalar) -> Self<br>
><br>
>> static func /= (inout Self, Scalar) -> Self<br>
><br>
>> static func * (Scalar, Self) -> Self<br>
><br>
>> }<br>
><br>
> The first test for the inclusion of any protocol in the standard library<br>
><br>
> is: “what generic algorithm that uses this protocol as a constraint<br>
><br>
> would be appropriate for inclusion in the standard library?”<br>
><br>
> I don't think we have a use for any of the above directly in the<br>
><br>
> standard library. All the generic algorithms I know of that would be<br>
><br>
> appropriate to those protocols are part of some specialized domain that<br>
><br>
> should have its own library built on top of the Swift standard lib.<br>
><br>
>> Detalization of mathematical terminology will be determined by what kind<br>
> of<br>
><br>
>> types we have in the standard library. Integer types are rings (except for<br>
><br>
>> overflow), floating-point types are fields (except for precision), point<br>
><br>
>> types are linear spaces, so I thought the abstractions above are the bare<br>
><br>
>> minimum.<br>
><br>
>><br>
><br>
>> Unfortunately, Swift doesn’t have rename operations for protocol<br>
><br>
>> requirements, so we can’t express groups that use operations other than +<br>
><br>
>> and -. What we can do is to include an adapter to wrap current instance in<br>
><br>
>> an additive group interface:<br>
><br>
>><br>
><br>
>> struct MultiplicativeGroupAdapter<T: Field> : Group {<br>
><br>
>> // ...<br>
><br>
>> }<br>
><br>
>><br>
><br>
>> extension Field {<br>
><br>
>> var multiplicativeGroup: MultiplicativeGroupAdapter<<wbr>Self><br>
><br>
>> }<br>
><br>
>><br>
><br>
>> <br>
><br>
>> ______________________________<wbr>_________________<br>
><br>
>> swift-evolution mailing list<br>
><br>
>> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
><br>
>> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
><br>
>><br>
><br>
> --<br>
><br>
> -Dave<br>
><br>
> ______________________________<wbr>_________________<br>
><br>
> swift-evolution mailing list<br>
><br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
> ______________________________<wbr>_________________<br>
> swift-evolution mailing list<br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
><br>
<br>
--<br>
-Dave<br>
<br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div></div>