1. Futures
Hello! In this lesson we will talk about futures in programming.
2. The demanding boss
Imagine our boss asks us to send a report to a client. We say that we'll do it after completing our current tasks. We don't do it immediately but there is an implied promise to do it.
This implied promise is very similar to a future in programming.
3. Immediate execution
Let's code this task in R. We have our report.
We write an email and attach the report. When we run this code our email is printed.
The task variable contains the report. All code within the curly braces is executed when the variable is created.
4. Delayed execution
But we can't interrupt our current task whenever a new task arrives. That would be very inefficient.
So how do we code a task to be executed later?
We load the future package. We supply all the code in curly braces to the future() function to create the variable task-underscore-future.
When we run this, nothing happens. This is because we created a future and it will be run when needed. So what are the contents of this future?
5. Delayed execution
If we print the task_future variable, it looks like a planner entry.
There's the code, the context, whether the task is already done, and, if so, a description of the result or value. What is this value?
6. Delayed execution
We can query the value using the value() function.
What happens is that as soon as we print task_future, the task is executed and the value slot inside task_future is filled with the result.
7. A team of workers
This behavior has important implications.
Imagine we are part of a team. Our boss assigns us multiple tasks.
8. A team of workers
We create a future for each task. Now, we have the option to plan.
During the morning, the office administrator uses the information stored in the futures to send the report and book meeting rooms.
The analyst has time in the afternoon and runs the analysis then.
Futures enabled many workers to handle a series of tasks efficiently.
9. Moving average with futures
Now let's say we have daily Amazon stock prices for one month. We also have a function, moving-underscore-average. It calculates an average for every three day period.
We create a future, called "ma", for the application of moving_average() to amazon_prices.
When we run this nothing happens.
10. Moving average with futures
But as soon as the value of this variable is required the task becomes urgent. Here we are making a line plot of the moving averages. The future is executed instantly and we get our results.
11. Parallel futures
Let's say now we have a list of variables, amazon-underscore-list. Each element corresponds to a month's prices.
We want to apply moving_average() to each element of amazon_list.
We have four cores available, similar to our team of workers.
12. Parallel futures
First we make a plan.
The plan() function from the future package can do this. We specify a multisession plan which means code is run in multiple R sessions.
We also specify the number of cores or workers we want to employ.
Using lapply(), we create a future for each mapping of moving_average() onto an element of amazon_list. While we use the sequential lapply() to create the futures, the plan determines whether these futures will be executed sequentially or in parallel.
13. Parallel futures
When we query their value, they are executed in parallel.
Once done, we switch back to a sequential plan to avoid creating parallel futures unintentionally.
14. Why future?
The key advantage of futures is that we can run code sequentially or in parallel without making any changes to the code itself.
15. Let's practice!
Now let's practice these new concepts!