Cast-Free Arithmetic in Swift
realm.io
realm.io
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.
[1] and only when you don't care about overhead of converting from one type.
I'm quite surprised objective-c doesn't warn by default if you try to a potentially lossy conversion without an explicit cast.
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.
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.
Implicit casts that are precision-lossy (say, int32 to int16) are definitely warnings in Obj-C, the issue is that most(?) Obj-C devs sail right past said warnings, and most projects are not configured to flag these as errors instead.
One of the other issues with implicit casts is that it's often non-obvious if what you're doing is lossy - there are a lot of aliased or conditional types (for example: a CGFloat is a float on 32-bit systems, and double on 64-bit)
Also things like time measurement - a NSTimeInterval is a double, so casting it down to a float is lossy, but not obviously so because for the most part we don't think about what's the actual object backing a lot of system types.
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?
Then whatever the type of integer rounding you do, you will get a solid 3.
Not all producton is critical.
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 ...
#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/// The native type used to store the CGFloat, which is Float on 32-bit architectures and Double on 64-bit architectures.
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.