Спикер:
Тема презентации:
Литвиненко Игорь
Swift. Функциональное программирование
в массы
Агенда
• Проблемы ООП
• Что такое ФП
• Ищем решение в функциональном
программировании (ФП)
• Основные столпы ФП
• Разбираемся на примерах
• Когда не надо применять ФП
• Заключение
Экскурс в историю
Проблемы императивной (ОО в частности) концепции
• Порог вхождения
• Не тривиально разбивание на абстракции
• Не правильное понимание паттернов –
объект типа БОГ
• Не очевидны побочные эффекты по
интерфейсу
• Сама концепция изменения состояния
перестает работать
• Грязный код
• Потеря в производительности
Что такое ФП
Функциона́льное программи́рование —
парадигма программирования, в
которой процесс вычисления трактуется
как вычисление значений функций в
математическом понимании последних
(в отличие от функций как подпрограмм
в процедурном программировании).
Основные столпы ФП
• Неизменность входных данных
• Никаких побочных эффектов
• Многопоточность
• Изменение уровня абстракции за счет
функций высших порядков
• Больше реюзабельного кода
• Лучше читабельность
• Сохранение контекста
Неизменность входных данных
Неизменность входных данных
class User { ... }
class ViewController {
var user: User
}
class NetworkOperation {
init(user: User)
}
Неизменность входных данных
var a = [1, 2, 3]
var b = a
// a = [1, 2, 3]; b = [1, 2, 3]
b.append(4)
// a = [1, 2, 3]; b = [1, 2, 3, 4]
var a = UIView()
var b = a
// a.alpha = 1; b.alpha = 1
b.alpha = 0
// a.alpha = 0; b.alpha = 0
Изменение уровня абстракции за счет функций высших
порядков
let numbers = [1,2,3]
let squares = numbers.map { $0 * $0 }
let odds = numbers.filter { $0 % 2 == 1 }
let sum = numbers.reduce(0) { $0 + $1 }
let act1SceneCount =
romeoAndJuliet.reduce(0){ count, title in
title.hasPrefix("Act 1") ? count + 1 : count
}
Опциональные типы данных и сахар Swift’a
- Generics
- Статическая типизация
- Перегрузка операторов
- Опциональные типы
- (NSUInteger)indexOfObject:(ObjectType)anObject
Return Value
The lowest index whose corresponding array value is equal to
anObject. If none of the objects in the array is equal to anObject,
returns NSNotFound.
public func indexOf(element: Self.Generator.Element) ->
Self.Index?
Пример 1. Валидация локального файла
func old_and_busted_expired(fileURL: NSURL) -> Bool
let fileManager = NSFileManager()
if let filePath = fileURL.path {
if fileManager.fileExistsAtPath(filePath) {
var error: NSError?
let fileAttributes = fileManager.attributesOfItemAtPath(filePath, error: &error)
if let fileAttributes = fileAttributes {
if let creationDate = fileAttributes[NSFileModificationDate] as? NSDate {
return creationDate.isBefore(NSDate.oneDayago())
}
}
else {
NSLog("No file attributes (filePath)")
}
}
}
Пример 1. Валидация локального файла
let fileExists : (String) -> (String?) = { path in
fileManager.fileExistsAtPath(path) ? path : nil
}
let retrieveFileAttributes : (String) -> ([NSObject: AnyObject]?) = { path in
var error: NSError?
let attributes = fileManager.attributesOfItemAtPath(path, error: &error)
if attributes == nil {
NSLog("Unable to check (path): (error)")
}
return attributes
}
let extractCreationDate : [NSObject:AnyObject] -> NSDate? ={
$0[NSFileModificationDate] as? NSDate
}
Пример 1. Валидация локального файла
let filePath:
String?
let fileExists:
String -> String?
let extractFileAttributes:
String -> [NSObject:AnyObject]?
let extractCreationDate:
[NSObject:AnyObject] -> NSDate?
func bind<A, B>(a: A?, f: A -> B?) -> B?
{
if let x = a {
return f(x)
} else {
return .None
}
}
func >>=<A, B>(a: A?, f: A -> B?) -> B?
{
return bind(a, f)
}
return filePath >>= fileExists >>= retrieveFileAttributes >>= extractCreationDate >>= checkExpired ?? false
Пример 2
let names = ["neal", "s", "stu", "j", "rich", "bob", "aiden",
"j", "ethan", "liam", "mason", "noah", "lucas", "jacob",
"jayden", "jack"]
let result = names
.filter({ $0.characters.count > 1})
.map({$0.capitalizedString})
.joinWithSeparator(", ")
Когда не надо применять ФП
Когда не надо применять ФП
Заключение
• Функциональное программирование
– круто
• Объектно-ориентированное
программирование – тоже круто
• ООП + ФП – идеальное сочетание
• Swift модный язык
Контакты
Игорь Литвиненко
Senior Mobile Developer at DataArt
ilitvinenko@dataart.com

"Swift. Функциональное программирование", Игорь Литвиненко, DataArt

  • 1.
    Спикер: Тема презентации: Литвиненко Игорь Swift.Функциональное программирование в массы
  • 2.
    Агенда • Проблемы ООП •Что такое ФП • Ищем решение в функциональном программировании (ФП) • Основные столпы ФП • Разбираемся на примерах • Когда не надо применять ФП • Заключение
  • 3.
  • 4.
    Проблемы императивной (ООв частности) концепции • Порог вхождения • Не тривиально разбивание на абстракции • Не правильное понимание паттернов – объект типа БОГ • Не очевидны побочные эффекты по интерфейсу • Сама концепция изменения состояния перестает работать • Грязный код • Потеря в производительности
  • 5.
    Что такое ФП Функциона́льноепрограмми́рование — парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).
  • 6.
    Основные столпы ФП •Неизменность входных данных • Никаких побочных эффектов • Многопоточность • Изменение уровня абстракции за счет функций высших порядков • Больше реюзабельного кода • Лучше читабельность • Сохранение контекста
  • 7.
  • 8.
    Неизменность входных данных classUser { ... } class ViewController { var user: User } class NetworkOperation { init(user: User) }
  • 9.
    Неизменность входных данных vara = [1, 2, 3] var b = a // a = [1, 2, 3]; b = [1, 2, 3] b.append(4) // a = [1, 2, 3]; b = [1, 2, 3, 4] var a = UIView() var b = a // a.alpha = 1; b.alpha = 1 b.alpha = 0 // a.alpha = 0; b.alpha = 0
  • 10.
    Изменение уровня абстракцииза счет функций высших порядков let numbers = [1,2,3] let squares = numbers.map { $0 * $0 } let odds = numbers.filter { $0 % 2 == 1 } let sum = numbers.reduce(0) { $0 + $1 } let act1SceneCount = romeoAndJuliet.reduce(0){ count, title in title.hasPrefix("Act 1") ? count + 1 : count }
  • 11.
    Опциональные типы данныхи сахар Swift’a - Generics - Статическая типизация - Перегрузка операторов - Опциональные типы - (NSUInteger)indexOfObject:(ObjectType)anObject Return Value The lowest index whose corresponding array value is equal to anObject. If none of the objects in the array is equal to anObject, returns NSNotFound. public func indexOf(element: Self.Generator.Element) -> Self.Index?
  • 12.
    Пример 1. Валидациялокального файла func old_and_busted_expired(fileURL: NSURL) -> Bool let fileManager = NSFileManager() if let filePath = fileURL.path { if fileManager.fileExistsAtPath(filePath) { var error: NSError? let fileAttributes = fileManager.attributesOfItemAtPath(filePath, error: &error) if let fileAttributes = fileAttributes { if let creationDate = fileAttributes[NSFileModificationDate] as? NSDate { return creationDate.isBefore(NSDate.oneDayago()) } } else { NSLog("No file attributes (filePath)") } } }
  • 13.
    Пример 1. Валидациялокального файла let fileExists : (String) -> (String?) = { path in fileManager.fileExistsAtPath(path) ? path : nil } let retrieveFileAttributes : (String) -> ([NSObject: AnyObject]?) = { path in var error: NSError? let attributes = fileManager.attributesOfItemAtPath(path, error: &error) if attributes == nil { NSLog("Unable to check (path): (error)") } return attributes } let extractCreationDate : [NSObject:AnyObject] -> NSDate? ={ $0[NSFileModificationDate] as? NSDate }
  • 14.
    Пример 1. Валидациялокального файла let filePath: String? let fileExists: String -> String? let extractFileAttributes: String -> [NSObject:AnyObject]? let extractCreationDate: [NSObject:AnyObject] -> NSDate? func bind<A, B>(a: A?, f: A -> B?) -> B? { if let x = a { return f(x) } else { return .None } } func >>=<A, B>(a: A?, f: A -> B?) -> B? { return bind(a, f) } return filePath >>= fileExists >>= retrieveFileAttributes >>= extractCreationDate >>= checkExpired ?? false
  • 15.
    Пример 2 let names= ["neal", "s", "stu", "j", "rich", "bob", "aiden", "j", "ethan", "liam", "mason", "noah", "lucas", "jacob", "jayden", "jack"] let result = names .filter({ $0.characters.count > 1}) .map({$0.capitalizedString}) .joinWithSeparator(", ")
  • 16.
    Когда не надоприменять ФП
  • 17.
    Когда не надоприменять ФП
  • 18.
    Заключение • Функциональное программирование –круто • Объектно-ориентированное программирование – тоже круто • ООП + ФП – идеальное сочетание • Swift модный язык
  • 19.
    Контакты Игорь Литвиненко Senior MobileDeveloper at DataArt ilitvinenko@dataart.com