> On 15. Jan 2018, at 23:55, Taylor Swift <kelvin1...@gmail.com> wrote:
> 
> 
> 
> On Jan 15, 2018, at 3:30 PM, Karl Wagner <razie...@gmail.com 
> <mailto:razie...@gmail.com>> wrote:
> 
>> 
>> 
>>> On 14. Jan 2018, at 21:12, Kelvin Ma via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> This could work, but you’re also giving up all the nice Numeric and 
>>> FloatingPoint conformances when you use this,, all of a sudden adding two 
>>> angles together isn’t let γ = α + β, it’s γ = Angle.radians(α.radians + 
>>> β.radians). just no. at the risk of blowing up the scope of this idea, 
>>> dedicated Angle types also begs for generic trigonometric functions like 
>>> Angle.sin(_:) and Angle.cos(_:). i proposed that a while back and even 
>>> tried implementing it but fast trig evaluation doesn’t genericize well 
>>> since it relies a lot on rsqrt-style magic constants
>> 
>> You could add those conformances back, if you wanted. Most low-level trig 
>> code will quickly escape the wrapper once it starts using the values. Mostly 
>> I use it as a currency type and for converting untyped angles. I think it’s 
>> a great example of Swift’s zero-cost abstractions - we added semantic 
>> meaning (this value isn’t just a number with a specific bit representation, 
>> it’s a number which represents a specific kind of quantity), and 
>> encapsulated some useful functionality, and we don't lose any performance.
>> 
>> I have a couple of these, such as Distance<T> and Time (wraps a 
>> TimeInterval). This allows me to write algorithms like:
>> 
>>     public func point(_ distance: Distance<Double>, along bearing: 
>> Angle<Double>) -> Geo.Point
>> 
>> And use it like this:
>> 
>>     let nextPlace = thisPlace.point(.kilometers(42), along: .degrees(45))
>> 
>> Or this:
>> 
>>     let nextPlace = thisPlace.point(.miles(500), along: .radians(.pi/2))
>> 
>> And so my algorithm actually becomes quite difficult to use incorrectly. 
>> Also, that’s why I use static constructors; similar to how lots of OptionSet 
>> types are implemented, doing it this way lets you use an enum-like syntax to 
>> create values, which fits Angle’s intended use as a parameter/return type.
>> 
>> I’m not saying this should be part of the standard library (this isn’t my 
>> pitch), I’m just saying these kind of wrappers are useful when creating good 
>> APIs. I think somebody was dismissing the idea of an Angle<T> type in 
>> general before.
>> 
>> - Karl
> 
> i thought the whole thing with resiliency barriers is that these kinds of 
> abstractions are *not* zero cost anymore, accessing a member of an imported 
> struct is always going to be through an indirect getter and setter. && this 
> doesn’t get fixed by slava’s inlineable thing because you can’t “inline” a 
> struct layout

This is what the @fixed_layout (or @frozen, or whatever it ends up being 
called) attribute is for. Resilience means that we have built-in indirection to 
allow for library evolution, but the design is that you can opt-out of that 
indirection and expose cross-module inlining or other optimisation 
opportunities.

https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst#fixed-contents-structs

- Karl

> 
>> 
>>> 
>>> also, why are radians(_:) and degrees(_:) static functions? i really only 
>>> use static constructors for initializers that have side effects
>>> 
>>> On Sun, Jan 14, 2018 at 6:36 AM, Karl Wagner <razie...@gmail.com 
>>> <mailto:razie...@gmail.com>> wrote:
>>> 
>>> 
>>>> On 14. Jan 2018, at 09:51, Taylor Swift via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> I do a lot of geometry and spherical-related work and i have never found 
>>>> an Angle type to be worth having. Always use radians. It’s what sin() and 
>>>> cos() take, it’s what graphics APIs like Cairo expect, it’s what graphics 
>>>> formats like SVG use. plus,, do you *really* want to be case-branching on 
>>>> every angle value? that really adds up when you’re converting 100,000s of 
>>>> lat-long pairs to cartesian.
>>> 
>>> You can do it without case-branching. I too have an Angle type; this is 
>>> what I use:
>>> 
>>> public struct Angle<T: FloatingPoint> {
>>>   public var radians: T
>>>   public var degrees: T {
>>>     return (radians / .pi) * 180
>>>   }
>>> 
>>>   public static func radians(_ rads: T) -> Angle {
>>>     return Angle(radians: rads)
>>>   }
>>>   public static func degrees(_ degs: T) -> Angle {
>>>     return Angle(radians: (degs / 180) * .pi)
>>>   }
>>> }
>>> 
>>> If you ask for “radians” (like most low-level trig code will), you just get 
>>> the stored property. The conversion “overhead” is only done at construction 
>>> time, so it makes a convenient parameter/return value.
>>> 
>>> - Karl
>>> 
>>>> 
>>>> On Jan 14, 2018, at 12:04 AM, BJ Homer via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> An Angle type already exists in Foundation; see Measurement<UnitAngle>. 
>>>>> You could add some convenience methods in an extension pretty easily.
>>>>> 
>>>>> import Foundation
>>>>> 
>>>>> typealias Angle = Measurement<UnitAngle>
>>>>> 
>>>>> extension Measurement where UnitType == UnitAngle {
>>>>>     var sine: Double {
>>>>>         let radians = self.converted(to: .radians).value
>>>>>         return sin(radians)
>>>>>     }
>>>>>     
>>>>>     static var threeQuarterTurn: Angle {
>>>>>         return Angle(value: 0.75, unit: .revolutions)
>>>>>     }
>>>>> }
>>>>> 
>>>>> let x = Angle.threeQuarterTurn
>>>>> x.sine // -1
>>>>> 
>>>>> -BJ
>>>>> 
>>>>> 
>>>>>> On Jan 13, 2018, at 9:31 PM, Erica Sadun via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> I would like to see a full Geometry implementation but I don't think it 
>>>>>> should be part of the standard library.
>>>>>> 
>>>>>> I've kicked around some ideas here: 
>>>>>> 
>>>>>> * https://gist.github.com/erica/8cb4b21cf0c429828fad1d8ad459b71b 
>>>>>> <https://gist.github.com/erica/8cb4b21cf0c429828fad1d8ad459b71b>
>>>>>> * https://gist.github.com/erica/ee06008202c9fed699bfa6254c42c721 
>>>>>> <https://gist.github.com/erica/ee06008202c9fed699bfa6254c42c721>
>>>>>> 
>>>>>> and
>>>>>> 
>>>>>> * https://github.com/erica/SwiftGeometry 
>>>>>> <https://github.com/erica/SwiftGeometry>
>>>>>> 
>>>>>>> On Jan 13, 2018, at 7:49 PM, Jonathan Hull via swift-evolution 
>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> Hi Evolution,
>>>>>>> 
>>>>>>> I would really like to see Swift gain an Angle type in the standard 
>>>>>>> library.  Every time I have to deal with an angle in an api, I have to 
>>>>>>> go figure out the conventions for that call.  Is it in degrees? Is it 
>>>>>>> in radians?  What if it is in radians, but I want to think about it in 
>>>>>>> degrees?
>>>>>>> 
>>>>>>> I ended up writing an Angle type for my own code a few years back, and 
>>>>>>> I have to say it is really wonderful.  It has greatly simplified my 
>>>>>>> graphics work.  It takes a lot of mental load off of my brain when 
>>>>>>> dealing with Angles.
>>>>>>> 
>>>>>>> I can of course initialize it either as degrees or radians (or 
>>>>>>> revolutions), but I can also just say things like ‘.threeQuarterTurn’, 
>>>>>>> and then I can get the value back out in whatever format I like.  There 
>>>>>>> are also useful additions that let me normalize the angle to different 
>>>>>>> ranges and which let me snap to the nearest multiple of an angle. Both 
>>>>>>> of these are enormously useful for user facing features.  I can also do 
>>>>>>> math on angles in a way that makes geometric sense for angles.  It is 
>>>>>>> also really useful for interacting with CGVectors in intelligent ways.
>>>>>>> 
>>>>>>> Using Doubles or CGFloats to represent angles everywhere is just 
>>>>>>> semantically wrong IMHO, and it stops us from adding all of these 
>>>>>>> angle-specific niceties.
>>>>>>> 
>>>>>>> Happy to provide code if there is interest…
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Jon
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to