KotlinConf 2018 - Exploring Coroutines in Kotlin by Venkat Subramaniam

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

That is some serious live coding.

👍︎︎ 6 👤︎︎ u/nhaarman 📅︎︎ Oct 09 2018 🗫︎ replies
Captions
[Music] [Applause] [Music] all right good morning welcome to the session on exploring co-routines in Catalan my name is Venkat Subramanyam I'm gonna talk about what's really exciting about co-routines why should we consider using it what are some of the problems it salts so that's what we're gonna focus on but before we do that I want to kind of step back and talk about where we are being especially in the in the world of Java and JVM and then why we should really consider maybe doing something very different in fact what's really exciting is languages like Kotlin are maybe I would say five to six years if not a decade earlier than where Java will be in terms of some of these things that'll become available eventually in Java but one of the things that we've been doing a lot in Java in general is parallelism in and I came from a background of C++ Java C sharp and languages like that and and pretty much I spend most of my life in sequential versus parallel computing and when I started programming in node I found it really hard in the beginning because I had to really think a synchronously rather than thinking in sequential versus parallel and that that was a huge paradigm shift for me in my mind but as I went through that I realized that this is where the real power is when it comes to scale while parallel is exciting I think we should really start rethinking the way we do things and asynchrony is seems to be making a lot more sense this is especially true in the world of micro services and such that we live in today this becomes very very very critical so let's talk a little bit about where does this really take us well when it comes to you know languages like Java we've been focusing on concurrency but rather than saying I want to run things in parallel what if we think along the lines of non blocking so I want to make a call but I don't want to wait and wait for that call to finish I want to just fire and forget and move on and when that call is finished maybe some process can't execute right after that so rather than concurrency and parallelism what if we start thinking in terms of non blocking calls but before we explore that let's think about you know what is the similarity and why is really exciting and I'm really beginning to rethink about some of the you know paradigms that we are exposed to and so let's back just a little bit to Java in and spend just a couple of minutes looking at something that Java really nicely for whites and then and then see where we want to go very differently now if you really think about you know the world of Java for a minute what did we have in the past well we had the imperative style of programming in the past but with the impure style of programming it's incredibly difficult to program concurrency so if you have written a sequential code using a traditional for loop for example and if somebody comes to you and says make the score parallel you will find the nearest exit because it's really hard to paralyze a code which is written imperatively but on the other hand if you were to take let's say a list of numbers if you will again just just a few minutes on Java here I can say numbers start stream and then I can perform a map operation for example map to int and give an element we could transform the element if you will and then of course once they do this I'll reduce this and in this case we'll just say reduce it using the sum method so that's a pretty simple operation but if I were to run this sequentially it would take as much time as the transform method is gonna take excuse me so what is the transform a method do it's going to do some kind of computation we don't care about what it's actually doing but let's say let's keep it extremely trivial here this going to simply return the value let's say and after all but I could introduce a little sleep function right here let's say this is gonna you know to pretend that it's gonna take some time to compute and if I were to provide a sleep function what what would it take for this code to execute well that's gonna take about 10 seconds for this code to execute after all because it's going to have to loop through every single element and do it and you can see the beach ball running right there but what if I want to parallelize this code that's one of the nice things about the streams API err is it makes it really easy to penalize it so I can simply say parallel and then of course we can just run this code and as you know it is a take that 10 seconds anymore that was quite fast so what we learned from that little exercise or from that experience and I would say one of the things we learned about it is that we can definitely relate to this very nicely so that the structure of I'm gonna say functional sequential code is the same as that of the parallel code and this is a huge benefit if you really think about it so this is really what we got from parallel streams and one of the really thinks about parallel streams is the structure of functional styled sequential code is the same as the structure of functional style parallel code but this is a huge benefit because in the past the code structure was so different between sequential and parallel it was really hard to maintain that code I want to take this forward and see what co-routines really give us and and maybe we can relate to that similarity in just a few minutes so let's step back and talk about you know why not be happy with just using parallel well it turns out that functional style is really awesome no doubt about it I love functional programming I like the way it works but there are times when maybe that's not the right choice or not for everything we do one of the things that really bothers me with functional style though is how does it really handle exceptions it is incredibly messy when it comes to dealing with exceptions and functional style part of the reason for that is the functional style of programming and exception handling are actually mutually exclusive it doesn't really make sense to throw exceptions in the code when you are dealing with functional style what functional style is really beautiful when you're dealing with pure functions but what if the functions are not pure what if you're doing IO which is the reality when you call a web service for example and what if those calls are gonna fail as typically it would when you talk to a web service our update a file or do other database operations so this is where co-routines can come in really handy so one of the things about co-routines are that co-routines are inherently asynchronous let's explore this a little bit to see what this really means in the context of coroutines so I'm going to start here with a little bit about Cartland right here so let's go ahead and create a process function it is taking an integer I'm going to keep it extremely simple and trivial here in this case all I'm gonna do is simply return the value given to me so when I when I go to this process I'm gonna just return the value and I want to call this particular method so I'm gonna print line and call the process method oh let's send a value of two rather a very simple example the process of simply returning what's given to it but obviously in this case we can ask for the thread information so I can say thread dart current thread and and the current thread of execution that's executing this code is going to be of course no surprise here it's going to be the main thread so that's Cartland reporting that we returned running a main thread and then of course the process is returning it but what in the what thread is the process really running so we could say process and then we could ask for the thread information within that of course and in this case we can immediately relate to and say of course that's going to run in the main thread as well and so as a result you can see that both of them are running in the main thread but what if I want to really run things in a different thread run it asynchronously in other words I don't want to block I don't want to wait for a process to be completed well in that case what I could do here is we could launch for example so I could say launch that particular process and I could ask it to run asynchronously and we'll talk more about this as we go along so I'm just calling a method called launch and say go ahead and fire that off and let that run and I'm gonna just put a little sleep here just to keep that alive if you will and we'll say sleep for about you know two seconds so we can fire them off and say go execute this on you know asynchronously and come back and report me the result so how does this really work so we can go ahead and import the launch method that I'm gonna use right in here so go ahead and fire that off and see what it's going to do and of course it you know requires that I spelled this properly so let's try this and then of course when I run this in here you can see that it is going to report to us that that's running off in a completely different thread so it's not really that hard to launch things and let them you know go off and run on a different thread automatically so you can see the mail is still running in the main thread but when we call the launch the process is running in a completely different thread so we could set off to things a synchronously but where does this really take us what we can go from a synchronous execution to a synchronous execution so in other words what we are saying is rather than having to execute something in the current thread and waiting on the process to finish we could just fire off that process and have that execute and then as that executes we can go back and do other things when would you want to really do this so one of the places where this becomes at least very critical is imagine you are in a UI thread well it could be a swing application or could be an Android application it really doesn't matter and we know that when you're in a UI based application in the UI thread you don't want to do anything that blocks because if you block in the UI thread the application becomes completely non-responsive and when the application becomes non-responsive it really results in a very poor user experience and the user score I was going to leave in in today's world where we are using devices we need immediate response respond responsiveness is extremely important so what do we do we can instead say well when I'm performing an operation on the UI thread I don't want to block and wait the UI thread for this let's just go ahead and you know make the call and continue processing other UI events well but what you want to do is to make this programming really easy because if it becomes really hard then it becomes expensive to write this code and to maintain it as well so in other words you want asynchrony to be as seamless as possibly you can get to so this is where you want to go from synchronous call to asynchronous call but also on the same note from blocking to non blocking calls that's what we really are interested so how does co-routines actually work what do they really provide for us so one of the things to really consider when it comes to co-routines is so what does it really mean to say it's a KO routine a code of teens have been around in programming languages for a very long time Catalan is not the first language to do it definitely but Catalan has a very what I'd like to call as high genic syntax so it becomes really easy to engage that in the code and to be able to process that so let's think about a little example to see how co-routines actually work so to understand this we're gonna write a method and and usually when you are writing methods you can mark a method as a method that would be suspending the call and then it can go off and execute potentially in a different thread but more important is synchronously well we cannot talk about co-routines without talking about continuations so under the hood it really is continuations that play a very important role so what is really a continuation so if this is a concept that has been around the game for a long time we're not quite exposed to this in the jvm languages unfortunately but that's going to change in the future but co-routines basically rely upon continuations so imagine you are making a call to a web server right now how does the traditional java web server work you make a call and say I want to process this request and then you establish who you are and then the response comes back and then when you want to maybe click on a link and send more data you reestablish your credentials and you say hey Here I am can I engage in a conversation and and this is the way we unfortunately implement the the web services on the other hand imagine how you and I communicate excuse me maybe you and I met yesterday we talked about something and this morning we can just hit off the conversation and start from where we left we don't have to re-establish the context because we remember the context that's exactly where continuations come in so imagine you make a call to a function but when you return from the function what if you can return not just the result of the function but a context of where you returned from when that caller wants to continue back with you they can call back into the context and continue let's take a look at how this is going to look like with a little example where we can just kind of entertain the start and see how this would work so to understand this let's go ahead and talk about one example of a sequence this is a rapper but API provided in Cartland so I'm gonna say sequence is equal to and I'm gonna say begin sequence over here and and let's go ahead and just start with a little sequence of call and within here I'm gonna simply ield let's start with baby steps I'm gonna ield one and I'm gonna stay in here value in will just say sequins right now and I'm going to simply print out those particular value that I've received on my hand and I'm just gonna start with this little example to you know just play with this and see how it's going to progress right now so so what we're doing here is to just start with a little you know lazy evaluation but what this object is going to do for us really is is it's going to give us an ability to walk through the code and be able to you know engage in a context of evaluation but the beautiful thing about co-routines is that you can continue from where you left a left off very easily if you will I'm gonna just pull in a little code here and play with this and I'm backing out so give me a second so all you're doing is you're just engaging in this conversation and pulling this data and moving forward so let's see how this is going to work with in just a little example here just to see how this is going to play out so what I'm going to do here is of course a build sequence sorry so so I'm gonna just build a sequence and continue with this conversation so what does this do well this is a little trivial it said yield one but let's go ahead and say over here we'll just say one for a minute and of course you know you're entering this method it says a 1 but the real nice thing about this is this is something you see in other languages like JavaScript as well so I'm gonna say 2 over here I'm gonna yield a value of 2 and maybe just a couple of more we'll say 3 here and ill the value of 3 but the beauty of this conversation is and then I'm gonna first finally say for example here let's go ahead and say done for a minute so when you look at this particular code you can see that you come into the sequence right now but I'm gonna say here well the value is let's say and then we'll just print the value we receive but when you execute this particular sequence of calls notice the the format of the call and how it goes back and forth between the code so we entered into the sequence we printed the one on the top line number 4 and then we say the value is 1 which is from line number 17 but notice that when we are looping through we step back right into line number 6 and execute we leave off at line number eight but then when we go back we go into line number nine and execute it so this is really where you are jumping into the middle of a function executing a part of it and then you're jumping back into the middle of the function and executing part of it so in other words you're not entering into the top of the method every single time you are leaving off here when you come back you do this part and then when you come back you do this part and then eventually you finish this part and go away it's intriguing to think about how in the world this could possibly work and and the way this actually works is when you are leaving off with the yield like I mentioned earlier you're not only returning this result but you are taking the remaining part of the code and moving it as what is the continuation so think of this as a lambda if you will so you're returning two parts to the caller one is the result of the call but the other is a lambda so the caller can use the result and then fire back right into the lambda and then you continue executing here and then this part again becomes the next continuation you return and then of course when you return this this part becomes the following continuation and then when you are done with this of course there is nothing to continue at the very end so continuations play a really vital role when it comes to using co-routines and you can dissect the code and see how this is working internally but to understand this let's try to do something a little different and see how we can put this into a bit of a practical context so to understand this let's go over here to a little example and play with it so the first thing here is I'm gonna go to the command prompt here for a second and I'm gonna open a little service I have our localhost 8080 five hopefully that's running but I'll Bera fie that and I'm gonna ask for the ticker Google and the service I'm running locally on this machine is just gonna report to me the price of a stock symbol when I asked for it so that's a price for a Google that is reports so it seems like that service that I'm running locally is running but let's go ahead and see how I can make use of that service here in my code and see why this is a little bit of a better approach than maybe using other approaches so to understand this let's go back here to a little example let's start with the book Tec baby steps let's take a function right now we'll call it as get stock price and and the stock price is going to take a dicker let's go and call that as a string and what I want to do is simply return a string I'll just keep it extremely simple here so I'm gonna just return back a string what do I want to return from here we'll say Java dot util dot URL and in this case well would let dot URL and in this case what people do is simply provide the HTTP localhost and this is going to be 80-85 is the port I'm running in a ticker is equal to and the given ticker so we'll just provide the ticker symbol for it to fight off the request but one of the nice things we can do here is we can then say on this one we can ask for the text so we could simply say this is going to return to me a text basically I can ask for a text value to be returned from this once I get the text value from this call what do I want to do I want to obviously print that result so we can say get stock price and we could ask for the ticker symbol let's just start with Google as the ticker symbol I want to start with so all we are going to ask for this is to simply say hey you run this little code for me giving back a result when I'm when it's done but this is going to be a very regular sequential call as you would expect nothing really exciting about it but I want to turn this into an asynchronous call how do we really do that that's the question so for that what I'm going to do here is we are going to ask it to provide the value so I'm going to simply say over here execute this code and when you're done with the simply give me a read text from it and return a text value from the response whatever the price is that I'm going to return back from the skull but this is a sequential call as we know but then what I want to do is what if potentially things were to go wrong we typically need to deal with exceptions as well so let's take this a little further keep that away we'll come back to this I have another function I'll call it as IP address so let's call it as get caller IP for lack of better words and and what this method is going to do is to return to us similarly we'll say return java.net dot URL and and what I'm gonna do here is ask for again we'll do a read text on it but I'll ask for a URL to tell me what IP address I'm making the call from that's gonna make a request to a remote server obviously in this case and I'm gonna just try that out real quick to see if that's working so caller IP we'll just go ahead and run that call and and hopefully that comes back eventually and tells us that's my IP address okay fair enough but what I want to do is to take a problem a little bit further and I want to say you know get the stock price and if successful get the IP so this kind of poses a little bit of a problem here it's possible that it did not succeed why wouldn't it sexy for a number of reasons I may not have connection to the service I may have an invalid ticker symbol a lot of things can fall apart so in other words we have to start dealing with exceptions so I'll go ahead and try this this way so we'll say try and we will say value price is equal to get stock price for Google will actually say ticker right here and we will start with a little thicker so ticker is equal to Google and and then of course I'm gonna say give me the price but what if that did not work so I'll say catch exception and in this case we'll say exception and and then we will you know maybe report the exception so we'll simply say you know error getting a price let's say getting price for maybe thicker so that's a very first step and if it works through we'll get the price otherwise we'll report that we we got into an error but what if we were able to get the price if you got the price then I want to say over here try and we will say IP is equal to get let's say call our IP and then I can print out we can say price for a thicker earth and I'm gonna report the price which is going to be the price and then we could say you know request from and then we would report the IP but what if things don't go as planned we could say catch exception and this is going to become an exception again and in this case of course what want to do is to simply report back saying friend let's say error getting a IP so if you notice this this is a traditional imperative style code but what is more important to keep in mind as the multiple exceptions and multiple levels of exception we have to deal with if the stock price fails we don't want to get the IP if the stock price exceeds but if the IP fails we want to report the two and if both of them succeeded we want to report the price and the ticker this is obviously a sequential code but it is going and calling two different services to make this call and of course the response eventually comes back with whatever the price was the question is how do we turn this into an asynchronous call how do we make this non-blocking so we don't have to just block and wait on each one of these calls well that's the part we're going to look at next so to see how this is going to work first of all let's go ahead and do something a little different let's go ahead and call a launch right here and and this launch is going to fire off that request so that the UI thread are whatever the main thread doesn't have to block and wait on this so typically in a UI application you don't have to do this because the application is alive and running it's going to be processing the request from the request thread whereas this is just a simple main program I'm running this is not going to wait for us to finish so I'm gonna put a little thread dot sleep on this just to keep it afloat let's say for a little bit so so this is going to launch off the request and that's going to run in a completely different thread and just to illustrate this point we'll just go ahead and print out here request let's say sent so so when I run this code the request is going to be sent off and then of course that call is going to happen and then it's going to come back with the response but when you look at the code within the launch itself what's gonna happen here is of course I need to bring in the reference to the import and and in this case of course when within the launch when we are making the call the call is gonna get blocked and wait on that within that thread but what if I really want to relieve that so this is where the real fun is if you go back to this you can say suspend and you can specify a little suspend on it so what does the suspend do this is where I want to say this is a very hygienic way of doing things there is it's almost too seamless but I don't want things to become so seamless that you don't know what's happening so the suspend over here gives you a clue that when you make a call to this function you're going to pretty much take this call and you're going to roll the rest of the code into a continuation and say you go off and execute this this code when the result comes back execute the rest of the code that's below this so this is a completely transform code thanks to this suspend similarly I can come in here and say suspend over here and as a result this call becomes a non-blocking call but the rest of the things are going to be executed in the context of co-routine now let's go ahead and run this first and then we'll come back and see how this actually is different in just a few minutes so when I run this code of course it's gonna go off and get the request we don't see much difference at all but what is the real difference to understand the real difference let's try something else a little differently you can try to run and see the threads of execution and all that but usually that's really hard to predict but let's look at this from a slightly different point of view let's just grab this function real quick let's analyze and take a look at something a little different so here on the command prompt I'm gonna try a few things don't have anything here in this directory right now we'll just go ahead and create a little you know Cartland file right now and and I'm gonna stay over here it's actually put this into a class for a minute so let's say class let's call this a sample and within the sample class I want to go ahead and copy those two functions just for a minute let's try this so let's go ahead and say Kotlin c and compile the this particular you know let's try this game Cartland c and compile this code really quick okay so it's Cortland alright so why is that not in the path okay let's try this again so alright so that's better it looks like I changed the path and don't do anything before the demo okay try this again so so let's try this Carlin Carlin see and then compiled this code again really okay so let's try this one more time alright there we go so so this time of course I'm gonna compile this one more time and and this produces the bytecode I want to say Java PE and I've already configured Java P to give me a minus C option let's take a look at the class file real quick what I really want to focus on right now is just this part for you so just look at this one-liner for a minute so it's very obvious what we are seeing here get stock prices the function we have a string value coming in it's returning a string I took so much effort and so many errors to prove the obvious to you that the get stock price is a function that takes a string returns a string no big deal right okay let's try something a little different let's go back to this you know function a class one more time but I'm gonna say suspend over here and I'm gonna mark this one as a suspend also so with doing this what did we achieve at this point by making those two as suspend let's go ahead and run Cartland see one more time let's go ahead and run a Java P one more time but this time the result is pretty significant if you notice this time though good new stock price is still taking a string however notice that it has actually a second argument in the code this is what I was talking about earlier as being extremely hygienic if you notice this function is no longer returning a string the function is taking not one argument but two arguments the first argument being a string and the second one being a continuation that it is actually taking house earlier saying this whole thing is based on continuations and this is one of the reasons to really see how this is actually working behind the scenes is that the get price method in fact what's really interesting about this is notice you didn't call this area differently but what the compiler does for you is internally when it makes the call it passes the continuation as a second argument without you having to do this so so the compiler does a lot of work for you in this case where it recognizes that the function is a space basis is a suspend function so to know that this is a suspend it is going to then pass the continuation as a second argument and all that is done for you automatically for you behind the scenes and as a result you can see in this case that when you make this call you are going to take the rest of the code and wrap it as a continuation and then pass it on to here for execution so that is an example of how that that call can execute in a thread independent of this so you don't have to block and wait on it so going back to this example what what's happening at this point is this is launching a separate thread of execution so this becomes non-blocking and imagine you are in a UI thread you can just you know fire off and say go do this for me I don't want to wait on this execution to finish when you come into this execution in the same way when you come in here your thread of execution sense of a request because we marked it as suspend this says I don't want to wait for this to execute and finish and go ahead and fire this off and when you are done executing at that point continue evaluating the rest of the code that's wrapped around as a continuation now why is this pretty exciting part of the reason this is exciting for me is notice how the code is going to look like right now in this particular context if you look at the code we had a minute ago what did we have well first of all we didn't have the launch so we didn't have a suspend and we didn't have this suspend right in here but then we did not have this launch over here and an either we did we have this part but rest of the code is pretty much the same that you saw here if you will so when it running this code this is the sequential code without any suspend without any continuations and you can see the code is producing the result but notice that changes I'm going to make right now I'm going to say this is suspend right here and similarly I'm gonna mark this a suspend right here so that's the two changes we made the next change we made here is to say a launch over here and and of course we are setting it off the run in a separate thread at this point and then we closed it off right here but if you really notice the chord structure was pretty much intact which is which is what I want to really drive to words so notice how the structure of functional sequential code is the same as the structure of you know parallel code with co-routines what we get really on our hand is that the structure of imperative style synchronous code is the same as the structure of asynchronous code as well so this is a huge benefit we get because if the code structure is extremely different then it becomes the impedance mismatch we have to spend way too much effort trying to maintain the code you write the code sequential e you got it working you debugged it it's easy to understand it's easier to work with then you realize you want to make it asynchronous you don't have to go and change the code structure and turn it into a monster you can pretty much keep the same code structure and move forward and this is one of the biggest benefits you get out of this is the structure of the synchronous code is the same as structure of a synchronous code when it comes to core routines and and that is a huge benefit now of course the reason we do this is for responsiveness I mentioned earlier so you're able to get a better responsiveness because you're saying I want this code to you know just give me the ability to respond to events while that goes off and execute it but what if I really want to get a performance out of this how do I really do that well you can also run the code asynchronously as well so don't understand this let's take a slightly different example here let's get rid of the these these values let's say for a minute I'm gonna write another function and and this function is going to be called measure let's say measure time so this is gonna just tell me how much time I'm taking to do some work so I'm gonna say block and in this case we will say this doesn't return anything for us I'll say start is equal to system dot nano time and then let's go ahead and say end is equal to system dot nano time and and what I want to do here is to call the block of code right in between so we can measure the time it takes and we'll just print out right here how about this n minus a start one point let's say Oh II 9 and then we want to say that's how many seconds we are taking to execute this so we'll simply say seconds so so that's gonna tell us how many seconds we are taking to run this little piece of code and and of course that's really what we want to use we got to do a few things to make this asynchronous but we'll come back and worry about this a little bit later so so now that we have this code what do I want to do I want to say it occurs is equal to list off let's go ahead and create a few of them let's say we have Google we have a few other thing in in listed here so I want to go back and get prices for all these different stocks how much time is it gonna take or what is the performance I'm gonna get out of this so measure time and in this case we will go ahead and say far and let's make it actually very imperative and traditional if you will so let's go ahead and say this is going to be priceless is equal to a beautiful list of string and I want to just create a mutable list of string values let's say that's all I'm going to create right now and we'll just go ahead and print out the prices we'll take baby steps and get to this and and see how this is going to work in just a minute so that's taking about you know 4 seconds well what four point minus 4 seconds obviously we're not doing any work shouldn't take much time but what do I want to do I'm gonna say price in this case we'll go ahead and say ticker for let's rather price so ticker in tickers and I want to get the price for each of the tickers so prices plus equal to and I want to say over here get stock price for the given ticker once I get all the prices will then say for price in prices and then I'm going to simply loop through this and print out what do I want to say in here I want to just print out the price we got back right that's again a very traditional for loop for getting the work done so so let's go ahead and remove the suspend for a minute we'll come back to that later so so execute it as you can see didn't like me putting the suspend welcome back to that a little bit later so when we run this code you can see that that's going to produce the result for us this is price not prices so we can see it's well actually let's do this a little differently let's go back to this code and say in here after it finishes let's go ahead and say this is going to become a price for ticker s and then we'll just print out the price for it there we go so so that should tell us the price for each of the tickers that we get back well okay so this is sequential we know this and how much time is it going to take to execute well it's going to take you know as many seconds as it wants if each of them take about a second that's going to be a little bit more than three seconds of execution and let's see if that actually reports it back to us so there you go it's about three seconds how do I make this asynchronous how do I make this you know maybe run asynchronously but get the results back at the same time so one of the things you could actually do is obviously I want to run this asynchronously I don't want my trick to block on this so we could against a thread sleeve to just keep it waiting in the because it's a main function well go ahead and do a launch on this one so we'll say launch and once we launch this will measure the time after we launch this as well right now you're not going to see many much performance difference but we'll take baby steps to get towards so when I run this code back thread is going to put it off the main is gonna finish and wait but in this case that other thread is going to still do it sequentially and no no surprise there to still took three seconds but what I can do though is I can come back to this code and say I can do a sync on this and when I do a sync on it I'm singing go ahead and evaluate this part asynchronously for me when I do this a synchronously what is this going to return it is going to return a deferred object so this is going to say I'm gonna run the execution but I'll come back to you with the result later on so that becomes a deferred string in this in this particular example so so I'm gonna take that as a deferred string and and I'm not gonna change this right now we'll change it eventually so when I run this you're not gonna get the results you want but nevertheless it illustrates the point so when you look at the output you notice that all these prices are actually going to be the deferred co-routine values so but notice the time it took the time it took is a lot less that's because it didn't wait for the results to come so that's why it's that low not a very fair comparison but what I want to do here is I want to wait for the result so in this case you can say I want to go ahead and execute this object this is this particular Co routine but when I finish it I want to wait for the results to come back so you have launched off a bunch of requests on the side and then you are saying when the results come back wait for them and report them this code won't work right now we'll see why in just a few minutes one of the best ways to do that is to just try to run it and see what error it gives us whenever I run does it says suspension function can only be used within a quarantine party well clearly that says you can't really call a wait over here and the reason is you are not in a in a function in a co-routine that'll I love you to suspend you mean look at this and say gosh what does that mean may mean because I'm after all in launched and that's a core routine block of code isn't it well it turns out that the real block of code we are in is this lambda right here but that lambda is not a core routine and because this lambda is not a core routine a suspend function it doesn't want you to do that so notice what I'm gonna do here I'm gonna make this a suspend because I don't want to you know do that in the in the main thread and block on it but then I'm gonna also mark this lambda parameter as a suspend as well so then it tells us that this particular lambda itself can run in a suspend mode so you can just go off and you know don't have to block and wait on it so we mark those two as suspend we don't care to make this one as suspend we could if you want to but in this case we don't really have to because we use the asynchronous over here so when I run this code this time around what what it gave us is the following when you run this code it gives us the else we are expecting but also notice it only took about one second and not three seconds where are we going with this where we are going with this this let me let me do this this way let me just go ahead and copy that let's go blow away everything we'll just go ahead and say co2 for a minute and co2 is the is the synchronous sorry that asynchronous version we've wrote let me fall back on the code we wrote a few minutes ago and just fall back to the synchronous version that we had a minute ago so back up to here I think that's good enough let's go ahead and run this code real quick and this takes about three seconds of execution for it to work on so yeah there we go let's go ahead and copy that as a code one for a minute so this is the code without synchrony so let's go ahead and just take a look at the difference between these two code just to see what what difference we are seeing here well if you notice over here the differences we see are the following let me see if I can zoom into this a little bit so you notice the first difference here is we put the suspend on this side and there was no suspend on this one that's the difference the second difference is just a type over here the third difference is the a sink over here versus no async on this side and then of course we call a weight on this one with noah weight on this side well essentially here is the difference between this the sequential version and the asynchronous version right the synchronous rather and the asynchronous and this goes back to the point I made earlier in that the structure of the synchronous code is the same as a structure of a synchronous code and you're able to keep them very consistent and and what I really like about this is it is almost seamless and I really want the word almost is important in my opinion if it is way too seamless where you don't see the difference at all it trips us up as programmers you want to know there's a difference but you don't want to work too hard for the difference and and so the seam is very very small here so when you look at the code you can see oh this looking at this you're like oh of course this is going to be the code I'm calling but this is a synchronous versus asynchronous and the way you know that is by having these kinds of cues oh that's a suspend function so that tells me that I'm going to you know have this you know called asynchronously and as a result my thread is not going to block on it it's gonna use a KO routine behind the scene and are continuations so that is fairly seamless or almost seamless to the point where you don't have to work too hard for it but more important the structure of the code is the same and on the other hand by looking at it you know that this code is not running sequentially as well so that's a fairly good difference to look at so the summarize what we talked about we talked about the what co-routines provide for us one of the things that I'm more and more convinced today is that moving towards a synchrony in the Java you know JVM we're being predominantly focusing on parallelism but moving forward I think we're gonna be focusing more on asynchronous and co-routines really make it easy to write asynchronous code while preserving the structure of the code between sequential verses are synchronous versus asynchronous it's we are able to preserve the code that removes the impedance mismatch that really gives us the ability to you know keep a sense of what the code is doing and to be able to go from you can you can defer your decision that's one of the biggest benefits is a deafening decision you don't have to go towards a synchrony in the beginning you can make it sequential when the need arises you can very easily convert it to a synchrony that's one of the biggest benefits you get if you want to download the code examples have showed you you can download it from that URL on the downloads page hope that was useful thank you [Applause]
Info
Channel: JetBrainsTV
Views: 73,819
Rating: undefined out of 5
Keywords: Venkat Subramariam, JetBrains, Kotlin, KotlinConf18, KotlinConf, KotlinConf2018, Amsterdam, Coroutines, programming
Id: jT2gHPQ4Z1Q
Channel Id: undefined
Length: 44min 11sec (2651 seconds)
Published: Mon Oct 08 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.