I understand that it’s only one function and that I’m probably being
ever-so-slightly unreasonable but I’ve spent the last month going crazy that a
language as expressive as Swift, with all of its support for protocols and
generics and under-the-hood optimization, makes me do stuff like this to
abstract the most typical of algorithms across functionally identical types:
protocol ScalarMathType {
func sqrt() -> Self
func sin() -> Self
func cos() -> Self
func asin() -> Self
func acos() -> Self
func atan2(x:Self) -> Self
}
func sqrt<T:ScalarMathType> (x:T) -> T {return x.sqrt()}
func sin<T:ScalarMathType> (x:T) -> T {return x.sin()}
func cos<T:ScalarMathType> (x:T) -> T {return x.cos()}
func asin<T:ScalarMathType>(x:T) -> T {return x.asin()}
func acos<T:ScalarMathType>(x:T) -> T {return x.acos()}
func atan2<T:ScalarMathType>(y:T,x:T) -> T {return y.atan2(x)}
extension Float : ScalarMathType {
func sqrt() -> Float {return Foundation.sqrt(self)}
func sin() -> Float {return Foundation.sin(self)}
func cos() -> Float {return Foundation.cos(self)}
func asin() -> Float {return Foundation.asin(self)}
func acos() -> Float {return Foundation.acos(self)}
func atan2(x:Float) -> Float {return Foundation.atan2(self,x)}
}
extension Double : ScalarMathType {
func sqrt() -> Double {return Foundation.sqrt(self)}
func sin() -> Double {return Foundation.sin(self)}
func cos() -> Double {return Foundation.cos(self)}
func asin() -> Double {return Foundation.asin(self)}
func acos() -> Double {return Foundation.acos(self)}
func atan2(x:Double) -> Double {return Foundation.atan2(self,x)}
}
That just seems so horribly hackish.
Even if the `Math` module only included this, it would be a win. Otherwise,
I’d almost prefer that we stuff these into the global namespace to keep `sqrt`
company. Right now every developer who wants to change between polar and
cartesian coordinates, or calculate a radius from a circumference in a generic
way needs to replicate this code…
Hopefully we all do it the same way and in the same way that Swift4 implements
it or we’re all going to have to deal with the conflicts later.
> On Jul 11, 2016, at 15:28 , Stephen Canon <[email protected]> wrote:
>
> The problem with having the Math module concurrent with this change is that
> such a thing is necessarily post-swift 3, whereas this change should happen
> in Swift 3 if it’s going to happen at all.
>
> Given that this only effects one function, and you already need your own
> wrappers for every other math operation, it seems like the right tradeoff to
> do it now.
>
> – Steve
>
>> On Jul 11, 2016, at 6:20 PM, G B <[email protected]> wrote:
>>
>> For certain functions (sqrt, sin, cos, log, etc) we’ve grown up in math
>> class calling them as a function on an argument rather than viewing them as
>> a property (or method) of the number.
>>
>> Just like we prefer to use `a - b` rather than `a.sub(b)`, we (or at least
>> I) prefer `sqrt(a)` over `a.squareRoot()`.
>>
>> It seems this is dooming everyone to either reverse their internal math
>> grammar or do what I’m doing now and write their own generic function for no
>> other purpose than to wrap a method call to look like a function call.
>>
>> I’d be less resistant if your proposed `Math` module was concurrent with the
>> change.
>>
>>> On Jul 11, 2016, at 15:13 , Stephen Canon <[email protected]> wrote:
>>>
>>> It wouldn’t delay code intended to operate generically at all. That code
>>> can use .squareRoot( ).
>>>
>>>> On Jul 11, 2016, at 6:12 PM, G B <[email protected]> wrote:
>>>>
>>>> While I don’t have a strong opinion about what functions are in the global
>>>> namespace and which are in a `Math` module, I’m not excited about the idea
>>>> of delaying the availability of generic implementations of floating point
>>>> functions.
>>>>
>>>> How would this affect code intended to operate generically over Float and
>>>> Double? I’ve made the mistake of trying to do this with some of my code
>>>> and it’s remarkably painful for what I’d hoped would be a simple
>>>> abstraction.
>>>>
>>>> Right now (pre SE-0067), it takes a surprising amount of tinkering to get
>>>> code to work generically across those two types. Provisions need to be
>>>> added to provide `sqrt`, `sin`, `cos`, etc. While it all compiles down to
>>>> the same instructions, I don’t feel it is natural to call `squareRoot()`
>>>> as a method.
>>>>
>>>> I don’t necessarily care if these functions are in the global namespace,
>>>> or if they’re imported from a `Math` module. I’m also not convinced that
>>>> they should be part of the core FloatingPoint protocol. `sqrt` probably
>>>> should be, but the trig functions would naturally fit together in a
>>>> protocol that itself conforms to FloatingPoint.
>>>>
>>>>> On Jul 11, 2016, at 14:28 , Stephen Canon via swift-evolution
>>>>> <[email protected]> wrote:
>>>>>
>>>>> Post SE-0067 FloatingPoint provides the usual global operators, as well
>>>>> as a single global function:
>>>>>
>>>>> func sqrt<T: FloatingPoint>(_: T) -> T
>>>>>
>>>>> It seems out of place and lonely, and it would be nice if we can keep the
>>>>> default members of the global namespace to a minimum.
>>>>>
>>>>> I’d like to suggest removing this global from FloatingPoint while keeping
>>>>> the existing global functions for concrete types in the Darwin.C module.
>>>>> The square root operation would still be available for all FloatingPoint
>>>>> types as `.squareRoot()`.
>>>>>
>>>>> I would also plan to provide this and other math.h-ish globals in a
>>>>> future (post swift 3) Math module.
>>>>>
>>>>> – Steve
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution