SlideShare a Scribd company logo
1 of 29
Download to read offline
Programación funcional con Swift
- Concurrencia
- Test
- Tolerante a errores
 Las funciones imperativas pueden tener efectos secundarios,
como cambiar el valor de cálculos realizados previamente.
Imperativo
Las funciones declarativas, el valor generado por una función
depende exclusivamente de los argumentos alimentados a la función.
Al eliminar los efectos secundarios se puede entender
y predecir el comportamiento de un programa mucho más fácilmente.
Declarativo
Stateless
struct User {
var id: Int
var name: String
var isActive: Bool
}
class KeyboardViewController: UIInputViewController {
var nameActiveUsers:[String] = []
var users: [User] = []
override func viewDidLoad() {
super.viewDidLoad()
users = [User(id: 1, name: "Juan", isActive: true),
User(id: 2, name: "Pedro", isActive: false),
User(id: 3, name: "Alan", isActive: true),
User(id: 4, name: "Pablo", isActive: false)]
getNameActiveUsers()
print(nameActiveUsers)
}
func getNameActiveUsers(){
var activeUsers = [User]()
for user in users{
if user.isActive{
activeUsers.append(user)
}
}
activeUsers.sort { (user1, user2) -> Bool in
return user1.id < user2.id
}
for active in activeUsers{
nameActiveUsers.append(active.name)
}
}
}
Stateless
struct User {
var id: Int
var name: String
var isActive: Bool
}
class KeyboardViewController: UIInputViewController {
var nameActiveUsers:[String] = []
var users: [User] = []
override func viewDidLoad() {
super.viewDidLoad()
users = [User(id: 1, name: "Juan", isActive: true),
User(id: 2, name: "Pedro", isActive: false),
User(id: 3, name: "Alan", isActive: true),
User(id: 4, name: "Pablo", isActive: false)]
getNameActiveUsers()
print(nameActiveUsers)
}
func getNameActiveUsers(){
var activeUsers = [User]()
for user in users{
if user.isActive{
activeUsers.append(user)
}
}
activeUsers.sort { (user1, user2) -> Bool in
return user1.id < user2.id
}
for active in activeUsers{
nameActiveUsers.append(active.name)
}
}
}
Orientado 

a instrucciones
Imperativo
Defino “cómo” se realiza un proceso para alcanzar un resultado.
Stateless
struct User {
var id: Int
var name: String
var isActive: Bool
}
Orientado 

a expresiones
Declarativo
class KeyboardViewController: UIInputViewController {
override func viewDidLoad() {
super.viewDidLoad()
let users = [User(id: 1, name: "Juan", isActive: true),
User(id: 2, name: "Pedro", isActive: false),
User(id: 3, name: "Alan", isActive: true),
User(id: 4, name: "Pablo", isActive: false)]
print(getNameActiveUsers(users: users))
}
func getNameActiveUsers(users: [User]) -> [String]{
return users.filter{$0.isActive}
.sorted{$0.id < $1.id}
.map{$0.name}
}
}
“Di qué quieres, pero no cómo lo quieres”
Stateless
struct User {
var id: Int
var name: String
var isActive: Bool
}
class KeyboardViewController: UIInputViewController {
override func viewDidLoad() {
super.viewDidLoad()
let users = [User(id: 1, name: "Juan", isActive: true),
User(id: 2, name: "Pedro", isActive: false),
User(id: 3, name: "Alan", isActive: true),
User(id: 4, name: "Pablo", isActive: false)]
print(getNameActiveUsers(users: users))
}
func getNameActiveUsers(users: [User]) -> [String]{
return users.filter{$0.isActive}
.sorted{$0.id < $1.id}
.map{$0.name}
}
}
class KeyboardViewController: UIInputViewController {
var nameActiveUsers:[String] = []
var users: [User] = []
override func viewDidLoad() {
super.viewDidLoad()
users = [User(id: 1, name: "Juan", isActive: true),
User(id: 2, name: "Pedro", isActive: false),
User(id: 3, name: "Alan", isActive: true),
User(id: 4, name: "Pablo", isActive: false)]
getNameActiveUsers()
print(nameActiveUsers)
}
func getNameActiveUsers(){
var activeUsers = [User]()
for user in users{
if user.isActive{
activeUsers.append(user)
}
}
activeUsers.sort { (user1, user2) -> Bool in
return user1.id < user2.id
}
for active in activeUsers{
nameActiveUsers.append(active.name)
}
}
}
// [“Juan”, “Alan”]
// [“Juan”, “Alan”]
Funciones de primera clase
func getURLFromString(url:String) -> URL{
return URL(string: url)!
}
override func viewDidLoad() {
super.viewDidLoad()
let urlImage = “https://www.apple.com.mx"
let url = getURLFromString(url: urlImage)
}
Un lenguaje de programación se dice que tiene Funciones de primera clase cuando
las funciones en ese lenguaje son tratadas como cualquier otra variable.
Funciones de primera clase
func getImage(urlImage: String) -> UIImage{
let url = getURLFromString(url: urlImage)
let data = getDataFromURL(url:url)
let image = getImageFromData(data: data)
return image
}
func getURLFromString(url:String) -> URL{
return URL(string: url)!
}
func getDataFromURL(url: URL) -> Data{
return try! Data(contentsOf: url)
}
func getImageFromData(data:Data) -> UIImage{
return UIImage(data: data)!
}
Funciones de orden Super
Pueden tomar otra función como parámetro:
func getURLFromString(url:String) -> URL{
return URL(string: url)!
}
func getDataFromURL(url: URL) -> Data{
return try! Data(contentsOf: url)
}
func getImageFromData(data:Data) -> UIImage{
return UIImage(data: data)!
}
func getImage(url: String, completion: (Data) -> UIImage) -> UIImage{
let url = getURLFromString(url: url)
let data = getDataFromURL(url:url)
return completion(data)
}
let image = getImage(url: urlImage, completion: getImageFromData)
Funciones de orden Super
Pueden tomar otra función como parámetro:
func getURLFromString(url:String) -> URL{
return URL(string: url)!
}
func getDataFromURL(url: URL) -> Data{
return try! Data(contentsOf: url)
}
func getImageFromData(data:Data) -> UIImage{
return UIImage(data: data)!
}
func getImage(url: String, completion: (Data) -> UIImage) -> UIImage{
let url = getURLFromString(url: url)
let data = getDataFromURL(url:url)
return completion(data)
}
let image = getImage(url: urlImage, completion: getImageFromData)
Firma de la función
(Data) -> UIImage
Funciones de orden Super
Pueden devolver una función de salida:
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage)))
image.draw(in: $0)
return image
}
}
let imageWithSize = image(CGRect(x: 0, y: 0, width: 50, height: 50))
Funciones de orden Super
Pueden devolver una función de salida:
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage)))
image.draw(in: $0)
return image
}
}
let imageWithSize = image(CGRect(x: 0, y: 0, width: 50, height: 50))
Pipelines
func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{
return {second(first($0))}
}
infix operator |> : AdditionPrecedence
Pipelines
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getURLFromString
|> self.getDataFromURL
|> self.getImageFromData
image(urlImage)
image.draw(in: $0)
return image
}
}
func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{
return {second(first($0))}
}
infix operator |> : AdditionPrecedence
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage)))
image.draw(in: $0)
return image
}
}
Antes
Después
Pipelines
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getURLFromString
|> self.getDataFromURL
|> self.getImageFromData
image(urlImage)
image.draw(in: $0)
return image
}
}
func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{
return {second(first($0))}
}
infix operator |> : AdditionPrecedence
func getImage(urlImage: String) -> (CGRect) -> UIImage {
return {
let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage)))
image.draw(in: $0)
return image
}
}
Composición
De funciones
Patron Result
Esto es similar al tipo Opcional nativo de Swift:
el “some” es que tiene un valor, y el “none” es que no tiene.
Es parecido a las promesas en Javascript
enum Result<S,E>{
case success(_ :S)
case failure(_ :E)
}
Patron Result
class NotificationParser {
private func serializeResponse(mapString:String) -> [String: Any]?{
return try! JSONSerialization.jsonObject(with: mapString.data(using: .utf8)!, options: [.allowFragments]) as? [String: Any]
}
func parseSomething(mapString: String, completion: @escaping(_ success: Bool, _ object: Any?) -> Void) {
guard let dataJSON = serializeResponse(mapString: mapString) else {
return completion(false, nil)
}
if dataJSON["success"] != nil {
if dataJSON["success"] as! Bool {
if let responseDictionary = dataJSON["data"] as? NSDictionary {
let response = User.from(responseDictionary)
print("CreateAccount: (response!)")
completion(true,response)
} else {
completion(false, nil)
}
}else{
if let responseDictionary = dataJSON["errors"] as? NSArray {
let errors = ErrorsResponse.from(responseDictionary)
print("Valores del modelo errors: (errors!)")
completion(false,errors?.first)
} else {
completion(false, ErrorsResponse.from(["status":0,"message":"duplicate"]))
}
}
} else {
completion(false, nil)
}
}
}
Patron Result
enum ErrorType{
case notSerialized
case notInternet
case serverError(String)
case messageErrorEmpty
}
extension ErrorType{
var description:String {
switch self {
case .notSerialize:
print("Not Serilized")
return "Error From Server"
case .notInternet:
print("there are not connection")
return "Not Internet Conection"
case .serverError (let message):
return message
case .messageErrorEmpty:
return ""
}
}
}
class NotificationParser{
private func serializeResponse(mapString:String) -> [String: Any]?{
return try! JSONSerialization.jsonObject(with: mapString.data(using: .utf8)!, options: [.allowFragments]) as? [String: Any]
}
func parseSomething(mapString:String, completion: @escaping (Result<User,ErrorType>) -> Void){
guard let dictionary = serializeResponse(mapString: mapString) else {
return completion(.failure(.notSerialized))
}
guard let success = dictionary["success"] as? Bool else{
guard let errorMessage = dictionary["message"] as? String else{
return completion(.failure(.messageErrorEmpty))
}
return completion(.failure(.serverError(errorMessage)))
}
guard let responseDictionary = dictionary["data"] as? Dictionary else{
return completion(.failure(.notSerialized))
}
let response = User.from(responseDictionary)
print("CreateAccount: (response!)")
completion(.success(response))
}
}
Patron Result
class NotificationViewControler:UIViewController {
let manager = Managers.shareInstance
override func viewDidLoad() {
super.viewDidLoad()
self.manager.createUser(email:email, password:password, completion: { [weak self] response in
guard let strongself = self else{ return }
switch response{
case .success(let user):
strongSelf.titleLabel.text = user.name
case .failure(let error):
showAlertOK(error.description)
}
}
}
}
Curry
Apply
Pure
Monad
Future
FlatMap
Reduce
Beneficios
- Código concurrente.
- Menos errores. Ya que la mayoría de tu código será con constantes.
- Fácil de testar. Ya que un objeto se puede considera valido desde su creación,
de ser así se va a considerar válido durante toda su existencia.
- Código paralelisable. Que se puede ejecutar en cores diferentes al mismo tiempo.
- Tolerante a fallos gracias al patron Result
Más información
https://functionalhub.thinkific.com/collections
@gandhimena
Result<Gracias>
Gracias!
@nscodermexico

More Related Content

What's hot

Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Yevhen Kotelnytskyi
 
20180721 code defragment
20180721 code defragment20180721 code defragment
20180721 code defragmentChiwon Song
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreNicolas Carlo
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashBret Little
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APISix Apart KK
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
20181020 advanced higher-order function
20181020 advanced higher-order function20181020 advanced higher-order function
20181020 advanced higher-order functionChiwon Song
 

What's hot (20)

Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
20180721 code defragment
20180721 code defragment20180721 code defragment
20180721 code defragment
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscore
 
Cyclejs introduction
Cyclejs introductionCyclejs introduction
Cyclejs introduction
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Presentation1
Presentation1Presentation1
Presentation1
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Lodash js
Lodash jsLodash js
Lodash js
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
20181020 advanced higher-order function
20181020 advanced higher-order function20181020 advanced higher-order function
20181020 advanced higher-order function
 

Similar to Intro programacion funcional

Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection apiMatthieu Aubry
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery ApplicationsRebecca Murphey
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access RunbookTaha Shakeel
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyHuiyi Yan
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说Ting Lv
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesRiad Benguella
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsJarod Ferguson
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologyDaniel Knell
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8RichardWarburton
 
Engineering JavaScript
Engineering JavaScriptEngineering JavaScript
Engineering JavaScriptJim Purbrick
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principlesAndrew Denisov
 

Similar to Intro programacion funcional (20)

Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 
meet.js - QooXDoo
meet.js - QooXDoomeet.js - QooXDoo
meet.js - QooXDoo
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Easy rest service using PHP reflection api
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Web api's
Web api'sWeb api's
Web api's
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
Taming that client side mess with Backbone.js
Taming that client side mess with Backbone.jsTaming that client side mess with Backbone.js
Taming that client side mess with Backbone.js
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 
Engineering JavaScript
Engineering JavaScriptEngineering JavaScript
Engineering JavaScript
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principles
 

More from NSCoder Mexico

Aprendizaje reforzado con swift
Aprendizaje reforzado con swiftAprendizaje reforzado con swift
Aprendizaje reforzado con swiftNSCoder Mexico
 
Programación Orientada a Protocolos
Programación Orientada a ProtocolosProgramación Orientada a Protocolos
Programación Orientada a ProtocolosNSCoder Mexico
 
Interfaces en interface builder y por codigo
Interfaces en interface builder y por codigoInterfaces en interface builder y por codigo
Interfaces en interface builder y por codigoNSCoder Mexico
 
Core ML and Computer Vision
Core ML and Computer VisionCore ML and Computer Vision
Core ML and Computer VisionNSCoder Mexico
 
Mathematics en la programación
Mathematics en la programaciónMathematics en la programación
Mathematics en la programaciónNSCoder Mexico
 
Video juegos con SpriteKit y Swift
Video juegos con SpriteKit y SwiftVideo juegos con SpriteKit y Swift
Video juegos con SpriteKit y SwiftNSCoder Mexico
 
Introduction a ARToolkit
Introduction a ARToolkitIntroduction a ARToolkit
Introduction a ARToolkitNSCoder Mexico
 
Diseño Agil para Desarrolladores
Diseño Agil para DesarrolladoresDiseño Agil para Desarrolladores
Diseño Agil para DesarrolladoresNSCoder Mexico
 
Simplify your Life with Message Extensions in iOS 10
Simplify your Life with Message Extensions in iOS 10Simplify your Life with Message Extensions in iOS 10
Simplify your Life with Message Extensions in iOS 10NSCoder Mexico
 
Taming the Massive View Controllers
Taming the Massive View ControllersTaming the Massive View Controllers
Taming the Massive View ControllersNSCoder Mexico
 

More from NSCoder Mexico (20)

Aprendizaje reforzado con swift
Aprendizaje reforzado con swiftAprendizaje reforzado con swift
Aprendizaje reforzado con swift
 
In app purchase
In app purchaseIn app purchase
In app purchase
 
Ib designables
Ib designablesIb designables
Ib designables
 
Programación Orientada a Protocolos
Programación Orientada a ProtocolosProgramación Orientada a Protocolos
Programación Orientada a Protocolos
 
Interfaces en interface builder y por codigo
Interfaces en interface builder y por codigoInterfaces en interface builder y por codigo
Interfaces en interface builder y por codigo
 
Introduction Swift
Introduction SwiftIntroduction Swift
Introduction Swift
 
Dependency Managers
Dependency ManagersDependency Managers
Dependency Managers
 
Taller PaintCode
Taller PaintCodeTaller PaintCode
Taller PaintCode
 
VIPER
VIPERVIPER
VIPER
 
Core ML and Computer Vision
Core ML and Computer VisionCore ML and Computer Vision
Core ML and Computer Vision
 
DIY Instagram
DIY InstagramDIY Instagram
DIY Instagram
 
Mathematics en la programación
Mathematics en la programaciónMathematics en la programación
Mathematics en la programación
 
Video juegos con SpriteKit y Swift
Video juegos con SpriteKit y SwiftVideo juegos con SpriteKit y Swift
Video juegos con SpriteKit y Swift
 
Unit Testing en iOS
Unit Testing en iOSUnit Testing en iOS
Unit Testing en iOS
 
Bridgefy SDK
Bridgefy SDKBridgefy SDK
Bridgefy SDK
 
Introduction a ARToolkit
Introduction a ARToolkitIntroduction a ARToolkit
Introduction a ARToolkit
 
Diseño Agil para Desarrolladores
Diseño Agil para DesarrolladoresDiseño Agil para Desarrolladores
Diseño Agil para Desarrolladores
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Simplify your Life with Message Extensions in iOS 10
Simplify your Life with Message Extensions in iOS 10Simplify your Life with Message Extensions in iOS 10
Simplify your Life with Message Extensions in iOS 10
 
Taming the Massive View Controllers
Taming the Massive View ControllersTaming the Massive View Controllers
Taming the Massive View Controllers
 

Recently uploaded

Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank  Design by Working Stress - IS Method.pdfIntze Overhead Water Tank  Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank Design by Working Stress - IS Method.pdfSuman Jyoti
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756dollysharma2066
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfRagavanV2
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringmulugeta48
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . pptDineshKumar4165
 
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Standamitlee9823
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Arindam Chakraborty, Ph.D., P.E. (CA, TX)
 
Intro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdfIntro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdfrs7054576148
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfKamal Acharya
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...SUHANI PANDEY
 

Recently uploaded (20)

Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank  Design by Working Stress - IS Method.pdfIntze Overhead Water Tank  Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
 
Call Girls in Netaji Nagar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Netaji Nagar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Netaji Nagar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Netaji Nagar, Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night StandCall Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
Call Girls In Bangalore ☎ 7737669865 🥵 Book Your One night Stand
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
Navigating Complexity: The Role of Trusted Partners and VIAS3D in Dassault Sy...
 
Intro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdfIntro To Electric Vehicles PDF Notes.pdf
Intro To Electric Vehicles PDF Notes.pdf
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
 

Intro programacion funcional

  • 2. - Concurrencia - Test - Tolerante a errores
  • 3.
  • 4.  Las funciones imperativas pueden tener efectos secundarios, como cambiar el valor de cálculos realizados previamente. Imperativo Las funciones declarativas, el valor generado por una función depende exclusivamente de los argumentos alimentados a la función. Al eliminar los efectos secundarios se puede entender y predecir el comportamiento de un programa mucho más fácilmente. Declarativo
  • 5. Stateless struct User { var id: Int var name: String var isActive: Bool } class KeyboardViewController: UIInputViewController { var nameActiveUsers:[String] = [] var users: [User] = [] override func viewDidLoad() { super.viewDidLoad() users = [User(id: 1, name: "Juan", isActive: true), User(id: 2, name: "Pedro", isActive: false), User(id: 3, name: "Alan", isActive: true), User(id: 4, name: "Pablo", isActive: false)] getNameActiveUsers() print(nameActiveUsers) } func getNameActiveUsers(){ var activeUsers = [User]() for user in users{ if user.isActive{ activeUsers.append(user) } } activeUsers.sort { (user1, user2) -> Bool in return user1.id < user2.id } for active in activeUsers{ nameActiveUsers.append(active.name) } } }
  • 6. Stateless struct User { var id: Int var name: String var isActive: Bool } class KeyboardViewController: UIInputViewController { var nameActiveUsers:[String] = [] var users: [User] = [] override func viewDidLoad() { super.viewDidLoad() users = [User(id: 1, name: "Juan", isActive: true), User(id: 2, name: "Pedro", isActive: false), User(id: 3, name: "Alan", isActive: true), User(id: 4, name: "Pablo", isActive: false)] getNameActiveUsers() print(nameActiveUsers) } func getNameActiveUsers(){ var activeUsers = [User]() for user in users{ if user.isActive{ activeUsers.append(user) } } activeUsers.sort { (user1, user2) -> Bool in return user1.id < user2.id } for active in activeUsers{ nameActiveUsers.append(active.name) } } } Orientado a instrucciones Imperativo Defino “cómo” se realiza un proceso para alcanzar un resultado.
  • 7. Stateless struct User { var id: Int var name: String var isActive: Bool } Orientado a expresiones Declarativo class KeyboardViewController: UIInputViewController { override func viewDidLoad() { super.viewDidLoad() let users = [User(id: 1, name: "Juan", isActive: true), User(id: 2, name: "Pedro", isActive: false), User(id: 3, name: "Alan", isActive: true), User(id: 4, name: "Pablo", isActive: false)] print(getNameActiveUsers(users: users)) } func getNameActiveUsers(users: [User]) -> [String]{ return users.filter{$0.isActive} .sorted{$0.id < $1.id} .map{$0.name} } } “Di qué quieres, pero no cómo lo quieres”
  • 8. Stateless struct User { var id: Int var name: String var isActive: Bool } class KeyboardViewController: UIInputViewController { override func viewDidLoad() { super.viewDidLoad() let users = [User(id: 1, name: "Juan", isActive: true), User(id: 2, name: "Pedro", isActive: false), User(id: 3, name: "Alan", isActive: true), User(id: 4, name: "Pablo", isActive: false)] print(getNameActiveUsers(users: users)) } func getNameActiveUsers(users: [User]) -> [String]{ return users.filter{$0.isActive} .sorted{$0.id < $1.id} .map{$0.name} } } class KeyboardViewController: UIInputViewController { var nameActiveUsers:[String] = [] var users: [User] = [] override func viewDidLoad() { super.viewDidLoad() users = [User(id: 1, name: "Juan", isActive: true), User(id: 2, name: "Pedro", isActive: false), User(id: 3, name: "Alan", isActive: true), User(id: 4, name: "Pablo", isActive: false)] getNameActiveUsers() print(nameActiveUsers) } func getNameActiveUsers(){ var activeUsers = [User]() for user in users{ if user.isActive{ activeUsers.append(user) } } activeUsers.sort { (user1, user2) -> Bool in return user1.id < user2.id } for active in activeUsers{ nameActiveUsers.append(active.name) } } } // [“Juan”, “Alan”] // [“Juan”, “Alan”]
  • 9. Funciones de primera clase func getURLFromString(url:String) -> URL{ return URL(string: url)! } override func viewDidLoad() { super.viewDidLoad() let urlImage = “https://www.apple.com.mx" let url = getURLFromString(url: urlImage) } Un lenguaje de programación se dice que tiene Funciones de primera clase cuando las funciones en ese lenguaje son tratadas como cualquier otra variable.
  • 10. Funciones de primera clase func getImage(urlImage: String) -> UIImage{ let url = getURLFromString(url: urlImage) let data = getDataFromURL(url:url) let image = getImageFromData(data: data) return image } func getURLFromString(url:String) -> URL{ return URL(string: url)! } func getDataFromURL(url: URL) -> Data{ return try! Data(contentsOf: url) } func getImageFromData(data:Data) -> UIImage{ return UIImage(data: data)! }
  • 11. Funciones de orden Super Pueden tomar otra función como parámetro: func getURLFromString(url:String) -> URL{ return URL(string: url)! } func getDataFromURL(url: URL) -> Data{ return try! Data(contentsOf: url) } func getImageFromData(data:Data) -> UIImage{ return UIImage(data: data)! } func getImage(url: String, completion: (Data) -> UIImage) -> UIImage{ let url = getURLFromString(url: url) let data = getDataFromURL(url:url) return completion(data) } let image = getImage(url: urlImage, completion: getImageFromData)
  • 12. Funciones de orden Super Pueden tomar otra función como parámetro: func getURLFromString(url:String) -> URL{ return URL(string: url)! } func getDataFromURL(url: URL) -> Data{ return try! Data(contentsOf: url) } func getImageFromData(data:Data) -> UIImage{ return UIImage(data: data)! } func getImage(url: String, completion: (Data) -> UIImage) -> UIImage{ let url = getURLFromString(url: url) let data = getDataFromURL(url:url) return completion(data) } let image = getImage(url: urlImage, completion: getImageFromData) Firma de la función (Data) -> UIImage
  • 13. Funciones de orden Super Pueden devolver una función de salida: func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage))) image.draw(in: $0) return image } } let imageWithSize = image(CGRect(x: 0, y: 0, width: 50, height: 50))
  • 14. Funciones de orden Super Pueden devolver una función de salida: func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage))) image.draw(in: $0) return image } } let imageWithSize = image(CGRect(x: 0, y: 0, width: 50, height: 50))
  • 15. Pipelines func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{ return {second(first($0))} } infix operator |> : AdditionPrecedence
  • 16. Pipelines func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getURLFromString |> self.getDataFromURL |> self.getImageFromData image(urlImage) image.draw(in: $0) return image } } func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{ return {second(first($0))} } infix operator |> : AdditionPrecedence func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage))) image.draw(in: $0) return image } } Antes Después
  • 17. Pipelines func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getURLFromString |> self.getDataFromURL |> self.getImageFromData image(urlImage) image.draw(in: $0) return image } } func |> <T,U,V> (_ first: @escaping (T) -> U, second: @escaping (U) -> V) -> (T)->V{ return {second(first($0))} } infix operator |> : AdditionPrecedence func getImage(urlImage: String) -> (CGRect) -> UIImage { return { let image = self.getImageFromData(data: self.getDataFromURL(url: self.getURLFromString(url: urlImage))) image.draw(in: $0) return image } } Composición De funciones
  • 18. Patron Result Esto es similar al tipo Opcional nativo de Swift: el “some” es que tiene un valor, y el “none” es que no tiene. Es parecido a las promesas en Javascript enum Result<S,E>{ case success(_ :S) case failure(_ :E) }
  • 19. Patron Result class NotificationParser { private func serializeResponse(mapString:String) -> [String: Any]?{ return try! JSONSerialization.jsonObject(with: mapString.data(using: .utf8)!, options: [.allowFragments]) as? [String: Any] } func parseSomething(mapString: String, completion: @escaping(_ success: Bool, _ object: Any?) -> Void) { guard let dataJSON = serializeResponse(mapString: mapString) else { return completion(false, nil) } if dataJSON["success"] != nil { if dataJSON["success"] as! Bool { if let responseDictionary = dataJSON["data"] as? NSDictionary { let response = User.from(responseDictionary) print("CreateAccount: (response!)") completion(true,response) } else { completion(false, nil) } }else{ if let responseDictionary = dataJSON["errors"] as? NSArray { let errors = ErrorsResponse.from(responseDictionary) print("Valores del modelo errors: (errors!)") completion(false,errors?.first) } else { completion(false, ErrorsResponse.from(["status":0,"message":"duplicate"])) } } } else { completion(false, nil) } } }
  • 20. Patron Result enum ErrorType{ case notSerialized case notInternet case serverError(String) case messageErrorEmpty } extension ErrorType{ var description:String { switch self { case .notSerialize: print("Not Serilized") return "Error From Server" case .notInternet: print("there are not connection") return "Not Internet Conection" case .serverError (let message): return message case .messageErrorEmpty: return "" } } } class NotificationParser{ private func serializeResponse(mapString:String) -> [String: Any]?{ return try! JSONSerialization.jsonObject(with: mapString.data(using: .utf8)!, options: [.allowFragments]) as? [String: Any] } func parseSomething(mapString:String, completion: @escaping (Result<User,ErrorType>) -> Void){ guard let dictionary = serializeResponse(mapString: mapString) else { return completion(.failure(.notSerialized)) } guard let success = dictionary["success"] as? Bool else{ guard let errorMessage = dictionary["message"] as? String else{ return completion(.failure(.messageErrorEmpty)) } return completion(.failure(.serverError(errorMessage))) } guard let responseDictionary = dictionary["data"] as? Dictionary else{ return completion(.failure(.notSerialized)) } let response = User.from(responseDictionary) print("CreateAccount: (response!)") completion(.success(response)) } }
  • 21. Patron Result class NotificationViewControler:UIViewController { let manager = Managers.shareInstance override func viewDidLoad() { super.viewDidLoad() self.manager.createUser(email:email, password:password, completion: { [weak self] response in guard let strongself = self else{ return } switch response{ case .success(let user): strongSelf.titleLabel.text = user.name case .failure(let error): showAlertOK(error.description) } } } }
  • 22.
  • 23.
  • 24.
  • 26. Beneficios - Código concurrente. - Menos errores. Ya que la mayoría de tu código será con constantes. - Fácil de testar. Ya que un objeto se puede considera valido desde su creación, de ser así se va a considerar válido durante toda su existencia. - Código paralelisable. Que se puede ejecutar en cores diferentes al mismo tiempo. - Tolerante a fallos gracias al patron Result