This won't happen (force of habit, etc), but if I were to dream, here's a list of breaking changes:
- make Int a typealias to Int32/64 (and seriously consider having it mapped to Int32 even on 64 bit devices)
- make
Float
a typealias to Float32/64
and remove Double
- make
CGFloat
a typealias to Float
and remove all the hackery about CGFloat <-> Float
interop.
- alternatively (even better) make CGFloat a typealias to a new Fixed datatype.
- remove NaN's (or expose the relevant functionality by some explicit additional APIs, so for every floating value "value == value" is true without exceptions).
- change
Optional.none
to Optional.nil
and remove bare nil
- expose
Bool
as an enum with .false
and .true
and remove bare false
/ true
- make enum values mutable (not entirely source breaking, can be made additive)
- alternatively make struct values immutable (although that would be too radical).
- change async from:
func foo() async -> Int to:
async func foo() -> Int
- change discardableResult from:
@discardableResut func foo() -> Int to:
func foo() -> discardable Int
- make "switch" and "do" statement expressions:
func foo(x: Int) -> Int {
switch x {
case 1: 100
case 2: 200
}
}
func bar() {
let x = do {
123
}
}
let items: [String: Int] = [
"first" : 1
"second" : 2
"third" : 3, "fourth" : 4 // comma is needed here
"fifth" : 5, // comma still allowed here
]
perhaps even here:
foo(
expression1
expression2
expression3
)
- allow types inference for parameter names:
func foo(x = true) { ... }
- allow types inference for function return type (additive):
func foo() -> _ { 123 }
- make closure parameters less ugly:
{ $0 * $1 } --->
{ p0 * p1 } // or param0, or value0, etc, or this:
{ p[0] * p[1] } // or this:
{ p.0 * p.1 }
alternatively (even better) derive closure parameter names like so:
func foo(execute: (_ a: Int, _ b: Int) -> Int) {
...
}
....
foo { a * b }
func foo(x: @autoclosure () -> Bool) -> Bool {
x() // parens
}
to
func foo(x: lazy Bool) -> Bool {
x // no parens
}
- change
&&
to &
and ||
to |
(they will still "short-circuit" for Bool ops)
- change Bool's not
!
to something else like suffix .not
and change !=
to <>
. Use pling only to denote "optional unwrapping" business (something that can terminate the app).
- while on this: check all current places that can terminate the app and introduce either a pling or a try in there, examples:
func foo() {
let a = Dictionary(uniqueKeysWithValues: [(1, 1), (1, 1)]) // prohibit
let a = Dictionary(uniqueKeysWithValues: [(1, 1), (1, 1)])! // either this
let a = try! Dictionary(uniqueKeysWithValues: [(1, 1), (1, 1)]) // or this
let b: [Int: Int] = [1:1, 1:1] // prohibit
let b = [Int: Int]([1:1, 1:1])! // either this
let b = try! [Int: Int]([1:1, 1:1]) // or this
let c: Set<Int> = [1, 1] // prohibit
let c = Set<Int>([1, 1])! // either this
let c = try! Set<Int>([1, 1]) // or this
let array: [Int] = [1, 2, 3]
let d: Int = array[123] // prohibit
let d: Int = array[123]!
}
subscript(_ internalName: Int) --> allow only: foo[1]
subscript(name: Int) --> allow only: foo[name: 1]
subscript(externalName x: Int) --> allow only: foo[externalName: 1]