Skip to content
This repository has been archived by the owner on Nov 12, 2024. It is now read-only.

How are you auto-casting with just the = sign #17

Open
eonist opened this issue Oct 9, 2016 · 14 comments
Open

How are you auto-casting with just the = sign #17

eonist opened this issue Oct 9, 2016 · 14 comments
Labels

Comments

@eonist
Copy link

eonist commented Oct 9, 2016

IN your sample code you have:

cgFloatValue = doubleValue
doubleValue = intValue
doubleValue = cgFloatValue

But I can't find the auto infer code in your src. Some sort of extension or?

@seivan
Copy link
Member

seivan commented Oct 10, 2016

@eonist Sorry, it looks like the Readme is a bit dated. I was relying on the @conversion keyword pre Swift 2.
It allowed for implicit conversion on assignment.

The only thing possible today, is what's defined in the test-suite(s).
I'll fix the Readme once I migrate over to 3.0.

Sorry for the inconvenience.

@eonist
Copy link
Author

eonist commented Oct 10, 2016

So something like this:

let someDouble:Double = 4
let someFloat:CGFloat = someDouble

Won't work in swift 3.0?

@seivan
Copy link
Member

seivan commented Oct 10, 2016

Not without some Arithmetic operation, e.g addition.
let someFloat:CGFloat = 0 + someInt
or
let someFloat:CGFloat = otherFloat + someInt
or
someFloat += someInt

Since we don’t got implicit conversion on assignment, the next best thing is implicit conversion through operators.

On 2016Oct10, at 12:23, Eon [email protected] wrote:

So something like this:

let someInt:Int = 4
let someFloat:CGFloat = someInt
Won't work in swift 3.0?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub #17 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AADYgAiUB_sUOYo-gGH5RPXZBc13-Cpnks5qyhIlgaJpZM4KR-Yj.

@eonist
Copy link
Author

eonist commented Oct 10, 2016

Right. Would be so awesome to not worry about casting Numerical types. I guess one could make an universal cast method by using inference and generics. like:

let someFloat:Float = 4
let someInt:Int = someFloat.cast()
let someDouble:Double = someFloat.cast()
let someCGFloat:CGFloat = someFloat.cast()

extension Float{
    func <T>cast()->T{
        if(T is Int){return Int(self)}
        else if(T is Double){return Double(self)}
        else if(T is CGFloat){return CGFloat(self)}
        else {fatalError("numerical type not supported")}
    }
}

Better yet. Make a protocol with an extension that every numerical type could extend. So that you only would have to write the extension once. extension Float:NumericalConversional... and extension CGFloat:NumericalConversional...etc

@seivan
Copy link
Member

seivan commented Oct 10, 2016

That’s actually been on my mind. But not sure about the implications.
So far I’ve resorted to + 0 just to be explicit about it. But maybe cast() is more explicit.

On 2016Oct10, at 12:53, Eon [email protected] wrote:

Right. Would be so awesome to not worry about casting Numerical types. I guess one could make an universal cast method by using inference and generics. like:

let someInt:Int = someFloat.cast()
let someDouble:Int = someFloat.cast()
let someCGFloat:Int = someFloat.cast()

extension Float{
func cast()->T{
if(T is Int){return Int(self)}
else if(T is Double){return Double(self)}
else if(T is CGFloat){return CGFloat(self)}
else {fatalError("numerical type not supported")}
}
}

You are receiving this because you commented.
Reply to this email directly, view it on GitHub #17 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AADYgECRHqfA0KOvzYFj_kV11IDqOXniks5qyhlCgaJpZM4KR-Yj.

@eonist
Copy link
Author

eonist commented Oct 10, 2016

What i personally do Is:

let someCGFloat:CGFloat = 4
let someInt:Int = someCGFloat.int
let someDouble:Int = someCGFloat.double
let someString:String = someCGFloat.string

But this solution has code all over the place. But the suggested cast solution would be more centralised and easier to reason with. Thats why I stared your project , I tought you had found a way to infer types with the "=" sign. :)

@seivan
Copy link
Member

seivan commented Oct 10, 2016

I am sorry, I did in Swift 1.0. But they sorta removed it, and I understand since implicit casts could be dangerous.
I actually like your way better, but a casted property could work without the huge switch case you had in mind if you rely on types. I could spike up a quick idea if you’d want that.

On 2016Oct10, at 13:00, Eon [email protected] wrote:

What i personally do Is:

let someInt:Int = cgFloat.int
let someDouble:Int = cgFloat.double
let someString:String = cgFloat.string
But this solution has code all over the place. But the suggested cast solution would be more centralised and easier to reason with. Thats why I stared your project , I tought you had found a way to infer types with the "=" sign. :)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub #17 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AADYgJqeZJdfFNrvc6yJXuXqKTsMGW1iks5qyhrDgaJpZM4KR-Yj.

@eonist
Copy link
Author

eonist commented Oct 10, 2016

Yes, definitely avoid the huge if else clause with polymorphism. And just extend every Numerical type instead. If its all in one .swift class its easy enough to reason with.

@eonist
Copy link
Author

eonist commented Oct 10, 2016

If you have arrays with numbers you can also do something like this:

let someFloats:[Float] = [1,2,3,4]
let someCGFloats:[CGFloat] = someFloats.cast()

extension Array{
   func cast<T:NumericConversional>() -> [T]{
      return self.map { $0.cast() }
   }
}

NOTE: NumericConversional would need to be a protocol that you add when you make the extension for each Number type. etc etc

@seivan
Copy link
Member

seivan commented Oct 11, 2016

For Sequence extensions - You'd probably want to use either a flatMap or rethrow errors.

@eonist
Copy link
Author

eonist commented Oct 11, 2016

Isn't flatmap used when a value can be nil? Are you thinking about numerical values that can be NaN? I can't remember but I think Int or UInt can't be NaN

@seivan
Copy link
Member

seivan commented Oct 11, 2016

Yep, not to mention between unsigned and signed and such. I recall seeing optional inits. But I might be mistaken.

Sent from an iPhone on the go.

On 11 Oct 2016, at 11:18, Eon [email protected] wrote:

Isn't flatmap used when a value can be nil? Are you thinking about numerical values that can be NaN? I can't remember but I think Int or UInt can't be NaN


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@eonist
Copy link
Author

eonist commented Oct 11, 2016

unsigned and signed == special cases no?

img

Anyways I usually just write for the simplest case first, if something needs more features then one could method overload... like for cases where the array items can be nil:

 func cast<T?:NumericConversional>() -> [T?]{
   return self.flatMap { $0.cast() }
 }

Also i'm not sure if flatMap handles NaN values. asserting for isNaN could be a substitute.

@seivan
Copy link
Member

seivan commented Oct 11, 2016

flatMap doesnt out of the box, but you'd have assertions in there on whatever protocol you have.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants