Lightening Talk I gave at Inaka in November 2015, after having developed Swift for a while.
It contains some lessons, mostly learned from the functional paradigm, that can be useful for any developer.
Developing Swift - Moving towards the futurePablo Villar
This is a talk I gave at Ciudad Universitaria de Buenos Aires on July 23rd, 2015.
The idea was expressing how it felt for me (and my co-worker fellows at Inaka) start using Swift in our projects.
The talk has three aims:
- Speaking a bit about Swift's history.
- Communicating how our mindset as iOS developers has changed from an attitude point of view, rather than technical.
- Speaking briefly about one of Swift's features (optionals) and showing some code.
Writing a REST Interconnection Library in SwiftPablo Villar
(a.k.a. #warilis) This is a talk I gave on our first SwiftBA Meetup event on June 8th, 2016 at Inaka's Offices.
In this talk, I covered 3 main aspects:
1. Motivation: How does our need for such a library emerge? Why should we need it? What should or goals be?
2. Architectural Concept: How do we architecture this library? Which design patterns could help us?
3. Implementation: How do we code this library in a Swifty manner? How can we take advantage of Swift's powerful features?
At the very end, I conclude presenting Jayme: (https://github.com/inaka/Jayme), a real case open-source library that I've developed with help of some of my workmates at Inaka, in which I based this talk's concepts and code snippets.
P.S.: My apologies, I couldn't find a way to export this PDF respecting the stages of each slide, so they were exported without animations.
Android application development company in chennaiedsseo
Elicit Designz Solutions specializes in website development and web designing, mobile application development, PHP and wordpress web development and SEO services in chennai.
Developing Swift - Moving towards the futurePablo Villar
This is a talk I gave at Ciudad Universitaria de Buenos Aires on July 23rd, 2015.
The idea was expressing how it felt for me (and my co-worker fellows at Inaka) start using Swift in our projects.
The talk has three aims:
- Speaking a bit about Swift's history.
- Communicating how our mindset as iOS developers has changed from an attitude point of view, rather than technical.
- Speaking briefly about one of Swift's features (optionals) and showing some code.
Writing a REST Interconnection Library in SwiftPablo Villar
(a.k.a. #warilis) This is a talk I gave on our first SwiftBA Meetup event on June 8th, 2016 at Inaka's Offices.
In this talk, I covered 3 main aspects:
1. Motivation: How does our need for such a library emerge? Why should we need it? What should or goals be?
2. Architectural Concept: How do we architecture this library? Which design patterns could help us?
3. Implementation: How do we code this library in a Swifty manner? How can we take advantage of Swift's powerful features?
At the very end, I conclude presenting Jayme: (https://github.com/inaka/Jayme), a real case open-source library that I've developed with help of some of my workmates at Inaka, in which I based this talk's concepts and code snippets.
P.S.: My apologies, I couldn't find a way to export this PDF respecting the stages of each slide, so they were exported without animations.
Android application development company in chennaiedsseo
Elicit Designz Solutions specializes in website development and web designing, mobile application development, PHP and wordpress web development and SEO services in chennai.
SEO pro eshopy a jejich majitele/správce - Eshopvíkend 2015 :-)Jakub Kašparů
Tématem prezentace je popsat nejčastější chyby, které stále vidím na eshopech z pohledu SEO. Nabídnout řešení. Ukázat, jaké jsou možnosti z pohledu analýzy konkurence a odkazových příležitostí pro majitele eshopů.
SEO pro eshopy a jejich majitele/správce - Eshopvíkend 2015 :-)Jakub Kašparů
Tématem prezentace je popsat nejčastější chyby, které stále vidím na eshopech z pohledu SEO. Nabídnout řešení. Ukázat, jaké jsou možnosti z pohledu analýzy konkurence a odkazových příležitostí pro majitele eshopů.
Empathic Programming - How to write comprehensible codeMario Gleichmann
Slides to a (non-commercial) talk i gave 2011 at XPUG Rhein/Main (Germany) about how to write comprehensible code, regarding cognitive abilities of human mind.
This talk will explore inference from the perspective of protocols and generics and is based off a series of blog posts I've written(foxinswift.com) on the topic. In the first part of my talk casting number types through inference. I'll then show you struct serialization example demonstrating inferring a type through a mapping function. My last example will take you through inferring an associatedtype on a barebones promise implementation and we'll use it to in the context of making a network request. To finish things off I'll briefly speak on what's new in swift generics and some limitations of those features.
Scala is a programming language that mixes object oriented and functional programming in a powerful and flexible way. While it can not be considered as a mainstream language, it has seen a growing adoption trend.An important ingredient for this diffusion is its complete interoperability with Java and the fact that it runs on a solid platform such as the JVM.
It is currently the 4th most loved programming language and the 2nd top paying technology of 2016 (StackOverflow Developers Survey).
These slides have been used for a 4h seminar at the University of Cagliari the 17th of December 2016
Introduction to Swift programming language.Icalia Labs
Take a look to Swift, if you've been developing for iOS in Objective-C many things may look familiar, maybe just "upgraded". If you're a first timer diving into iOS development we strongly recommend you to understand first the basics of Cocoa.
Are you stuck in the Java world? I’ll share my story about convincing my team and the client of the benefits of Kotlin. Furthermore I’ll delve into how we migrated an existing Java Android app, with 300k active users, to Kotlin.
Even if you have never seen Kotlin before, come and see how you will create better apps with this modern and elegant language. At the end of this talk you’ll be able to convince your team / client why it’s a great to use Kotlin.
The power of Kotlin can be leveraged everywhere you use Java, since it compiles to JVM bytecode. So even if you’re not an Android developer, check out this session to get acquainted with Kotlin!
No excuses: switch to Kotlin
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
Even though at surface level ‘java.lang.OutOfMemoryError’ appears as one single error; underlyingly there are 9 types of OutOfMemoryError. Each type of OutOfMemoryError has different causes, diagnosis approaches and solutions. This session equips you with the knowledge, tools, and techniques needed to troubleshoot and conquer OutOfMemoryError in all its forms, ensuring smoother, more efficient Java applications.
We describe the deployment and use of Globus Compute for remote computation. This content is aimed at researchers who wish to compute on remote resources using a unified programming interface, as well as system administrators who will deploy and operate Globus Compute services on their research computing infrastructure.
Accelerate Enterprise Software Engineering with PlatformlessWSO2
Key takeaways:
Challenges of building platforms and the benefits of platformless.
Key principles of platformless, including API-first, cloud-native middleware, platform engineering, and developer experience.
How Choreo enables the platformless experience.
How key concepts like application architecture, domain-driven design, zero trust, and cell-based architecture are inherently a part of Choreo.
Demo of an end-to-end app built and deployed on Choreo.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Modern design is crucial in today's digital environment, and this is especially true for SharePoint intranets. The design of these digital hubs is critical to user engagement and productivity enhancement. They are the cornerstone of internal collaboration and interaction within enterprises.
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...Juraj Vysvader
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I didn't get rich from it but it did have 63K downloads (powered possible tens of thousands of websites).
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
The European Union Agency for Law Enforcement Cooperation (Europol) has suffered an alleged data breach after a notorious threat actor claimed to have exfiltrated data from its systems. Infamous data leaker IntelBroker posted on the even more infamous BreachForums hacking forum, saying that Europol suffered a data breach this month.
The alleged breach affected Europol agencies CCSE, EC3, Europol Platform for Experts, Law Enforcement Forum, and SIRIUS. Infiltration of these entities can disrupt ongoing investigations and compromise sensitive intelligence shared among international law enforcement agencies.
However, this is neither the first nor the last activity of IntekBroker. We have compiled for you what happened in the last few days. To track such hacker activities on dark web sources like hacker forums, private Telegram channels, and other hidden platforms where cyber threats often originate, you can check SOCRadar’s Dark Web News.
Stay Informed on Threat Actors’ Activity on the Dark Web with SOCRadar!
How to Position Your Globus Data Portal for Success Ten Good PracticesGlobus
Science gateways allow science and engineering communities to access shared data, software, computing services, and instruments. Science gateways have gained a lot of traction in the last twenty years, as evidenced by projects such as the Science Gateways Community Institute (SGCI) and the Center of Excellence on Science Gateways (SGX3) in the US, The Australian Research Data Commons (ARDC) and its platforms in Australia, and the projects around Virtual Research Environments in Europe. A few mature frameworks have evolved with their different strengths and foci and have been taken up by a larger community such as the Globus Data Portal, Hubzero, Tapis, and Galaxy. However, even when gateways are built on successful frameworks, they continue to face the challenges of ongoing maintenance costs and how to meet the ever-expanding needs of the community they serve with enhanced features. It is not uncommon that gateways with compelling use cases are nonetheless unable to get past the prototype phase and become a full production service, or if they do, they don't survive more than a couple of years. While there is no guaranteed pathway to success, it seems likely that for any gateway there is a need for a strong community and/or solid funding streams to create and sustain its success. With over twenty years of examples to draw from, this presentation goes into detail for ten factors common to successful and enduring gateways that effectively serve as best practices for any new or developing gateway.
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?XfilesPro
Worried about document security while sharing them in Salesforce? Fret no more! Here are the top-notch security standards XfilesPro upholds to ensure strong security for your Salesforce documents while sharing with internal or external people.
To learn more, read the blog: https://www.xfilespro.com/how-does-xfilespro-make-document-sharing-secure-and-seamless-in-salesforce/
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
Strategies for Successful Data Migration Tools.pptxvarshanayak241
Data migration is a complex but essential task for organizations aiming to modernize their IT infrastructure and leverage new technologies. By understanding common challenges and implementing these strategies, businesses can achieve a successful migration with minimal disruption. Data Migration Tool like Ask On Data play a pivotal role in this journey, offering features that streamline the process, ensure data integrity, and maintain security. With the right approach and tools, organizations can turn the challenge of data migration into an opportunity for growth and innovation.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
Why React Native as a Strategic Advantage for Startup Innovation.pdfayushiqss
Do you know that React Native is being increasingly adopted by startups as well as big companies in the mobile app development industry? Big names like Facebook, Instagram, and Pinterest have already integrated this robust open-source framework.
In fact, according to a report by Statista, the number of React Native developers has been steadily increasing over the years, reaching an estimated 1.9 million by the end of 2024. This means that the demand for this framework in the job market has been growing making it a valuable skill.
But what makes React Native so popular for mobile application development? It offers excellent cross-platform capabilities among other benefits. This way, with React Native, developers can write code once and run it on both iOS and Android devices thus saving time and resources leading to shorter development cycles hence faster time-to-market for your app.
Let’s take the example of a startup, which wanted to release their app on both iOS and Android at once. Through the use of React Native they managed to create an app and bring it into the market within a very short period. This helped them gain an advantage over their competitors because they had access to a large user base who were able to generate revenue quickly for them.
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
Code reviews are vital for ensuring good code quality. They serve as one of our last lines of defense against bugs and subpar code reaching production.
Yet, they often turn into annoying tasks riddled with frustration, hostility, unclear feedback and lack of standards. How can we improve this crucial process?
In this session we will cover:
- The Art of Effective Code Reviews
- Streamlining the Review Process
- Elevating Reviews with Automated Tools
By the end of this presentation, you'll have the knowledge on how to organize and improve your code review proces
Advanced Flow Concepts Every Developer Should KnowPeter Caitens
Tim Combridge from Sensible Giraffe and Salesforce Ben presents some important tips that all developers should know when dealing with Flows in Salesforce.
Check out the webinar slides to learn more about how XfilesPro transforms Salesforce document management by leveraging its world-class applications. For more details, please connect with sales@xfilespro.com
If you want to watch the on-demand webinar, please click here: https://www.xfilespro.com/webinars/salesforce-document-management-2-0-smarter-faster-better/
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
5. Let’s talk about functions!
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
6. var number = 4 // A boring Int
Let’s talk about functions!
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
7. var number = 4 // A boring Int
Let’s talk about functions!
var sum = { (a: Float, b: Float) in
return a + b
}
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
8. var number = 4 // A boring Int
Let’s talk about functions!
var sum = { (a: Float, b: Float) in
return a + b
}
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
// A fun...ction
9. var number = 4 // A boring Int
Let’s talk about functions!
var sum = { (a: Float, b: Float) in
return a + b
}
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
// A fun...ction
10. var number = 4 // A boring Int
Let’s talk about functions!
var sum = { (a: Float, b: Float) in
return a + b
}
let four = sum(2, 2)
print(four) // Prints 4.0
Did you know that in Swift you can assign functions to variables?
No, seriously…
*pun intended
fun
// A fun...ction
15. Higher order functions
Moment…
What’s that?
Roughly speaking…
"A higher order function is a function that accepts functions
as parameters"
- Some guy.
16. let sum = { (a: Float, b: Float) in
return a + b
}
let subtract = { (a: Float, b: Float) in
return a - b
}
let multiply = { (a: Float, b: Float) in
return a * b
}
let divide = { (a: Float, b: Float) in
return a / b
}
func main() {
let eight = operateOn(6, and: 2, usingFunction: sum)
let four = operateOn(6, and: 2, usingFunction: subtract)
let twelve = operateOn(6, and: 2, usingFunction: multiply)
let three = operateOn(6, and: 2, usingFunction: divide)
}
func operateOn(a: Float, and b: Float, usingFunction f: (Float, Float) -> Float)
-> Float {
return f(a, b)
}
17. let sum = { (a: Float, b: Float) in
return a + b
}
let subtract = { (a: Float, b: Float) in
return a - b
}
let multiply = { (a: Float, b: Float) in
return a * b
}
let divide = { (a: Float, b: Float) in
return a / b
}
func main() {
let eight = operateOn(6, and: 2, usingFunction: sum)
let four = operateOn(6, and: 2, usingFunction: subtract)
let twelve = operateOn(6, and: 2, usingFunction: multiply)
let three = operateOn(6, and: 2, usingFunction: divide)
}
func operateOn(a: Float, and b: Float, usingFunction f: (Float, Float) -> Float)
-> Float {
return f(a, b)
}
We have defined 4
functions
as variables.
18. let sum = { (a: Float, b: Float) in
return a + b
}
let subtract = { (a: Float, b: Float) in
return a - b
}
let multiply = { (a: Float, b: Float) in
return a * b
}
let divide = { (a: Float, b: Float) in
return a / b
}
func main() {
let eight = operateOn(6, and: 2, usingFunction: sum)
let four = operateOn(6, and: 2, usingFunction: subtract)
let twelve = operateOn(6, and: 2, usingFunction: multiply)
let three = operateOn(6, and: 2, usingFunction: divide)
}
func operateOn(a: Float, and b: Float, usingFunction f: (Float, Float) -> Float)
-> Float {
return f(a, b)
}
We have defined 4
functions
as variables.
We pass in those functions in the
operateOn call "as if" they
were variables… (well, they
actually are)
19. operateOn is a higher order function, because it
accepts a function as an input parameter.
let sum = { (a: Float, b: Float) in
return a + b
}
let subtract = { (a: Float, b: Float) in
return a - b
}
let multiply = { (a: Float, b: Float) in
return a * b
}
let divide = { (a: Float, b: Float) in
return a / b
}
func main() {
let eight = operateOn(6, and: 2, usingFunction: sum)
let four = operateOn(6, and: 2, usingFunction: subtract)
let twelve = operateOn(6, and: 2, usingFunction: multiply)
let three = operateOn(6, and: 2, usingFunction: divide)
}
func operateOn(a: Float, and b: Float, usingFunction f: (Float, Float) -> Float)
-> Float {
return f(a, b)
}
We have defined 4
functions
as variables.
We pass in those functions in the
operateOn call "as if" they
were variables… (well, they
actually are)
22. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Let’s see a more practical example…
23. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Mutability
Let’s see a more practical example…
24. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Mutability
Danger!
Let’s see a more practical example…
25. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Mutability
Danger!
But… Hold on… Why?
Let’s see a more practical example…
26. Nope,
it’s not
this…
func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Mutability
Danger!
But… Hold on… Why?
Let’s see a more practical example…
27. Mutability:
By using mutable variables, we are not 100% sure what
the value of the variable at some point is.
It could be modified somewhere, and that leads to the
fact that we need to keep track of where that variable
is being used and how it’s being modified.
In smaller cases like this, it’s easy to keep track, but…
28. for jsonRow in rows {
var post = Post(json: jsonRow)
let postId = jsonRow["id"].stringValue
if let storedPost = realm.objects(Post).filter("id = %@", postId).first {
post = storedPost
post!.refresh(jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = PostType(rawValue:(storedPost.postType.rawValue | feedType.rawValue))
updates.append(post!.id)
} else {
post = Post(json: jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = feedType
additions.append(postId)
}
realm.add(post!, update: true)
}
How about this…?
29. for jsonRow in rows {
var post = Post(json: jsonRow)
let postId = jsonRow["id"].stringValue
if let storedPost = realm.objects(Post).filter("id = %@", postId).first {
post = storedPost
post!.refresh(jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = PostType(rawValue:(storedPost.postType.rawValue | feedType.rawValue))
updates.append(post!.id)
} else {
post = Post(json: jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = feedType
additions.append(postId)
}
realm.add(post!, update: true)
}
How about this…?
Let’s keep track of post…
30. for jsonRow in rows {
var post = Post(json: jsonRow)
let postId = jsonRow["id"].stringValue
if let storedPost = realm.objects(Post).filter("id = %@", postId).first {
post = storedPost
post!.refresh(jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = PostType(rawValue:(storedPost.postType.rawValue | feedType.rawValue))
updates.append(post!.id)
} else {
post = Post(json: jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = feedType
additions.append(postId)
}
realm.add(post!, update: true)
}
How about this…?
Let’s keep track of post…
31. for jsonRow in rows {
var post = Post(json: jsonRow)
let postId = jsonRow["id"].stringValue
if let storedPost = realm.objects(Post).filter("id = %@", postId).first {
post = storedPost
post!.refresh(jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = PostType(rawValue:(storedPost.postType.rawValue | feedType.rawValue))
updates.append(post!.id)
} else {
post = Post(json: jsonRow, endpoint: self.basePath as! ServerEndpoint)
post!.postType = feedType
additions.append(postId)
}
realm.add(post!, update: true)
}
How about this…?
At this point, we can’t easily ensure what the post is going to be…
Let’s keep track of post…
32. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Back to our example…
Could we replace it, somehow, such that we
avoid mutability?
33. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
34. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let :)
35. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let 😊
36. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let 😊
Yes, emojis are allowed in Swift source code… ✌
37. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let 😊
Yes, we are tending to become hippies
Yes, emojis are allowed in Swift source code… ✌
38. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let 😊
Yes, we are tending to become hippies
Yes, emojis are allowed in Swift source code… ✌
39. func teenagersFromPeople(people: [Person]) -> [Person] {
let teenagers: [Person]
teenagers = people.filter({ (person) -> Bool in
return person.age > 12 && person.age < 20
})
return teenagers
}
Higher order functions to the rescue!
// let 😊
Yes, we are tending to become hippies
Yes, emojis are allowed in Swift source code… ✌
If we could just simplify this…
42. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Not
preferred
Higher order functions
43. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Not
preferred
func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
Preferred
Higher order functions
44. func teenagersFromPeople(people: [Person]) -> [Person] {
var teenagers = [Person]()
for person in people {
if person.age > 12 && person.age < 20 {
teenagers.append(person)
}
}
return teenagers
}
Not
preferred
func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
Preferred
FILTER
Higher order functions
45. func idsFromPeople(people: [Person]) -> [String] {
var ids = [String]()
for person in people {
ids.append(person.id)
}
return ids
}
Not
preferred
Higher order functions
46. func idsFromPeople(people: [Person]) -> [String] {
var ids = [String]()
for person in people {
ids.append(person.id)
}
return ids
}
func idsFromPeople(people: [Person]) -> [String] {
return people.map { $0.id }
}
Preferred
Not
preferred
Higher order functions
47. func idsFromPeople(people: [Person]) -> [String] {
var ids = [String]()
for person in people {
ids.append(person.id)
}
return ids
}
func idsFromPeople(people: [Person]) -> [String] {
return people.map { $0.id }
}
Preferred
Not
preferred
MAP
Higher order functions
49. func childrenCountFromPeople(people: [Person]) -> Int {
var count = 0
for person in people {
count += person.children.count
}
return count
}
func childrenCountFromPeople(people: [Person]) -> Int {
return people.reduce(0) { $0 + $1.children.count }
}
Preferred
Not
preferred
Higher order functions
50. func childrenCountFromPeople(people: [Person]) -> Int {
var count = 0
for person in people {
count += person.children.count
}
return count
}
func childrenCountFromPeople(people: [Person]) -> Int {
return people.reduce(0) { $0 + $1.children.count }
}
Preferred
Not
preferred
REDUCE
Higher order functions
51. FILTER
MAP
REDUCE
You want some of the original
elements
You want new elements based
on the original elements
You want a result based on the
original elements
53. Pure functions
A pure function is a function where the return value is only
determined by its input values, without observable side
effects.
54. Pure functions
A pure function is a function where the return value is only
determined by its input values, without observable side
effects.
• There is a return value
55. Pure functions
A pure function is a function where the return value is only
determined by its input values, without observable side
effects.
• There is a return value
• Result depends only on input values
56. Pure functions
A pure function is a function where the return value is only
determined by its input values, without observable side
effects.
• There is a return value
• No side effects
• Result depends only on input values
57. Pure functions
A pure function is a function where the return value is only
determined by its input values, without observable side
effects.
• There is a return value
• No side effects
• Result depends only on input values 100%
unit-testable!
58. • There is a return value
• No side effects
• Result depends only on input values
func configureLabelTextWithNumber(number: Int) {
self.numberLabel.text = "(number)"
}
Example #1
Pure functions
59. • There is a return value
• No side effects
• Result depends only on input values
func configureLabelTextWithNumber(number: Int) {
self.numberLabel.text = "(number)"
}
• There is a return value ❌
Example #1
Pure functions
60. • There is a return value
• No side effects
• Result depends only on input values
func configureLabelTextWithNumber(number: Int) {
self.numberLabel.text = "(number)"
}
• There is a return value ❌
• Result depends only on input values ✅
Example #1
Pure functions
61. • There is a return value
• No side effects
• Result depends only on input values
func configureLabelTextWithNumber(number: Int) {
self.numberLabel.text = "(number)"
}
• There is a return value ❌
• No side effects ❌
• Result depends only on input values ✅
Example #1
Pure functions
62. • There is a return value
• No side effects
• Result depends only on input values
func configureLabelTextWithNumber(number: Int) {
self.numberLabel.text = "(number)"
}
• There is a return value ❌
• No side effects ❌
• Result depends only on input values ✅
Example #1
Functions using "self.something" are a call to side effects
Pure functions
63. • There is a return value
• No side effects
• Result depends only on input values
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
Pure functions
64. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
Pure functions
65. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• Result depends only on input values ✅
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
Pure functions
66. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ✅
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
Pure functions
67. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ✅
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
Pure
function
Pure functions
68. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ✅
func labelTextForNumber(number: Int) -> String {
return "(number)"
}
Example #1
self.numberLabel.text = self.labelTextForNumber(1)
Pure
function
Pure functions
69. func teenagers() -> [Person] {
return self.people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
Example #2
Pure functions
70. func teenagers() -> [Person] {
return self.people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
Example #2
Pure functions
71. func teenagers() -> [Person] {
return self.people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
Example #2
Pure functions
72. func teenagers() -> [Person] {
return self.people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
Example #2
• Result depends only on input values ❌
Pure functions
73. func teenagers() -> [Person] {
return self.people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
Example #2
• Result depends only on input values ❌
How would you test it?
Pure functions
74. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
Example #2
Pure functions
75. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
Example #2
Pure functions
76. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
Example #2
• Result depends only on input values ✅
Pure functions
77. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
Example #2
• Result depends only on input values ✅
Pure functions
78. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
• There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
Example #2
• Result depends only on input values ✅
Pure
function
Pure functions
79. func teenagersFromPeople(people: [Person]) -> [Person] {
return people.filter { $0.age > 12 && $0.age < 20 }
}
Example #2
func test15YearsOldIsTeenager() {
let filter = PeopleFilter() // System Under Test
let someone = Person(name: "asd", age: 15)
let input = [someone]
let output = filter.teenagersFromPeople(input)
XCTAssertEqual(output.count, 1)
if output.count == 1 {
XCTAssertEqual(output.first!, someone)
}
}
Pure
function
100%
unit-testable!
Pure functions
80. • There is a return value
• No side effects
• Result depends only on input values
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Pure functions
81. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Pure functions
82. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Pure functions
83. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ❌
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Pure functions
84. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ❌
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Functions involving randomness can never be pure functions
Pure functions
85. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ❌
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Functions involving randomness can never be pure functions
They are not unit-testable, because we can't know what expected result is
Pure functions
86. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ❌
func randomCharacterFromString(string: String) -> String {
let maxNumber = UInt32((string as NSString).length)
let randomNumber = Int(arc4random_uniform(maxNumber))
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
Functions involving randomness can never be pure functions
They are not unit-testable, because we can't know what expected result is , unless…
Pure functions
87. • There is a return value
• No side effects
• Result depends only on input values
func randomCharacterFromString(string: String, seed: Int) -> String {
let maxNumber = Int32((string as NSString).length)
srand(UInt32(seed)) // Configure the randomizer's seed
let randomNumber = Int(rand() % maxNumber)
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
, unless…
Pure functions
88. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
func randomCharacterFromString(string: String, seed: Int) -> String {
let maxNumber = Int32((string as NSString).length)
srand(UInt32(seed)) // Configure the randomizer's seed
let randomNumber = Int(rand() % maxNumber)
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
, unless…
Pure functions
89. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• Result depends only on input values ✅
func randomCharacterFromString(string: String, seed: Int) -> String {
let maxNumber = Int32((string as NSString).length)
srand(UInt32(seed)) // Configure the randomizer's seed
let randomNumber = Int(rand() % maxNumber)
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
, unless…
Pure functions
90. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ✅
func randomCharacterFromString(string: String, seed: Int) -> String {
let maxNumber = Int32((string as NSString).length)
srand(UInt32(seed)) // Configure the randomizer's seed
let randomNumber = Int(rand() % maxNumber)
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
, unless…
Pure functions
91. • There is a return value
• No side effects
• Result depends only on input values
• There is a return value ✅
• No side effects ✅
• Result depends only on input values ✅
func randomCharacterFromString(string: String, seed: Int) -> String {
let maxNumber = Int32((string as NSString).length)
srand(UInt32(seed)) // Configure the randomizer's seed
let randomNumber = Int(rand() % maxNumber)
let range = NSRange(location: randomNumber, length: 1)
return (string as NSString).substringWithRange(range)
}
Example #3
, unless…
Pure
function
Pure functions
92. Pure functions
Higher order functions
Protocol-oriented
programming
Immutability
Generic
programming
Pattern matching
MVVM
93. If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
94. If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
But also…
95. The intention of your code is clearer
If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
But also…
96. The intention of your code is clearer
If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
But also…
Code is easier to understand for others
97. The intention of your code is clearer
If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
But also…
Code is easier to understand for others
Less headaches when maintaining each others’ code
98. The intention of your code is clearer
If you start applying these little yet valuable concepts…
Your brain starts to think in different ways and your mind
gets open to learn more and more!
But also…
Code is easier to understand for others
Less headaches when maintaining each others’ code
More effectiveness, more productivity