
Cast-Free Arithmetic in Swift - ingve
https://realm.io/news/richard-fox-casting-swift-2/
======
potatolicious
> _" In Objective-C, we have syntax like this:"_

Not really - implicit casts were always a warning in Obj-C, along with any
number of things that other languages consider errors.

My personal opinion is that Obj-C is so loose as a language that, for
production uses at least, one should turn on as many warnings as the compiler
gives you, and then turn on warnings-as-errors. We've been doing this for a
while and it's saved our bacon at least a few times.

 _Floats, doubles, and ints are not interchangeable_. Likewise, _int8, int16,
int32, and int64 are not interchangeable_ and IMO should never be converted
from one to the other without the explicit knowledge of the programmer.

This seems like a nice convenience, but I'm skeptical if the convenience
gained is worth the (IMO substantial) risk of shooting yourself in the foot.

~~~
mnem
What's dangerous about converting an int to a wider type?

~~~
takeda
You're bringing just one specific case where probably is acceptable[1] and
ignoring all other cases where it's definitively bad (to narrower type, or
mixing floats with ints).

[1] and only when you don't care about overhead of converting from one type.

~~~
mnem
I couldn't think of anything immediately Evil for that case and wanted to
check I wasn't missing something :) The others definitely have badness if you
aren't expecting it.

I'm quite surprised objective-c doesn't warn by default if you try to a
potentially lossy conversion without an explicit cast.

~~~
takeda
I think it all depends what you meant by wider. I don't think anything will
happen if you convert int8 to int16 (don't know swift so I don't know if it
distinguishes between those types), but if you for example do casting from
integer to floats and vice versa (the author uses double as the universal
type) and do some heavy calculations you can get wrong results.

This is because float/double is not really a wider type it is just a number
representation that is not exact and just uses approximations so you actually
are losing information.

~~~
mnem
I'd generally limit wider to apply to the same, uh, type classes (there's
probably a proper word) int8 to int16, float to double and so on.

Casting between integers and floating point is pretty risky unless you're
absolutely sure about your ranges and precision. Anything that does that
silently gives me The Fear.

------
pacaro
I understand the spirit of exploration and fun that this was done with,
however the author talks of using this in "production". This scares me. These
types are not interchangeable.

I would love to see a disclaimer and/or a discussion of what can go wrong

EDIT: If I add the floats 1.5 and 1.5 to get an integer, is the result 2 or 3?

~~~
nadohs
I use the dot property conversion, not the overloading in general use. I also
have such reservations about using overloading for casting in production. What
I do use, is the series of extensions for single letter dot property
conversions, the extensions without the protocol extending, that I also used
in Swift 1.2. Sorry if that was unclear...

------
Kallikrates
The Swift patterns Emerging definitely favor explicit conversions over
implicit. One of the QA questions begins eluding to some issues with this
pattern with under and overflows, but the author also doesn't mention safety
around Nan's or Infinity. Last thing I want as a consumer of an API is
surprises. There are good reasons why these value types are non
interchangeable without being explicit.

~~~
nadohs
Good point bringing up over/underflow, I didn't think much about Nan or
infinity, but I did consider potential over/underflows. I originally built an
overflow/underflow checker(on the github project), but then re-evaluated it
and figured it wasn't really necessary since the default action for number
types that overflow/underflow in swift is to throw an error runtime. The
person asking the question mentioned another series of operators that exist
&+, &-, &*,etc that allow for overflow/underflow to occur on number types in
swift.. without the error throwing, which is not the default.

------
webjprgm
The case that has bugged me is when I have some integer number of items and I
need to compute some CGFloat for drawing something based on it. count *
SpacingPixels gives an error, need CGFloat(count) * SpacingPixels even though
there is no possibility of losing precision by the up-cast from Int to
CGFloat.

It is also slightly annoying to have Double and CGFloat not be the same, but I
solved that by just always using CGFloat pretty much everywhere even when not
referring to pixels or points.

I don't think I would overload + and *, though, due to possible complications
with the error messages as the article suggests. But I might play with more
terse Ruby-like ".to_f" as an extension or something ...

~~~
Alphasite_
CGFloat is a different type based on the system, is it not?

~~~
_jsn
Yes. It's double precision on 64-bit platforms and single precision on 32-bit.

    
    
      #if defined(__LP64__) && __LP64__
      # define CGFLOAT_TYPE double
      # define CGFLOAT_IS_DOUBLE 1
      # define CGFLOAT_MIN DBL_MIN
      # define CGFLOAT_MAX DBL_MAX
      #else
      # define CGFLOAT_TYPE float
      # define CGFLOAT_IS_DOUBLE 0
      # define CGFLOAT_MIN FLT_MIN
      # define CGFLOAT_MAX FLT_MAX
      #endif

~~~
nadohs
Exactly, this is also pointed out in the struct definition in CoreGraphics for
CGFloat.

/// The native type used to store the CGFloat, which is Float on 32-bit
architectures and Double on 64-bit architectures.

------
hamstergene
This is called coercion — implicit conversion between types.

Numeric types coercion is very basic convenience that is present in many
statically typed programming languages. Older languages like C used to allow
unsafe conversions, but modern ones like C# or Java are doing it right: for
example, adding int and float is allowed, but assigning float to int is not.
There is no reason Swift shouldn't have the same.

I suspect is has been given up (temporarily or not) because of type inference.
Swift's already giving "expression is too complex" errors in some situations,
numeric coercions would surely make it worse.

------
p0nce
What was wrong with Java type promotion already?

