> On 14. Jan 2018, at 06:04, BJ Homer via swift-evolution
> <[email protected]> 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
Maybe it would be good to pitch such improvements to the Foundation API?
“Angle” is certainly a lot more discoverable and convenient to type than
“Measurement<UnitAngle>”. That said, I tend not to use Foundation’s Measurement
API. It’s pretty heavyweight.
test.swift:
import Foundation
@available(macOS 10.12, *)
func a() {
let a = Measurement(value: 20, unit: UnitDuration.minutes).converted(to:
.seconds)
}
Generated IR:
define hidden swiftcc void @_T04test1ayyF() #0 {
entry:
%0 = call %swift.type* @_T0So12UnitDurationCMa() #3
%1 = getelementptr inbounds %swift.type, %swift.type* %0, i32 0, i32 0
%.kind = load i64, i64* %1, align 8
%isObjCClassWrapper = icmp eq i64 %.kind, 14
br i1 %isObjCClassWrapper, label %isWrapper, label %metadataForClass.cont
isWrapper: ; preds = %entry
%2 = bitcast %swift.type* %0 to %swift.type**
%3 = getelementptr inbounds %swift.type*, %swift.type** %2, i64 1
%4 = load %swift.type*, %swift.type** %3, align 8, !invariant.load !31
br label %metadataForClass.cont
metadataForClass.cont: ; preds = %isWrapper, %entry
%.class = phi %swift.type* [ %0, %entry ], [ %4, %isWrapper ]
%5 = bitcast %swift.type* %.class to %objc_class*
%6 = load i8*, i8** @"\01L_selector(minutes)", align 8
%7 = bitcast %objc_class* %5 to i8*
%8 = call %0* bitcast (void ()* @objc_msgSend to %0* (i8*, i8*)*)(i8* %7, i8*
%6)
%9 = bitcast %0* %8 to i8*
%10 = call i8* @objc_retainAutoreleasedReturnValue(i8* %9) #4
%11 = bitcast i8* %10 to %0*
%12 = bitcast %0* %11 to %TSo12UnitDurationC*
%.asUnsubstituted = bitcast %TSo12UnitDurationC* %12 to %TSo4UnitC*
%13 = call swiftcc { %TSo4UnitC*, double }
@_T010Foundation11MeasurementVACyxGSd5value_x4unittcfC(double 2.000000e+01,
%TSo4UnitC* %.asUnsubstituted, %swift.type* %0)
%14 = extractvalue { %TSo4UnitC*, double } %13, 0
%15 = extractvalue { %TSo4UnitC*, double } %13, 1
%.asSubstituted = bitcast %TSo4UnitC* %14 to %TSo12UnitDurationC*
%16 = getelementptr inbounds %swift.type, %swift.type* %0, i32 0, i32 0
%.kind1 = load i64, i64* %16, align 8
%isObjCClassWrapper2 = icmp eq i64 %.kind1, 14
br i1 %isObjCClassWrapper2, label %isWrapper3, label %metadataForClass.cont4
isWrapper3: ; preds =
%metadataForClass.cont
%17 = bitcast %swift.type* %0 to %swift.type**
%18 = getelementptr inbounds %swift.type*, %swift.type** %17, i64 1
%19 = load %swift.type*, %swift.type** %18, align 8, !invariant.load !31
br label %metadataForClass.cont4
metadataForClass.cont4: ; preds = %isWrapper3,
%metadataForClass.cont
%.class5 = phi %swift.type* [ %0, %metadataForClass.cont ], [ %19,
%isWrapper3 ]
%20 = bitcast %swift.type* %.class5 to %objc_class*
%21 = load i8*, i8** @"\01L_selector(seconds)", align 8
%22 = bitcast %objc_class* %20 to i8*
%23 = call %0* bitcast (void ()* @objc_msgSend to %0* (i8*, i8*)*)(i8* %22,
i8* %21)
%24 = bitcast %0* %23 to i8*
%25 = call i8* @objc_retainAutoreleasedReturnValue(i8* %24) #4
%26 = bitcast i8* %25 to %0*
%27 = bitcast %0* %26 to %TSo12UnitDurationC*
%.asUnsubstituted6 = bitcast %TSo12UnitDurationC* %27 to %TSo9DimensionC*
%.asSubstituted.asUnsubstituted = bitcast %TSo12UnitDurationC*
%.asSubstituted to %TSo9DimensionC*
%28 = call swiftcc { %TSo9DimensionC*, double }
@_T010Foundation11MeasurementVAASo9DimensionCRbzlE9convertedACyxGx2to_tF(%TSo9DimensionC*
%.asUnsubstituted6, %TSo9DimensionC* %.asSubstituted.asUnsubstituted, double
%15, %swift.type* %0)
%29 = extractvalue { %TSo9DimensionC*, double } %28, 0
%30 = extractvalue { %TSo9DimensionC*, double } %28, 1
%.asSubstituted7 = bitcast %TSo9DimensionC* %29 to %TSo12UnitDurationC*
call void bitcast (void (%objc_object*)* @objc_release to void
(%TSo12UnitDurationC*)*)(%TSo12UnitDurationC* %.asSubstituted) #4
call void bitcast (void (%objc_object*)* @objc_release to void
(%TSo12UnitDurationC*)*)(%TSo12UnitDurationC* %.asSubstituted7) #4
ret void
}
declare swiftcc { %TSo9DimensionC*, double }
@_T010Foundation11MeasurementVAASo9DimensionCRbzlE9convertedACyxGx2to_tF(%TSo9DimensionC*,
%TSo9DimensionC*, double, %swift.type*) #0
declare swiftcc { %TSo4UnitC*, double }
@_T010Foundation11MeasurementVACyxGSd5value_x4unittcfC(double, %TSo4UnitC*,
%swift.type*) #0
; Function Attrs: nounwind readnone
define linkonce_odr hidden %swift.type* @_T0So12UnitDurationCMa() #1 {
entry:
%0 = load %swift.type*, %swift.type** @_T0So12UnitDurationCML, align 8
%1 = icmp eq %swift.type* %0, null
br i1 %1, label %cacheIsNull, label %cont
cacheIsNull: ; preds = %entry
%2 = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_NSUnitDuration",
align 8
%3 = call %objc_class* @swift_rt_swift_getInitializedObjCClass(%objc_class*
%2)
%4 = call %swift.type* @swift_getObjCClassMetadata(%objc_class* %3) #3
store atomic %swift.type* %4, %swift.type** @_T0So12UnitDurationCML release,
align 8
br label %cont
cont: ; preds = %cacheIsNull, %entry
%5 = phi %swift.type* [ %0, %entry ], [ %4, %cacheIsNull ]
ret %swift.type* %5
}
; Function Attrs: noinline nounwind
define linkonce_odr hidden %objc_class*
@swift_rt_swift_getInitializedObjCClass(%objc_class*) #2 {
entry:
%load = load %objc_class* (%objc_class*)*, %objc_class* (%objc_class*)**
@_swift_getInitializedObjCClass
%1 = tail call %objc_class* %load(%objc_class* %0)
ret %objc_class* %1
}
declare %swift.type* @swift_getObjCClassMetadata(%objc_class*)
declare void @objc_msgSend()
declare i8* @objc_retainAutoreleasedReturnValue(i8*)
declare void @objc_release(%objc_object*)
… which, personally, I think is just excessive. Maybe for complex conversions
it’s worth it, but I’m not sure it is for simple conversions.
- Karl
>
>
>> On Jan 13, 2018, at 9:31 PM, Erica Sadun via swift-evolution
>> <[email protected] <mailto:[email protected]>> 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
>>> <[email protected] <mailto:[email protected]>> 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
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[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