Ответ 1
Примечание. Это перекрестный вызов мой ответ в вопросе перекрестного сообщения в форумах Apple Dev.
Это потому, что Swift кажется немного академически благоприятным (это один из Swift plus для меня!:-)).
Математическая функция - это отношение между некоторыми входами (аргументами) и некоторыми выходами (возвращаемыми значениями). Вместо определения целого класса (например, "подпрограмма" или "процедура" ), для которой это не применяется (без вывода, в частности), Swift просто определяет "процедуру" как отношение с некоторым набором входов (возможно, пустым) и пустой набор выходов.
Есть некоторые преимущества для него, хотя и необычные (по крайней мере, до тех пор, пока функциональное программирование не станет более доминирующим в языке и сообществе). Маленький пример:
infix operator ~~ { precedence 10 associativity right }
func ~~(l: A -> B, r: A) -> B {
return l(r)
}
let productsSoldIn2014 = productOfSales ~~ salesInYears ~~ [2014]
let salespersonsInvolvedIn2014Sales = salespersonsOfSales ~~ salesInYears ~~ [2014]
fireSalespersons ~~ salespersonsOfSales ~~ salesInYears ~~ [2014] // Awful companies only.
func salesInYears(_ y: [Int]) -> [Sale] { … }
func productsOfSales(_ s: [Sale]) -> [Product] { … }
func salespersonsOfSales(_ s: [Sale]) -> [SalesPerson] { … }
func fireSalespersons(_ s: [SalesPerson]) -> () { … } // The appended arrow and null tuple can be left out.
Я определил оператор "цепочки" ~~
(подумайте о цепочке изгиба), который справа налево выталкивает значение через цепочку. С некоторыми соответствующими названными функциями мы можем декларативно определять нужные нам значения. (С ленивыми коллекциями, а не массивами, мы подходим к парадигмам Хаскелла. Если я не ошибаюсь, ~~
здесь присутствует идентификатор monad. Или это просто оператор композиции.)
Третий оператор (после двух дат) запускает продавцов, которые продали что-либо в 2014 году. Обратите внимание, что ~~
хочет вернуть значение "fireSalespersons" (чтобы продолжить цепочку слева, что здесь не present), который в Swift действителен - это просто нулевой кортеж, и мы его отбрасываем. Нет причин, по которым функции без возвращаемого значения не должны работать с оператором (без перегрузки).
Кстати, это также верно:
increaseCEOBonus(35000) ~~ fireSalespersons ~~ salespersonsOfSales ~~ salesInYears ~~ [2014] // Really awful companies only.
// () -> () ~~ [Salesperson] -> () ~~ [Sales] -> [Salesperson] …
func increaseCEOBonus(amount: Int)() { … }
В этом примере самая левая цепочка не имеет значения - она по-прежнему остается справа, но нет никаких значений, переданных влево. Я бы не рекомендовал это использовать, но лучше просто перечислить каждую из них на отдельной строке.
Чтобы вернуться к вашему вопросу, поскольку "ничего" можно использовать (через аргументы), было бы глупо явно запрещать "ничего" назначать переменным-аргументам переменные.
P.S.: Прежде чем кто-нибудь спросит: да, я хотел иметь оправдание, чтобы сделать надуманный пример; это было просто проверить мою способность писать сложные типы.