Swift 3.0 Preview

Здесь мы с вами начнем краткий обзор намечаемых изменений в Swift 3.0.

Поехали!

Удаление синтаксиса функций карринга (SE-0002)

Мы удалили поддержку шаблонов с несколькими аргументами в объявлении функций, что позволяет вам использовать только один аргумент в паре круглых скобок. При миграции ваш код, испольщующий синтаксис объявления функций карринга, вместо этого может быть трансформирован в явно возвращающий замыкания.

// До:
func curried(x: Int)(y: String) -> Float {
  return Float(x) + Float(y)!
}

// После:
func curried(x: Int) -> (String) -> Float {
  return {(y: String) -> Float in
    return Float(x) + Float(y)!
  }
}

Оригинальный пост на англ.

Удаление ключевого слова var из параметров функции (SE-0003)

Была некоторая путаница между параметрами с маркером inout и параметрами с маркером var. Потому как оба из них позволяют менять входное значение, но только inout позволяет перезаписать его. Поэтому маркер переменной в параметрах функций var будет удален.

func doSomethingWithVar(var i: Int) {
  i = 2 // Это не имеет никакого эффекта на передаваемый параметр "i", он может быть изменен только локально, в пределах функции.
}

func doSomethingWithInout(inout i: Int) {
  i = 2 // Это изменение так же переносится и в передаваемый в функцию параметр "i", что можно увидеть не только в пределах зоны видимости функции.
}

var x = 1
print(x) // 1

doSomethingWithVar(x)
print(x) // 1

doSomethingWithInout(&x)
print(x) // 2

Оригинальный пост на англ.

Удаление операторов инкремента декремента (SE-0004)

Как мы с вами уже говорили ранее, и как это было видно при программировании на Swift 2.2, операторы инкремента и декремента будут польностью удалены из Swift 3.0.

Теперь вам нужно будет использовать альтернативный синтаксис.

// до
let a = ++x  
let b = x++  

let d = --x  
let e = x--  


// после
let c = x + 1
let f = x - 1

Оригинальный пост на англ.

Более удобный переход с Objective-C API на Swift (SE-0005)

Руководства по программированию по фреймворку Cocoa показывают как можно создать аккуратные, последовательные API на Objective-C, которые работают просто изумительно. Однако Swift является другим языком, у которого есть свои особенности: строгая типизация, вывод типов, универсальные шаблоны, переполнение. Из-за таких отличий эти самые Objective-C API, которые так хорошо выглядят в Objective-C, в Swift выглядят через чур многословными:

let content = listItemView.text.stringByTrimmingCharactersInSet(
   NSCharacterSet.whitespaceAndNewlineCharacterSet())

API, которое получается, если следовать Objective-C руководоству. А теперь есть более Swift'овая версии этого же куска кода, которая выглядет вот так:

let content = listItemView.text.trimming(.whitespaceAndNewlines)

Последний пример более близко подходит под руководства Swift API Deisgn, в частности пропуская "ненужные" слова, которые и так подразумеваются компилятором (view, string, character set и другие). Смысл этого предложения - сделать импортированный Objective-C код более "Swifty", предлагая более плавный опыт перехода для программистов Swift при использовании Objective-C API.

Оригинальный пост на англ.

Применение API Guidelines к стандартной библиотеке (SE-0006)

Swift API Design Guidelines разрабатывались как часть Swift 3. Это очень важно, чтобы Стандартная Библиотека являлась экземпляром Swift API Design Guidelines, которая, возможно, является самым часто используемым API в любых приложениях. Стандартная Библиотека так же создает преценденты и для других библиотек.

Чтобы посмотреть все изменения, посмотрите тут.

Оригинальный пост на англ.

Удаление стандартных C-циклов for (SE-0007)

Мы тоже об этом говорили ранее, что стандартные циклы будут удалены из Swift 3.0.

//до
for var i = 0 ; i < 10 ; i++ {
    print(i)
}

//после
for i in 0..<10 {
	print(i)
}

Оригинальный пост на англ.

Добавление Lazy для flatMap опциональных последовательностей (SE-0008)

Сейчас Стандартная Библиотека Swift имеет две версии записи .flatMap. Одна из которых сглаживает последовательность последовательностей после трансформации:

[1, 2, 3]
  .flatMap { n in n..<5 } 
// [1, 2, 3, 4, 2, 3, 4, 3, 4]

И другая, которая сглаживает последовательность опциональностей:

(1...10)
  .flatMap { n in n % 2 == 0 ? n/2 : nil }
// [1, 2, 3, 4, 5]

Однако версия .lazy существовала только для первого варианта:

[1, 2, 3]
  .lazy
  .flatMap { n in n..<5 }
// LazyCollection<FlattenBidirectionalCollection<LazyMapCollection<Array<Int>, Range<Int>>>>

(1...10)
  .lazy
  .flatMap { n in n % 2 == 0 ? n/2 : nil }
// [1, 2, 3, 4, 5]

Оригинальный пост на англ.

Добавление инициализаторов для Int и UInt для конвертирования из UnsafePointer и UnsafeMutablePointer (SE-0016)

Так как пользователи могут создать Unsafe[Mutable]Pointer из Ints и UInts, то у них так же должна быть возможность создавать Int и UInt из Unsafe[Mutable]Pointer. Это позволит пользователям вызывать C-функии с параметрами intptr_t и uintptr_t, что позволит пользователям применять более сложную арифметику для указателей, чем они могли с UnsafePointer.

Оригинальный пост на англ.

Изменение Unmanaged на UnsafePointer (SE-0017)

Структура Стандартной Библиотеки Unmanaged предоставляет типобезопасную обертку, которая не учавствует в процессах ARC, что позволяет пользователю делать ручные запросы retain/release.

Следующие методы нужны для того, чтобы конвертировать в/из Unmanaged:

static func fromOpaque(value: COpaquePointer) -> Unmanaged<Instance>
func toOpaque() -> COpaquePointer

Однако API C, которая переменные или константы типа void * попадают в Swift как UnsafePointer или как , а не как COpaquePointer. На практике пользователи должны конвертировать UnsafePointer -> COpaquePointer -> Unamaged, что ведет к такому раздутию кода:

someFunction(context: UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()))

info.retain = { Unmanaged<AnyObject>.fromOpaque(COpaquePointer($0)).retain() }
info.copyDescription = {
    Unmanaged.passRetained(CFCopyDescription(Unmanaged.fromOpaque(COpaquePointer($0)).takeUnretainedValue()))
}

В Unmanaged API замените использование COpaquePointer на UnsafePointer и UnsafeMutablePointer.

Функции, которые подвержены изменениям fromOpaque() и toOpaque(). Нужна еще одна небольшая модификация в текущей реализации:

@_transparent
@warn_unused_result
public static func fromOpaque(value: UnsafePointer<Void>) -> Unmanaged {
    // Null pointer check is a debug check, because it guards only against one
    // specific bad pointer value.
    _debugPrecondition(
      value != nil,
      "attempt to create an Unmanaged instance from a null pointer")

    return Unmanaged(_private: unsafeBitCast(value, Instance.self))
}

@_transparent
@warn_unused_result
public func toOpaque() -> UnsafeMutablePointer<Void> {
    return unsafeBitCast(_value, UnsafeMutablePointer<Void>.self)
}

Обратите внимание, что значения типа UnsafeMutablePointer могут быть переданы функциям, включая как UnsafePointer, так и UnsafeMutablePointer. Таким образом для простоты использования, мы выбираем UnsafePointer в качестве входного параметра в fromOpaque() и UnsafeMutablePointer в качестве возвращаемого типа в toOpaque().

Использования кода теперь не требует преобразований:

info.retain = { Unmanaged<AnyObject>.fromOpaque($0).retain() }
info.copyDescription = {
    Unmanaged.passRetained(CFCopyDescription(Unmanaged.fromOpaque($0).takeUnretainedValue()))
}

Оригинальный пост на англ.

Тестирование Swift (SE-0019)

Тестирование - важная часть современной разработки софта. Глубокая интерграция тестирования в Swift Package Manager обеспечит стабильную, надежную систему упаковки.

Мы предлагаем расширить нашу традиционную структуру директорий пакета для добавления тестовых модулей. Любоя поддиректория кореневой директории пакета с именем "Tests" или другая поддиректория существующего модуля директории с именем "Tests" будет включать в себя тестовый модуль. Например:

Package
├── Sources
│   └── Foo
│       └──Foo.swift
└── Tests
    └── Foo
        └── Test.swift

//Или

Package
└── Sources
    ├── Foo.swift
    └── Tests
        └── Test.swift

//или для проектов с одним модулем

Package
├── Sources
│   └── Foo.swift
└── Tests
    └── TestFoo.swift

//Имя файла: TestFoo.swift опционально

//В примерах выше поддиректория "Tests" создается для модуля Foo, основываясь на источниках в релевантных поддиректориях.
//Тестовый модуль создан как подкатегория категории "Tests":

Package
├── Sources
│   └── Foo
│       └──Foo.swift
└── Tests
    └── Foo
        └── Test.swift
    └── Bar
        └── Test.swift

Здесь мы создали 2 тестовых модуля. Модули в этом примере могут тестировать различные аспекты модуля Foo. На самом деле это напрмую зависит от автора данного пакета.

В дополнение, мы так же предполагаем, что создание модуля, так же должно сопровождаться созданием соответсвтующих тестов для этого модуля. Несмотря на то, что такой подход будет требовать немного больше времени для сборки проекта, мы верим, что тестирование достаточно важная часть разработки, чтобы принять это. Более того, мы хотим пойти дальше и сделать выполнение тестов постоянным при сборке проекта, но так же мы понимаем, что это может препятствовать циклам дебаггинга.

Оригинальный пост на англ.

API Design Guidelines (SE-0023)

Предлагаемые API Design Guidlines доступны по ссылке https://swift.org/documentation/api-design-guidelines/.

Исходники SE-0023 API Design Guidelines, SE-0006 Apply API Guidelines to the Standard Library, SE-0005 Better Translation of Objective-C APIs Into Swift размещены по ссылке https://github.com/apple/swift-internals. Пулл запросы по простому редактированию копий приветствуются. Более серьезные изменения должны быть рассмотрены как часть процесса обзора языка.

Оригинальный пост на англ.

Модернизация идентификаторов для дебаггинга в Swift (SE-0028)

Изменения произошли и в идентификаторах типа __FILE__, __LINE__, __COLUMN__, __FUNCTION__, и __DSO_HANDLE__. Теперь каждый изменяется вот так: __FILE__ -> #file ,__LINE__ -> #line, __COLUMN__ -> #column, __FUNCTION__ -> #function (добавлена во время обзора), __DSO_HANDLE__ -> #dsohandle.

Оригинальный пост на англ.

Удаление неявного splat-поведения из функциональных приложений (SE-0029)

Давайте рассмотрим следующий пример:

func foo(a : Int, b : Int) {}
//Вы можете вызвать эту функцию, присвоив соответствующие значение в параметры при вызове:

foo(42, b : 17)
//Либо вам можно использовать малоизвестную особенность и передать в качестве аргумента кортеж, который заменит оба значения сразу одним значением:

let x = (1, b: 2)
foo(x)

В силу некоторых недостатков такого поведения было решено избавиться от такой формы записи. Теперь у вас не будет возможности передавать кортеж в качесвте нескольких значений для входных параметров.

Оригинальный пост на англ.

Обновление объявления inout параметра в качестве типа (SE-0031)

Ключевое слово inout обозначает, поведение аргумента как copy-in/copy-out (то есть изменяет входное значение). Текущая реализация определяет ключевое слово inout непосредственно перед именем аргумента. Мы же хотим переместить это ключевое слово за двоеточие, чтобы указать тип в качестве inout, а не имя самого параметра.

В Swift 2 inout параметр находится на стороне имени, а не на стороне типа, хотя это ключевое слово определяет изменения типа, но не имени. Перенос ключевого слова inout определит следующие преимущества:

(x: inout T) -> U // => (inout T) -> U
  • Это позволит inout корректно интегрироваться в синтаксис типа, например:
  • Это так же позволит предотвратить сходства с аргументами маркированными inout, например:
func foo(inOut x: T) // foo(inOut:), type (T) -> Void
func foo(inout x: T) // foo(_:), type (inout T) -> Void
  • Перемещение ключевого слова inout, позволит использовать его в качестве имени параметра, что по сути не является сильной мотивацией для изменения, но тем не менее, в Swift 3 inout является ключевым словом и использовать его в качестве имени нельзя. Соответственно перемещение inout в правую сторону, в сторону типа, сделаем язык Swift немножечко проще.
  • Это так же позволит соотносится с аналогичными паттернами в других языках, например borrowing в Rust, что может быть со временем введено обратно в Swift.

Оригинальный пост на англ.

Добавление метода first(where:) к Sequence (или к последовательностям) (SE-0032)

Новый метод first(where:) позволяет вернуть найденный элемент в последовательности.

Очень часто бывает нужно вернуть первый найденный элемент последовательности, которой передается предикат (или фильтр, другими словами). Для коллекций вы можете использовать методы index(of:) или index(where:), после чего вы можете передать найденный индекс обратно в коллекцию в качестве сабскрипта, но это несколько неудобно. Для последовательностей нет простого способа найти необходимый элемент, как перебирать все ее через цикл и добавлять найденные элементы в массив.

Мы видели, как некоторые программисты писали что-то вроде seq.lazy.filter(predicate).first, но на самом деле это не lazy потому, что .first является единственным методом коллекций, который при вызове fitler() приводит к Sequence.filter(), который возвращает массив, вместо LazySequenceProtocol.filter(), который возвращает lazy последовательность. Пользователи обычно не обращают на это внимание, что означает, что проделывают куда большую работу, чем рассчитывают.

Соответственно все это нас подводит к тому, чтобы расширить наши Sequence и доварить новый метод first(where:), который принимает предикат и возвращает опциональное значение первого элемента, который проходит предикат, если, конечно, такой вообще есть.

Добавьте вот такое расширение к Sequence:

extension Sequence {
  /// Returns the first element where `predicate` returns `true`, or `nil`
  /// if such value is not found.
  public func first(where predicate: @noescape (Self.Iterator.Element) throws -> Bool) rethrows -> Self.Iterator.Element? {
    for elt in self {
      if try predicate(elt) {
        return elt
      }
    }
    return nil
  }
}

Оригинальный пост на англ.

Импорт Objective-C констант в качестве типов в Swift (SE-0033)

Учитывая список констант языка Objective-C, мы думаем добавить атрибут, который позволит Swift импортировать эти константы либо как Enum, либо как Struct, используя RowRepresentable для конвертирования их начального типа. Таким образом вместо постоянной передачи сток по API, мы можем использовать типобезопасные объекты, которые будут иметь возможность автозавершения в Swift, что делает наш Swift и Objective-C код более читабельным и более понятным для начинающих программистов.

Swift-evolution thread: Original E-Mail, Replies.

Оригинальный пост на англ.

Устранение неоднозначностей между выражений линейной системы управления от идентификаторов отладки (SE-0034)

В настоящее время принята Swift Evolution SE-0028 (https://github.com/apple/swift-evolution/blob/master/proposals/0028-modernizing-debug-identifiers.md) перегружает использование выражения #line, которое обозначает и идентификатор, который соответствуют номеру строки вызываемого участка внутри файла, а так же является частью выржаения линейной системы управления.

Оригинальный пост на англ.

Уточнение взаимодействия комментариев и операторов (SE-0037)

Есть несколько несоответствий в том, как обрабатываются комментарии при определении оператора как префиксного, постфиксного или инфиксного. Иногда они обрабатываются как пробелы, иногда не как пробелы, и это все зависит от того по какую сторону они находятся от оператора, а так же зависит от того, что находится в самом комментарии. Это предложение предлагает установить универсальные правила для всех этих случаев.

Ветка Swift-evolution: началась тут, продолжается тут

В настоящий момент комментарии, расположенные сразу после операторов не являются пробелами, для корректного определения оператора в качестве prefix/infix/postfix, означая, что компиляция не пройдет (SR-186).

Обратите внимание на следующий пример:

if /* comment */!foo { ... }

Код не компилируется, так как "!" является префиксным оператором, а компилируется как бинарный, что подразумевает, что у него нет пробелов ни с одной из сторон. Очевидно, что такое поведение кода не является корректным.

Оригинальный пост на англ.

Модернизация литералов playground'а (песочницы) (SE-0039)

Литералы песочницы токенизируют цвета, файлы, изображения. Именно это и позволяет использовать drag-and-drop для размещения быстрых ссылок или визуализации контекста, когда вы оформляете свой контент песочницы. Однако эти литералы используют квадратные скобки, что вызывает конфликт с литералом коллекций, которые так же используют их. Это предложение пересматривает литералы песочницы по использованию маркеров #available и #selector.

Оригинальный пост на англ.

Замещение знаков равенства знаком двоеточия для атрибутов аргументов (SE-0040)

Атрибуты аргументов не похожи на другие аргументы языка Swift. В вызываемом участке они используют "=" вместо ":", для разграничения имен аргументов от передаваемых значений. Эта предложение возвращает синтаксис атрибутов к стандартному синтаксису Swift, заменяя "=" на ":".

Оригинальный пост на англ.

Объявление переменных с помощью ярлыков "case" для соответствия нескольких шаблонам  (SE-0043)

В Swift 2 есть возможность соответствовать нескольким шаблонам при помощи "case". Однако эти "case" не могут иметь различные шаблоны, если они определяют переменные.

Следующий код выдает ошибку:

enum MyEnum {
  case Case1(Int,Float)
  case Case2(Float,Int)
}

switch value {
case let .Case1(x, 2), let .Case2(2, x):
  print(x)
case .Case1, .Case2:
  break
}

Ошибка заключается в том, что "case" с различными шаблонами не могу объявлять переменные.

Данное предложение направлено на устранение этой ошибки, когда каждый шаблон создает переменные соответствующие его типу.

Изменение этого подхода приведет к уменьшению повторяющегося кода. На данный момент этот код согласуется с множественностью шаблонов, до тех пор пока не объявляются переменные.

Оригинальный пост на англ.

Импорт в качестве члена импортируемого типа  (SE-0044)

Swift импортирует объявления C, позволяя коду на Swift нативно взаимодействовать с библиотеками и фреймворками на C. Но импортированные таким образом API не совсем свободно взаимодействуют со Swift. Это предложение стремится обеспечить такой механизм, который позволит авторам API на C указать возможность импорта функций и переменных в качестве членов импортируемых типов в Swift. Также оно стремится обеспечить вариант автоматического вывода для API-интерфейсов, которые аккуратно и последовательно следуют соглашению об именах.

Оригинальный пост на англ.

Установка постоянного поведения для ярлыков всех параметров, включая и первые тоже (SE-0046)

Мы предлагаем нормализовать объявление первого параметра функций и методов. В это предложении поведение первого параметра будет абсолютно таким же как второго и третьего параметров. Все параметры, несмотря на их позицию, будет иметь одинаковое поведение. Это позволит создать простой и последовательный подход к объявлению параметров языка Swift и привести объявления методов и функций в соответствие с инициализаторами, которые уже используют этот стандарт.

//Объявляем функцию foo 
func foo(x: Int, y: Int)

//Вызываем в Swift 2 вот так 
foo(_:,y:) 

//Будем вызывать в Swift 3 вот так 
foo(x:,y:)

Оригинальный пост на англ.

Установка уведомлений о неиспользовании результатов on-Void функций (SE-0047)

В текущей версии Swift функции и методы имеющие маркеры @warn_unused_result информируют компилятор о том, что non-void возвращение должно быть где-то использовано. Если же такого маркера нет, то вы не увидите никаких уведомлений и ошибок, когда ваша функция возвращает результат, который нигде не используется.

На текущий момент этот атрибут объявления в основном разграничивает только изменчивость и неизменчивость значения. Сейчас он предлагает опциональный mutable_variant, когда ожидаемое возвращаемое значение не будет использовано. Например, когда вызывается функция sort() с неиспользуемым результатом, вам будет предложено заменить ее на sortInPlace, которая не имеет выходного значения.

Оригинальный пост на англ.

Универсальные псевдонимы типов (SE-0048)

Это предложение нацелено на то, чтобы добавить универсальные псевдонимы типов в Swift.

Универсальные псевдонимы типов являются очевидной универсализацией существующей модели псевдонимов типов Swift, которая позволит вам предоставить имя для существующего номинального универсального типа, либо предоставить имя для таких типов как кортежи, функции и т.д. с универсальными параметрами.

На данный момент есть такое решение, которое позволяет псеводонимам представлять параметры типа, которые находятся в области их определения.

typealias StringDictionary = Dictionary
typealias DictionaryOfStrings = Dictionary
typealias IntFunction = (T) -> Int
typealias Vec3 = (T, T, T)
typealias BackwardTriple = (T3, T2, T1)

Это согласуется с остальной частью подхода к универсальным типам Swift и хорошо вписывается в эту модель.

Оригинальный пост на англ.

Перенос @noescape и @autoclosure атрибутов в качестве атрибутов типа, а не параметров (SE-0049)

Это предложение нацелено на перемещение существующих атрибутов @noescape, @autoclosure из атрибутов объявления параметров в атрибуты типа. Это улучшает последовательность и уменьшает избыточность внутри языка, что так же является аналогичным изменению SE-0031, которое удаляет inout, позволяя синтаксису объявления быть более последовательным.

Оригинальный пост на англ.

Удаление явного let из параметров функций  (SE-0053)

Так как параметры функций неизменяемы по умолчанию, позволяет использовать ключевое слово let, что является избыточным или даже лишним, поэтому удаление этого излишка было бы лучшим решением. Исключение такой возможности именования параметра с помощью let позволит так же очистить синтаксис объявления Swift. Более того, предложение SE-0003 говорит нам о том, что мы так же удаляем и var при объявлении параметров функций и методов, что позволяет нам избавиться от какой-либо неоднозначности.

// можно сделать так 
func foo(let x: Int) { ... }

// но выглядит лучше вот так, а результат один и тот же
func foo(x: Int) { ... }

Оригинальный пост на англ.

Отмена неявно извлеченного опционального(ImplicitlyUnwrappedOptional или IUO) типа (SE-0054)

Это предложение направлено на исключение IUO типа из файловой системы Swift и заместить его атрибутом IUO при объявлениях. Добавление "!" к типу Swift будет указывать на опциональность типа и аннотировать объявление с указанием атрибута, что это значение может быть неявно извлечено при использовании.

Оригинальный пост на англ.

Использование опционалов для явного обозначения допустимости пустого значения небезопасного указателя (SE-0055)

Указатели в Objective-C (будь то указатели на объекты или на необъектные типы) могут быть обозначены как nullable или nonnull, в зависимости от того может ли быть значение указателя null или нет. Однако в Swift нет такой возможности разграничить указатели на необъектные типы. В Swift UnsafePointer либо может быть null, либо никогда нет.

У нас уже есть способ описать такой случай - опционалы. Это предложение нацелено на то, чтобы UnsafePointer отображал необнуляемый указатель, а UnsafePointer? отображал обнуляемый указатель. Это так же позволит сохранить информацию об обнуляемости указателя, которая хранится в .h файлах для импортируемых C и Objective-C API.

Оригинальный пост на англ.

Импорт легковесных универсальных шаблонов Objective-C (SE-0057)

Легковесные универсальные шаблоны Objective-C позволяют классам Objective-C быть параметризованными типами, с которыми они работают, аналогично синтаксису универсальных шаблонов Swift. Их адаптация в коллекции классов Foundation позволяет Objective-C API лучше переходить в Swift. Например, NSArray<NSString *> * переходит в [String], а не в значительно более слабый [AnyObject]. Однако параметризированные Objective-C классы теряют свои параметры типа, когда импортируются в Swift, таким образом использование параметров типа за пределами связанных, коллекций типа (NSArray, NSDictonary, NSSet) не имеет никаких преимуществ в Swift. Это предложение представляет способ импорта параметров типа Objective-C классов в Swift.

Оригинальный пост на англ.

Обновление API правил по именованию и обновление API множеств соответственно (SE-0059)

Когда было предложено SE-0006, которое применяет руководящие принципы API для стандартной библиотеки, отсутствие приемлемого соглашения об именовании для некоторых пар методов mutating/nonmutating означает, что множества SetAlgebra, Set<T> и OptionSet<T> не были соответствующе обновлены. Это предложение лечит обе проблемы с помощью:

  • созданием необходимых соглашений об именовании и
  • применение соответствующих изменений к API множеств. В дополнение к этому еще несколько других проблем в API будут так же попутно устранены.

Так как вы читаете это предложение, возможно вам будут так же интересны следующие ссылки (на англ):

Оригинальный пост на англ.

Добавление универсального результата и обработка ошибок в autoreleasepool() (SE-0061)

 Функция стандартной бибилиотеки autoreleasepool на данный момент не поддерживает ни возвращаемого значения ни обработку ошибок, что делает сложной и подверженной ошибке передачу результата и ошибок в вызывающий контекст.

Дискуссия была начата тут. Dmitri Gribenko указал на то, что было бы полезно добавить универсальный возвращаемый тип (сначала в моем pull запросе), а в другой раз тут. Jordan Rose указал на то, что это необходимо для избежания некорректного вывода возвращаемого типа телом блока, однако после тестирования, мы убедились в том, что компилятор обрабатывает этот момент корректно.

Оригинальный пост на англ.

Привязка путей по ключу Objective-C (SE-0062)

В Objective-C и Swift пути по ключу (key-paths) используются в KVC, KVO и представлены в качестве строкового литерала (например "friend.address.streetName"). Данное предложение направлено на повышение уровня безопасности и устойчивости к изменению кода, использующего пути по ключу, вводя специальное выражение, которое позволит компилятору проверять то, что вы вводите.

На дамнный момент использование строкового литерала является слабым местом, где происходит много описок и опечаток и нет никакой гарантии, что во время компиляции строка соответствует реальному пути по ключу. Аналогичным образом избавились от Objective-C выражения селектора в SE-0022, которое так же предлагает новый синтаксис для возможности проверки компилятором ключевого пути. Когда соответствующие свойства и методы будут переименованы или удалены, то программист получит уведомление в виде ошибки компиляции.

Новое выражение, которое позволит решить данную проблему выглядит как #keyPath(), который позволяет собрать валидный путь по ключу в виде строкового литерала во время компиляции:

class Person: NSObject {
    dynamic var firstName: String = ""
    dynamic var lastName: String = ""
    dynamic var friends: [Person] = []
    dynamic var bestFriend: Person?

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
}

let chris = Person(firstName: "Chris", lastName: "Lattner")
let joe = Person(firstName: "Joe", lastName: "Groff")
let douglas = Person(firstName: "Douglas", lastName: "Gregor")
chris.friends = [joe, douglas]
chris.bestFriend = joe


#keyPath(Person.firstName) // => "firstName"
chris.valueForKey(#keyPath(Person.firstName)) // => Chris
#keyPath(Person.bestFriend.lastName) // => "bestFriend.lastName"
chris.valueForKeyPath(#keyPath(Person.bestFriend.lastName)) // => Groff
#keyPath(Person.friends.firstName) // => "friends.firstName"
chris.valueForKeyPath(#keyPath(Person.friends.firstName)) // => ["Joe", "Douglas"]

Имея на вооружении выражение #keyPath, которое формирует корректный Objective-C путь по ключу, мы освобождаем разработчика от ручного ввода и проверки валидности написаного пути.

Оригинальный пост на англ.

Привязка Objective-C селектора геттера и сеттера свойства  (SE-0064)

Предложение SE-0022 было принято и реализовано для того, чтобы предоставить #selector для выражений ссылающихся на селекторы Objective-C методов. К сожалению сейчас это все еще не позволяет ссылаться на методы get и set свойств. Таким образом это предложение направлено на то, чтобы найти способ релизовать возможность ссылки на эти методы в Swift 3.0.

Выражение #selector очень полезно, но оно все еще не покрывает все возможные кейсы. Доступ к геттеру и сеттеру свойства требует опусититься до строкового синтаксиса и поступиться безопасностью типа. Это предложение поддерживает этот конкретный случай использования #selector без использования нового синтаксиса, но с переопределением самого выражения #selector для компилятора.

Оригинальный пост на англ.

Новая модель для коллекций и индексов (SE-0065)

Мы предлагаем новую модель для Collections, где индекс элемента перемещается из обычного своего положения в саму коллекцию. Например, вместо написания i.successor() мы будем писать c.index(after: i). Мы так же предлагаем обратить внимание на следующие изменения, которые являются следствием внедрения новой модели:

  • Индекс коллекции может быть любым типом Comparable протокола.
  • Различия между интервалами  и диапазонами исчезает, потому как остаются только диапазоны.
  • Закрытый диапазон, который включает в себя верхнее значение границы теперь очевиден.
  • Существующие "частные" методы индекса теперь доступны публично.

Оригинальный пост на англ.

Стандартизация синтаксиса требованием написания скобок при указании типа аргумента функции (SE-0066)

Функции в Swift используют бесскобочный способ написания типа своих параметров (собственно как синтаксис объявления функции, так и синтаксис вызова функции). Однако в дегеративном случае единичного невариативного, неименованного аргумента без атрибутов Swift позволяет опустить круглные скобки. Например вот эти случаи:

(Int) -> Float
(String) -> Int
(T) -> U
(Int) -> (Float) -> String

Может быть записан в такой форме:

Int -> Float
String -> Int
T -> U
Int -> Float -> String

В то время пока мы экономим написание скобок, у нас создаются небольшие проблемы с тем, что этот код не совсем аналогичен или последователен грамматике Swift, что уменьшает последовательность внутри самих функциональных типов и не добавляет никакого дополнительного выражения смысла (это просто синтаксический сахарок!). Это предложение направлено на исключения этого особенного случая, чтобы во всех случаях написания типа требовало круглых скобок.

Оригинальный пост на англ.

Изменчивость и Типы значений Foundation (SE-0069)

Один из основных принципов Swift - "mutability when you need it". Что по сути означает, что используйте изменчивость, только когда вам это нужно. Это подкрепляется официальной документацией Swift:

Эта концепкиця настолько важна, что она подается в  The Swift Programming Language, сразу после  print("Hello, world!"):

Простые значения

Используйте let для того, чтобы создать константу, var - переменную. Значение константы не обязательно знать во время компиляции, но значение должно быть присвоено исключительно один раз

Когда определенные типы Foundation импортируются в Swift, они не полностью перенимают те возможности, которые предлагает Swift разработчиком для контролирования изменчивости объектов.

Это предложение описывает простую концепцию предоставления такой возможности. Оно описывает набор новых значений типов Foundation, которые заворачивают свои соответсвтующие ссылочные типы. Эта техника используется стандартной библиотекой. Это позволит нам:

  1. Улучить опыть разработчиков.
  2. Увеличить производительность таких маленьких типов как Date. 
  3. Сохранение возможности для разработчиков самостоятельно настраивать поведение большинства типов.

Это предложение описывает основные идеи и предоставляет общее обоснование.

 

Оригинальный пост на англ.

Сделает опциональные требования доступными только для Objective-C (SE-0070)

На данный момент Swift поддерживает опциональные требования в протоколах Objective-C, для соответствия соответсвующей особенности Objective-C. Мы не хотим создавать опциольаные трбоевания для протоколов Swift (все причины будут описаны далее), но мы так же не можем исключить это понятие из языка. Таким образом для предотвражения заблуждений по поводу нашего направления это предложение нацелено на то, чтобы было требование добавлять атрибут "@objc" в каждое опциональное требование, указывая на то, что это особенность совместимости с Objective-C.

Оригинальный пост на англ.

Позволит большинству ключевых слов иметь ссылку на "членство" (SE-0071)

Swift API Design Guidelines указывает на то, что значения кейсов в перечислениях имеют lowerCamelCase соглашение о присвоении имен. Это означает, что если ранее кейсы не имели никаких конфликтов с ключевыми словами (такими как Default, Private, Repeat), то теперь конфликтуют. Для смягчения данного конфликта мы предлагаем использовать точечный синтаксис (или попросту символ ".") перед ключевыми словами, аналогично тому как это предлагается в SE-0001.

Оригинальный пост на англ.

Имена команд в Package Manager (SE-0085)

Это предложение о смене команд для вызова Swift Package Manager. Вместо того, чтобы вешать всю функциональность на swift build и swift test, мы предлагаем новую команду swift package с множеством подкоманд. Команды swift build и swift test предлагаем оставить в качестве высокоуровневых команд из-за частоты их использования.

Оригинальный пост на англ.

Добавление sequence(first:next:) и sequence(state:next:) в stdlib (SE-0094)

Это предложение акцентировано на добавление новых sequence(first:next:) и sequence(state:next:) - паре глобальных функций, которые возвращают (потенциально бесконечные) последовательности ленивых заявлений замыкания к первоначальному значению или изменяемому состоянию.

Последовательность может быть использована для применения шагов, использующих нелинейную математику или для применения неметематических операций, как в следующих примерах:

for x in sequence(first: 0.1, next: { $0 * 2 }).prefix(while: { $0 < 4 }) {
    // 0.1, 0.2, 0.4, 0.8, ...
}

и

for view in sequence(first: someView, next: { $0.superview }) {
    // someView, someView.superview, someView.superview.superview, ...
}

Оригинальный пост на англ.

Повторюсь, что это краткий обзор, так что за более детальными изменениями вам нужно обращаться к первоисточнику, на Swift.org.