1 00:00:05,239 --> 00:00:07,259 [music] 2 00:00:09,825 --> 00:00:11,845 [music] 3 00:00:15,040 --> 00:00:19,880 Can I get a warm welcome for Peter? 4 00:00:20,305 --> 00:00:22,325 [applause] 5 00:00:26,960 --> 00:00:28,820 Thank you. Thank you very much. Um, 6 00:00:28,820 --> 00:00:29,439 [snorts] 7 00:00:29,439 --> 00:00:30,960 I was going to write this talk, but then 8 00:00:30,960 --> 00:00:35,600 I uh I didn't get around to it. Sorry. 9 00:00:35,600 --> 00:00:38,879 That was a joke. 10 00:00:38,879 --> 00:00:40,640 For those that don't know me, my name is 11 00:00:40,640 --> 00:00:42,559 Peter. Peter love it. I have been a 12 00:00:42,559 --> 00:00:44,399 programmer for longer than most of you 13 00:00:44,399 --> 00:00:47,280 have been alive. 14 00:00:47,280 --> 00:00:49,520 Um, I run uh computer programming 15 00:00:49,520 --> 00:00:51,920 language training courses uh in Python, 16 00:00:51,920 --> 00:00:55,039 of course, um, and also C++, hence the 17 00:00:55,039 --> 00:00:57,760 name of my company. And I've been doing 18 00:00:57,760 --> 00:01:01,120 that for a long time. The outline for 19 00:01:01,120 --> 00:01:03,520 the talk today will be in three parts. 20 00:01:03,520 --> 00:01:05,519 Firstly, looking at being a lazy 21 00:01:05,519 --> 00:01:07,680 programmer. 22 00:01:07,680 --> 00:01:10,640 Secondly, lazy evaluation. 23 00:01:10,640 --> 00:01:12,479 But about half of the talk is going to 24 00:01:12,479 --> 00:01:15,600 be on the new 3.15 25 00:01:15,600 --> 00:01:18,720 new keyword, the lazy keyword. Of 26 00:01:18,720 --> 00:01:20,560 course, I think that I'm a very brave 27 00:01:20,560 --> 00:01:22,080 person 28 00:01:22,080 --> 00:01:24,080 because I'm going to be doing live demo 29 00:01:24,080 --> 00:01:27,920 with pre-release software. 30 00:01:29,360 --> 00:01:33,680 Let's start on being a lazy programmer. 31 00:01:33,680 --> 00:01:36,159 According to Larry Wall, anyone familiar 32 00:01:36,159 --> 00:01:38,400 with Larry Wall? Oh, good. Lots of you. 33 00:01:38,400 --> 00:01:40,000 For those that aren't, Larry Wall is 34 00:01:40,000 --> 00:01:42,000 quite a famous programmer, he wrote the 35 00:01:42,000 --> 00:01:44,000 Pearl programming language. If you're 36 00:01:44,000 --> 00:01:46,159 not familiar with Pearl, it um at one 37 00:01:46,159 --> 00:01:48,240 stage was known as the duct tape of the 38 00:01:48,240 --> 00:01:51,600 internet and um uh was is a crucial 39 00:01:51,600 --> 00:01:54,880 language. and uh he came up with the 40 00:01:54,880 --> 00:01:57,280 three great virtues of a programmer. 41 00:01:57,280 --> 00:01:59,439 Although in my head it goes the three 42 00:01:59,439 --> 00:02:01,920 virtues of a great programmer. They 43 00:02:01,920 --> 00:02:04,799 being number one 44 00:02:04,799 --> 00:02:06,560 laziness, 45 00:02:06,560 --> 00:02:09,599 number two, impatience 46 00:02:09,599 --> 00:02:13,520 and number three hubris or pride in your 47 00:02:13,520 --> 00:02:18,319 work. Let's focus on laziness. 48 00:02:18,319 --> 00:02:20,400 Lazy Oh, there was a link to that. 49 00:02:20,400 --> 00:02:22,560 Laziness makes you write laborsaving 50 00:02:22,560 --> 00:02:24,160 programs that other people will find 51 00:02:24,160 --> 00:02:25,920 useful. 52 00:02:25,920 --> 00:02:28,640 Part one. Part two, document what you 53 00:02:28,640 --> 00:02:30,400 wrote so you don't have to answer so 54 00:02:30,400 --> 00:02:34,480 many in my mind bracket stupid questions 55 00:02:34,480 --> 00:02:37,680 about it. Um, this isn't a talk about 56 00:02:37,680 --> 00:02:41,040 AI, but I would make a mention about AI 57 00:02:41,040 --> 00:02:42,239 is not going to help you with the first 58 00:02:42,239 --> 00:02:44,080 part. [laughter] 59 00:02:44,080 --> 00:02:47,920 That's why we still need programmers. 60 00:02:47,920 --> 00:02:50,319 So, I'm going to do an exercise here, a 61 00:02:50,319 --> 00:02:52,560 live thing where I'm going to break the 62 00:02:52,560 --> 00:02:55,040 uh the the the group up into two. We'll 63 00:02:55,040 --> 00:02:57,120 have the lefthand side and we'll have 64 00:02:57,120 --> 00:02:58,879 the right hand side and we'll see who's 65 00:02:58,879 --> 00:03:02,319 better. The um I'm going to show you uh 66 00:03:02,319 --> 00:03:04,000 the left hand side and then the right 67 00:03:04,000 --> 00:03:06,560 hand side, a small snippet of code and 68 00:03:06,560 --> 00:03:08,480 I'm going to show it to you for about 69 00:03:08,480 --> 00:03:12,080 one to one and a half seconds. 70 00:03:12,080 --> 00:03:14,319 And uh it's going to be similar but not 71 00:03:14,319 --> 00:03:16,959 identical code. and I'm going to see 72 00:03:16,959 --> 00:03:19,519 which of the two sides can get the 73 00:03:19,519 --> 00:03:22,480 answer for what this code actually does. 74 00:03:22,480 --> 00:03:25,280 Who's going to get it quickest? 75 00:03:25,280 --> 00:03:27,440 When you've got it, don't say it out. 76 00:03:27,440 --> 00:03:29,840 Let the uh let the other side see if 77 00:03:29,840 --> 00:03:35,560 they can get it. So, are you ready? 78 00:03:36,959 --> 00:03:38,879 H the right hand side seems to know that 79 00:03:38,879 --> 00:03:40,480 they're going to be the ones that win. 80 00:03:40,480 --> 00:03:42,239 But [laughter] 81 00:03:42,239 --> 00:03:44,400 let's try it. Left hand side, are you 82 00:03:44,400 --> 00:03:47,360 ready? 83 00:03:48,597 --> 00:03:50,560 [laughter] 84 00:03:50,560 --> 00:03:52,720 How'd you go? Don't Don't say it out 85 00:03:52,720 --> 00:03:54,560 because uh let's try the right hand 86 00:03:54,560 --> 00:03:57,112 side. Are you ready? Right hand side. 87 00:03:57,112 --> 00:03:58,080 [cheering] 88 00:03:58,080 --> 00:04:01,879 They know they're going to win. 89 00:04:04,080 --> 00:04:08,680 Let's have a look at how that was. 90 00:04:09,439 --> 00:04:11,760 As a trainer, I run training courses and 91 00:04:11,760 --> 00:04:14,000 people say, "We want self-documenting 92 00:04:14,000 --> 00:04:16,560 code. we don't need comments. I'm like, 93 00:04:16,560 --> 00:04:18,799 yeah, nah. 94 00:04:18,799 --> 00:04:21,919 Yeah, comments still have a place. And 95 00:04:21,919 --> 00:04:24,479 um I think you will all agree, even the 96 00:04:24,479 --> 00:04:27,440 left-hand side people will agree that um 97 00:04:27,440 --> 00:04:30,320 a comment there makes a big difference. 98 00:04:30,320 --> 00:04:34,080 Now um one thing about comments 99 00:04:34,080 --> 00:04:36,720 is Pepe makes a very strong point and I 100 00:04:36,720 --> 00:04:38,960 like it that inline comments are 101 00:04:38,960 --> 00:04:41,600 unnecessary and in fact distracting if 102 00:04:41,600 --> 00:04:43,840 they state the obvious. If you're doing 103 00:04:43,840 --> 00:04:45,600 an x gets x plus one and I don't know 104 00:04:45,600 --> 00:04:48,960 why pep 8 doesn't have plus equals 1 but 105 00:04:48,960 --> 00:04:51,840 uh that will increment x. We know I want 106 00:04:51,840 --> 00:04:55,040 to know why. I want the summary. I want 107 00:04:55,040 --> 00:04:57,520 a I want a oneliner. 108 00:04:57,520 --> 00:05:00,800 So I threw this into AI. Can you please 109 00:05:00,800 --> 00:05:03,919 comment this code? 110 00:05:03,919 --> 00:05:06,720 And to be honest, this is a great 111 00:05:06,720 --> 00:05:10,080 comment in a training context or in a 112 00:05:10,080 --> 00:05:13,039 detail context, but it's um and to be 113 00:05:13,039 --> 00:05:14,880 honest, it's pretty much how I would 114 00:05:14,880 --> 00:05:17,039 write a comment if I was deeply 115 00:05:17,039 --> 00:05:21,440 commenting that particular reject 116 00:05:21,440 --> 00:05:22,960 um 117 00:05:22,960 --> 00:05:25,280 intentionally complicated. So I asked 118 00:05:25,280 --> 00:05:28,160 AI, please uh summarize that, make it a 119 00:05:28,160 --> 00:05:32,160 oneliner. and for some reason it 120 00:05:32,160 --> 00:05:35,680 realized it was a date and gave me an XY 121 00:05:35,680 --> 00:05:38,320 Z. 122 00:05:38,320 --> 00:05:43,120 So, thank you AI. But um so to be clear, 123 00:05:43,120 --> 00:05:45,759 I do use AI. AI has a lot of value, but 124 00:05:45,759 --> 00:05:50,000 I also like um poking fun at AI, 125 00:05:50,000 --> 00:05:52,560 like asking um any African countries 126 00:05:52,560 --> 00:05:54,320 that begin with K. And as most of you 127 00:05:54,320 --> 00:05:56,080 know, the closest is Kenya, which starts 128 00:05:56,080 --> 00:05:58,880 with a K, but is actually spelled with a 129 00:05:58,880 --> 00:06:01,039 K. 130 00:06:01,039 --> 00:06:04,080 Or I could ask it for uh the ancient 131 00:06:04,080 --> 00:06:08,169 Greek merchant cargo ship. [snorts] 132 00:06:08,639 --> 00:06:11,120 Well, the one that I love, 133 00:06:11,120 --> 00:06:15,880 what sound does a fox make? 134 00:06:17,939 --> 00:06:19,520 [laughter] It's just that's just 135 00:06:19,520 --> 00:06:21,039 beautiful. 136 00:06:21,039 --> 00:06:23,360 I could I I feel like just doing a 137 00:06:23,360 --> 00:06:27,039 25minut talk just on AI fails because I 138 00:06:27,039 --> 00:06:29,919 also love that one. [laughter] 139 00:06:29,919 --> 00:06:32,880 I need me a laptop like that. 140 00:06:32,880 --> 00:06:38,400 Um and uh of course watch out for AI 141 00:06:38,400 --> 00:06:41,840 inside a spreadsheet. 142 00:06:41,840 --> 00:06:43,600 And I love how if you change the 143 00:06:43,600 --> 00:06:46,000 question from sum the numbers above to 144 00:06:46,000 --> 00:06:49,280 sum all the numbers above, you get a 145 00:06:49,280 --> 00:06:52,800 completely different answer. Um AI, 146 00:06:52,800 --> 00:06:54,880 again, this isn't an AI talk, but I kind 147 00:06:54,880 --> 00:06:56,319 of sort of have to talk about it a 148 00:06:56,319 --> 00:06:58,160 little bit. If you haven't come across 149 00:06:58,160 --> 00:07:01,280 the meta study, um this is one that you 150 00:07:01,280 --> 00:07:04,960 really need to be exposed to. First up, 151 00:07:04,960 --> 00:07:07,280 um it is an old study. It's from last 152 00:07:07,280 --> 00:07:11,039 year. And uh I like the way that um a 153 00:07:11,039 --> 00:07:13,280 programmer Steve Gibson of Gibson 154 00:07:13,280 --> 00:07:14,960 Research Corporation, some of you might 155 00:07:14,960 --> 00:07:17,039 know him, doesn't talk about AI, he 156 00:07:17,039 --> 00:07:19,520 talks about today's AI. [snorts] So 157 00:07:19,520 --> 00:07:22,319 whenever I say AI, I mean today's AI 158 00:07:22,319 --> 00:07:24,400 because next week, next month, next 159 00:07:24,400 --> 00:07:26,400 year, it's all going to be different. 160 00:07:26,400 --> 00:07:30,319 The meta study actually looked at um 161 00:07:30,319 --> 00:07:33,199 programmers using AI for code solving 162 00:07:33,199 --> 00:07:36,720 and these were real life problems and 163 00:07:36,720 --> 00:07:39,680 measuring the perceptional difference 164 00:07:39,680 --> 00:07:41,440 between 165 00:07:41,440 --> 00:07:44,240 how much faster I think it made me and 166 00:07:44,240 --> 00:07:46,880 how much faster it actually made me. And 167 00:07:46,880 --> 00:07:49,759 there's a big disparity between how much 168 00:07:49,759 --> 00:07:51,680 the people thought they were how much 169 00:07:51,680 --> 00:07:53,520 the programmers thought they were going 170 00:07:53,520 --> 00:07:56,160 faster and how much they uh were 171 00:07:56,160 --> 00:07:58,000 actually slower. 172 00:07:58,000 --> 00:08:01,919 So um it is a study that should be taken 173 00:08:01,919 --> 00:08:03,919 with not [snorts] a grain of salt but 174 00:08:03,919 --> 00:08:07,199 with caution because it's um measuring a 175 00:08:07,199 --> 00:08:09,759 perceptional difference. But um if 176 00:08:09,759 --> 00:08:11,199 you're not familiar with that study, I'd 177 00:08:11,199 --> 00:08:14,879 recommend looking that up afterwards. 178 00:08:14,879 --> 00:08:17,520 too long, didn't listen. Document your 179 00:08:17,520 --> 00:08:22,160 work for your own sake. And I'm all for 180 00:08:22,160 --> 00:08:23,520 if I'm going to be lazy, I'm going to 181 00:08:23,520 --> 00:08:26,240 use AI, but I'm going to use it 182 00:08:26,240 --> 00:08:29,039 carefully. 183 00:08:29,039 --> 00:08:32,479 That's part one. 184 00:08:32,479 --> 00:08:37,399 Part two, lazy evaluation. 185 00:08:38,880 --> 00:08:41,839 Lazy evaluation. For those of you that 186 00:08:41,839 --> 00:08:43,680 are familiar with Python 2, who are my 187 00:08:43,680 --> 00:08:46,000 Python 2 users? First started using 188 00:08:46,000 --> 00:08:49,920 Python in the Python 2 era. Good. Good. 189 00:08:49,920 --> 00:08:52,080 You'll remember that range gave you a 190 00:08:52,080 --> 00:08:55,080 list. 191 00:08:55,440 --> 00:08:58,000 And one of the big shifts in Python 3 192 00:08:58,000 --> 00:09:00,880 was not that print got PNS. 193 00:09:00,880 --> 00:09:02,959 That was a big shift. The biggest shift 194 00:09:02,959 --> 00:09:05,200 most people don't realize was the um the 195 00:09:05,200 --> 00:09:06,959 shift from text to uniode. And that's 196 00:09:06,959 --> 00:09:09,680 the bit that created the biggest drama. 197 00:09:09,680 --> 00:09:12,560 But there was also a big shift in lazy 198 00:09:12,560 --> 00:09:15,760 evaluation so that in Python 3 when you 199 00:09:15,760 --> 00:09:18,160 ask for a range it gives you a range 200 00:09:18,160 --> 00:09:20,480 object. 201 00:09:20,480 --> 00:09:24,279 Time for a live demo. 202 00:09:25,120 --> 00:09:30,240 So in Python 2 and Python this is 314 203 00:09:30,240 --> 00:09:33,120 which is um up to date. So here if I ask 204 00:09:33,120 --> 00:09:36,959 for a range of a range of 10 numbers I 205 00:09:36,959 --> 00:09:39,760 get a list 206 00:09:39,760 --> 00:09:44,480 and in Python 3 3 point anything color 207 00:09:44,480 --> 00:09:49,440 ooh I get a range object from zero up to 208 00:09:49,440 --> 00:09:53,040 but not including 10. Now this has to 209 00:09:53,040 --> 00:09:58,640 build the list. So if I built a list of 210 00:09:58,640 --> 00:10:02,000 actually I might not do that 211 00:10:02,000 --> 00:10:03,839 but if I did something like I'm going to 212 00:10:03,839 --> 00:10:07,440 iterate through that list for each I ps 213 00:10:07,440 --> 00:10:10,880 in my brain four always says for each 214 00:10:10,880 --> 00:10:13,680 I'm a pearl programmer 215 00:10:13,680 --> 00:10:19,839 for each I in a range oops not capitals 216 00:10:19,839 --> 00:10:23,040 from uh one one two three one two three 217 00:10:23,040 --> 00:10:25,600 maybe another 218 00:10:25,839 --> 00:10:29,839 And uh it didn't indent for me. If I is 219 00:10:29,839 --> 00:10:33,360 greater than three. 220 00:10:33,360 --> 00:10:36,360 Oops, 221 00:10:36,480 --> 00:10:39,600 then break. 222 00:10:39,600 --> 00:10:42,000 And when that runs, 223 00:10:42,000 --> 00:10:43,600 went too quickly. Let's try another 224 00:10:43,600 --> 00:10:46,560 bigger Let's try a bigger one. 225 00:10:46,560 --> 00:10:51,360 for each I um break 226 00:10:51,360 --> 00:10:54,480 it has to build that list 227 00:10:54,480 --> 00:10:57,279 and that took too long. Whereas in 228 00:10:57,279 --> 00:11:01,040 Python 3 anything for each I in range of 229 00:11:01,040 --> 00:11:03,120 numbers one I don't know pick anything 230 00:11:03,120 --> 00:11:05,920 doesn't matter integers how big an 231 00:11:05,920 --> 00:11:08,959 integer can you have 232 00:11:08,959 --> 00:11:12,037 arbitrary how much RAM have you got 233 00:11:12,037 --> 00:11:14,720 [snorts] it indents for me thank you and 234 00:11:14,720 --> 00:11:17,920 if I is greater than three it indents 235 00:11:17,920 --> 00:11:20,560 for me thank you then that will always 236 00:11:20,560 --> 00:11:24,160 be instant yay 237 00:11:24,160 --> 00:11:29,240 that's Whoops lazy evaluation. 238 00:11:29,279 --> 00:11:31,760 And uh there is actually a nice little 239 00:11:31,760 --> 00:11:34,000 trick there that happens with in as 240 00:11:34,000 --> 00:11:36,800 well. Uh in is special case for the 241 00:11:36,800 --> 00:11:38,800 range object. So it doesn't matter what 242 00:11:38,800 --> 00:11:41,600 you do. Uh [snorts] side note. Oh, I 243 00:11:41,600 --> 00:11:43,120 just noticed a typo. We didn't get 244 00:11:43,120 --> 00:11:47,120 underscores in Python 2. 245 00:11:47,120 --> 00:11:49,040 PSC got a big number. Put an underscore 246 00:11:49,040 --> 00:11:50,959 in it. 247 00:11:50,959 --> 00:11:53,600 Um so lazy valuation that was a big 248 00:11:53,600 --> 00:11:56,160 shift in two to three and it affected 249 00:11:56,160 --> 00:11:58,480 lots of the method lots of the built-in 250 00:11:58,480 --> 00:12:01,839 functions including range zip filter map 251 00:12:01,839 --> 00:12:05,120 etc etc etc and one of the big benefits 252 00:12:05,120 --> 00:12:08,000 is that it gave us quicker startup it 253 00:12:08,000 --> 00:12:10,160 was all about that startup speed and 254 00:12:10,160 --> 00:12:14,918 also affected the memory overhead 255 00:12:14,918 --> 00:12:17,279 [snorts] um or you could make your own 256 00:12:17,279 --> 00:12:19,440 and uh I'm not going to go into detail 257 00:12:19,440 --> 00:12:21,680 on yield. Uh that's been covered in 258 00:12:21,680 --> 00:12:26,000 detail over um a long time, but uh I 259 00:12:26,000 --> 00:12:28,560 could have a a generator there that uh 260 00:12:28,560 --> 00:12:31,440 is an infinite generator. PS, it would 261 00:12:31,440 --> 00:12:33,680 be easier to use it tools for that. It 262 00:12:33,680 --> 00:12:36,800 tools repeat would be nice. 263 00:12:36,800 --> 00:12:39,200 That's 264 00:12:39,200 --> 00:12:40,800 that 265 00:12:40,800 --> 00:12:44,600 that's lazy evaluation. 266 00:12:44,720 --> 00:12:50,279 Which brings us to lazy imports. 267 00:12:50,720 --> 00:12:53,920 So this has one specific use case. We're 268 00:12:53,920 --> 00:12:57,360 looking at the startup latency. How long 269 00:12:57,360 --> 00:13:00,240 it takes things to start. 270 00:13:00,240 --> 00:13:02,880 So let me give you a use case. This is 271 00:13:02,880 --> 00:13:07,680 my starting code. I'm using pandas 272 00:13:07,680 --> 00:13:09,920 and um I've got some command line 273 00:13:09,920 --> 00:13:13,519 processing. So uh if that's help, 274 00:13:13,519 --> 00:13:16,720 it does something and exits. Side note, 275 00:13:16,720 --> 00:13:18,079 I don't know if a lot of people don't 276 00:13:18,079 --> 00:13:19,920 know this, you should be using cisexit, 277 00:13:19,920 --> 00:13:22,000 not exit. Exit is for interactive use. 278 00:13:22,000 --> 00:13:25,600 CIS exit for use within a program. Um, 279 00:13:25,600 --> 00:13:28,240 if it's a help or something, then go and 280 00:13:28,240 --> 00:13:32,079 do something. And I'm not using pandas. 281 00:13:32,079 --> 00:13:35,120 Now, um, for those that were in, um, 282 00:13:35,120 --> 00:13:38,880 Alyssa's talk 2 days ago, 283 00:13:38,880 --> 00:13:42,320 she gave a, uh, very nice example of a, 284 00:13:42,320 --> 00:13:44,959 uh, a switch that some people don't know 285 00:13:44,959 --> 00:13:49,440 about, which is my friend 286 00:13:49,440 --> 00:13:52,560 Tac X. X for the extras. If you're not 287 00:13:52,560 --> 00:13:54,880 familiar with X, this is a C Python 288 00:13:54,880 --> 00:13:57,920 specific feature that may or may not 289 00:13:57,920 --> 00:13:59,440 stay. 290 00:13:59,440 --> 00:14:02,160 experimental extras 291 00:14:02,160 --> 00:14:04,480 for import time. 292 00:14:04,480 --> 00:14:07,519 I've got a little program there and uh 293 00:14:07,519 --> 00:14:11,040 that goes and import time shows me how 294 00:14:11,040 --> 00:14:13,279 long it takes for things to be imported. 295 00:14:13,279 --> 00:14:16,000 Very useful for your startup process. 296 00:14:16,000 --> 00:14:17,760 Not only does it tell you how much time, 297 00:14:17,760 --> 00:14:19,920 it shows you what's being imported. And 298 00:14:19,920 --> 00:14:21,440 all of my data scientists should be 299 00:14:21,440 --> 00:14:23,299 going pandas 300 00:14:23,299 --> 00:14:24,880 [laughter] 301 00:14:24,880 --> 00:14:28,240 because when you import pandas 302 00:14:28,240 --> 00:14:31,040 you get 303 00:14:31,040 --> 00:14:34,680 you get an error. 304 00:14:35,040 --> 00:14:39,000 Pick the right version. 305 00:14:40,639 --> 00:14:44,920 Try and pick the right version. 306 00:14:46,160 --> 00:14:50,399 Ah sorry. I had hacked my code and 307 00:14:50,399 --> 00:14:52,639 didn't want that. 308 00:14:52,639 --> 00:14:56,360 Let's try that again. 309 00:14:57,680 --> 00:15:00,560 Let's try 310 00:15:00,560 --> 00:15:04,040 saving it. 311 00:15:05,220 --> 00:15:06,079 [laughter] 312 00:15:06,079 --> 00:15:09,120 And that's the modules that pandas goes 313 00:15:09,120 --> 00:15:11,839 and imports. 314 00:15:11,839 --> 00:15:14,880 Now I'm confession. This is a very old 315 00:15:14,880 --> 00:15:17,920 laptop. I inherited it from my son who 316 00:15:17,920 --> 00:15:21,519 made me pay money for it. 317 00:15:21,519 --> 00:15:25,199 So, it's an i7. It's an early i7 and 318 00:15:25,199 --> 00:15:28,079 that took admittedly the printing would 319 00:15:28,079 --> 00:15:29,760 have taken a fair bit of time, but it 320 00:15:29,760 --> 00:15:32,320 took nearly 7 seconds for me to import 321 00:15:32,320 --> 00:15:34,639 pandas. And if I'm not going to be using 322 00:15:34,639 --> 00:15:38,399 pandas, then that was a waste of time. 323 00:15:38,399 --> 00:15:40,320 And if you have a look at what pandas 324 00:15:40,320 --> 00:15:41,839 imports, 325 00:15:41,839 --> 00:15:45,760 you can see that it imports a um am I 326 00:15:45,760 --> 00:15:47,839 allowed to swear 327 00:15:47,839 --> 00:15:49,759 lot [laughter] 328 00:15:49,759 --> 00:15:53,120 a large amount of stuff including numpy 329 00:15:53,120 --> 00:15:56,880 etc. We're familiar with that. So all of 330 00:15:56,880 --> 00:15:59,360 that's to say coming back to the 331 00:15:59,360 --> 00:16:00,880 presentation 332 00:16:00,880 --> 00:16:04,240 is that there is a downside of doing all 333 00:16:04,240 --> 00:16:07,199 my imports but we like doing all our 334 00:16:07,199 --> 00:16:09,680 imports at top at the top but here's uh 335 00:16:09,680 --> 00:16:12,560 here's let's go and explore uh so that 336 00:16:12,560 --> 00:16:14,399 was the performance that's on my 337 00:16:14,399 --> 00:16:17,519 computer and if I use the switch it 338 00:16:17,519 --> 00:16:20,800 takes the same amount of time. 339 00:16:20,800 --> 00:16:22,560 So, let's look at some options for 340 00:16:22,560 --> 00:16:25,839 solving the startup latency issue. 341 00:16:25,839 --> 00:16:28,240 Option one, don't do the import at the 342 00:16:28,240 --> 00:16:31,600 top. Do the import later on when you 343 00:16:31,600 --> 00:16:35,440 need it. Um, that will actually solve my 344 00:16:35,440 --> 00:16:37,920 imports or my startup latency problem, 345 00:16:37,920 --> 00:16:41,279 but is messy. Your code is probably 346 00:16:41,279 --> 00:16:44,480 longer than this sample code. And to 347 00:16:44,480 --> 00:16:46,399 have imports scattered all the way 348 00:16:46,399 --> 00:16:49,839 through it is considered bad style. It's 349 00:16:49,839 --> 00:16:51,920 uh in fact if you're using pilint um 350 00:16:51,920 --> 00:16:54,320 pilint will complain about that saying 351 00:16:54,320 --> 00:16:56,240 you should be doing all of the imports 352 00:16:56,240 --> 00:16:58,639 at the top. 353 00:16:58,639 --> 00:17:00,800 Option two 354 00:17:00,800 --> 00:17:02,720 is that you could do the import in the 355 00:17:02,720 --> 00:17:05,439 middle of a function. Wrap it up into a 356 00:17:05,439 --> 00:17:08,559 function put it where it's needed. Again 357 00:17:08,559 --> 00:17:10,640 um pilint will complain about that. 358 00:17:10,640 --> 00:17:12,640 Again we're going to be scattering the 359 00:17:12,640 --> 00:17:15,199 imports the dependencies throughout the 360 00:17:15,199 --> 00:17:18,720 code and that's not desirable. 361 00:17:18,720 --> 00:17:21,839 So, what's a better solution? 362 00:17:21,839 --> 00:17:23,600 Do that. 363 00:17:23,600 --> 00:17:26,799 Use the new keyword lazy 364 00:17:26,799 --> 00:17:30,240 and uh that will lazily import. It'll 365 00:17:30,240 --> 00:17:32,720 import it when it needs it, but you've 366 00:17:32,720 --> 00:17:35,360 still got it at the top. That's the end 367 00:17:35,360 --> 00:17:37,360 of the end of the talk. I hope you found 368 00:17:37,360 --> 00:17:39,039 that useful. That's really all you need 369 00:17:39,039 --> 00:17:41,840 to know. 370 00:17:41,840 --> 00:17:44,400 And of course then I get a much better 371 00:17:44,400 --> 00:17:47,520 performance because if I use my switch 372 00:17:47,520 --> 00:17:50,400 and it doesn't go and use anything out 373 00:17:50,400 --> 00:17:54,720 of pandas then it won't import pandas. 374 00:17:54,720 --> 00:17:56,720 And then the last thing that was 375 00:17:56,720 --> 00:18:00,160 imported was site. Nice and quick. 376 00:18:00,160 --> 00:18:01,840 Maybe there's a bit more I can tell you 377 00:18:01,840 --> 00:18:03,840 about lazy. 378 00:18:03,840 --> 00:18:05,760 Um if you want to know more um about 379 00:18:05,760 --> 00:18:09,200 this check out Python 810. 380 00:18:09,200 --> 00:18:13,039 Um as mentioned um this is uh a new 381 00:18:13,039 --> 00:18:17,120 feature in 315 in October. We should be 382 00:18:17,120 --> 00:18:19,600 getting it in October. 383 00:18:19,600 --> 00:18:23,440 Um the opposite of the keyword of of of 384 00:18:23,440 --> 00:18:27,440 the concept of lazy is eager. Um but 385 00:18:27,440 --> 00:18:31,360 I've also seen it called non-lazy. 386 00:18:31,360 --> 00:18:33,919 I haven't seen it called unlazy. And the 387 00:18:33,919 --> 00:18:37,520 basic syntax is that you lazy import the 388 00:18:37,520 --> 00:18:40,480 module. And again, that gives me the 389 00:18:40,480 --> 00:18:42,799 quicker startup and a lower memory 390 00:18:42,799 --> 00:18:46,240 overhead if I don't need it. 391 00:18:46,240 --> 00:18:50,720 Um, lazy is a soft keyword. 392 00:18:50,720 --> 00:18:52,080 Who's familiar with the difference 393 00:18:52,080 --> 00:18:56,720 between soft and hard keywords? 394 00:18:56,720 --> 00:18:58,320 Three of you. [laughter] 395 00:18:58,320 --> 00:19:02,160 Four of you. Toby, who I um quizzed on 396 00:19:02,160 --> 00:19:04,799 earlier, 397 00:19:04,799 --> 00:19:08,240 lazy is a soft keyword. Now, what does 398 00:19:08,240 --> 00:19:10,880 that mean? In introducing a new keyword 399 00:19:10,880 --> 00:19:12,720 into a language such as Python, there's 400 00:19:12,720 --> 00:19:14,960 a great danger that people are already 401 00:19:14,960 --> 00:19:18,640 using that word for something. I might 402 00:19:18,640 --> 00:19:21,919 have a variable called lazy. 403 00:19:21,919 --> 00:19:23,919 And if I've got a variable called lazy, 404 00:19:23,919 --> 00:19:28,400 315 will now break that. So a l a soft 405 00:19:28,400 --> 00:19:30,799 keyword is a keyword that you can still 406 00:19:30,799 --> 00:19:33,280 use as a variable. You could think of it 407 00:19:33,280 --> 00:19:35,760 as a contextual 408 00:19:35,760 --> 00:19:38,960 um a con contextual keyword. It only 409 00:19:38,960 --> 00:19:41,919 makes sense. So you can do a lazy equals 410 00:19:41,919 --> 00:19:45,679 true. That's fine. And as well you can 411 00:19:45,679 --> 00:19:49,679 also do a lazy import of a module. The 412 00:19:49,679 --> 00:19:53,840 lazy is just uh the first lazy that lazy 413 00:19:53,840 --> 00:19:57,280 is just an ordinary variable and doesn't 414 00:19:57,280 --> 00:20:00,799 conflict with the lazy import. Um this 415 00:20:00,799 --> 00:20:03,200 all happened when the paser changed in 416 00:20:03,200 --> 00:20:05,039 Python 417 00:20:05,039 --> 00:20:07,679 can't remember 418 00:20:07,679 --> 00:20:10,480 when we got the peg 311 312 somewhere 419 00:20:10,480 --> 00:20:12,799 around there. 420 00:20:12,799 --> 00:20:17,520 So lazy is one of the soft keywords. 421 00:20:17,520 --> 00:20:20,720 What are the other soft keywords in 315? 422 00:20:20,720 --> 00:20:23,440 There's five of them. Lazy is one, the 423 00:20:23,440 --> 00:20:28,240 other four. Anyone shout it out? 424 00:20:28,240 --> 00:20:29,360 Async. 425 00:20:29,360 --> 00:20:31,520 Async. Oh, that's a very interesting 426 00:20:31,520 --> 00:20:33,600 question. Yeah, that was because that 427 00:20:33,600 --> 00:20:37,280 actually varied. Um, it it wasn't uh it 428 00:20:37,280 --> 00:20:39,760 was [sighs] 429 00:20:39,760 --> 00:20:42,159 not for a while. That's right. What else 430 00:20:42,159 --> 00:20:44,000 have we got? 431 00:20:44,000 --> 00:20:46,880 Match. Match and case. 432 00:20:46,880 --> 00:20:48,799 uh came out when we got the uh the match 433 00:20:48,799 --> 00:20:53,120 and case. Um one um 434 00:20:53,120 --> 00:20:55,840 two more. 435 00:20:55,840 --> 00:20:56,720 What was that? 436 00:20:56,720 --> 00:20:57,440 Type. 437 00:20:57,440 --> 00:21:00,080 Type. Yes. Nice. And uh even that's an 438 00:21:00,080 --> 00:21:01,360 interesting one because we've even got 439 00:21:01,360 --> 00:21:04,960 type as a built-in function and uh type 440 00:21:04,960 --> 00:21:07,600 as a type aliasing keyword. And the 441 00:21:07,600 --> 00:21:10,320 other one is one that I um often forget 442 00:21:10,320 --> 00:21:13,600 which is underscore which only applies 443 00:21:13,600 --> 00:21:18,880 in a um within a case label. 444 00:21:18,880 --> 00:21:21,280 That's soft keywords. That means that 445 00:21:21,280 --> 00:21:25,440 lazy won't break your uh your um current 446 00:21:25,440 --> 00:21:29,760 programs as you move to 315. 447 00:21:29,760 --> 00:21:31,919 Lazy imports are optin. You don't have 448 00:21:31,919 --> 00:21:34,240 to use them. If you don't use them, 449 00:21:34,240 --> 00:21:36,880 they're um it'll just be eager by 450 00:21:36,880 --> 00:21:39,520 default, how it always was. Lazy is 451 00:21:39,520 --> 00:21:41,520 thread safe, so we don't have to worry 452 00:21:41,520 --> 00:21:44,960 about different um uh threads doing the 453 00:21:44,960 --> 00:21:47,360 imports. The first of the threads that 454 00:21:47,360 --> 00:21:51,120 does the actual use will be the one that 455 00:21:51,120 --> 00:21:54,559 um uh causes the invocation to um to 456 00:21:54,559 --> 00:21:57,760 load it. Uh there's no measurable 457 00:21:57,760 --> 00:21:59,600 performance overhead. So there's no real 458 00:21:59,600 --> 00:22:02,080 penalty in making them lazy from a 459 00:22:02,080 --> 00:22:04,559 performance perspective. And once 460 00:22:04,559 --> 00:22:06,960 they're brought in then there is 461 00:22:06,960 --> 00:22:09,520 literally zero overhead. There is no 462 00:22:09,520 --> 00:22:13,360 overhead once they have been 463 00:22:13,360 --> 00:22:15,679 that word. [laughter] 464 00:22:15,679 --> 00:22:18,640 Uh I've read that as reified but um my 465 00:22:18,640 --> 00:22:21,679 wife corrected me that it's raified. um 466 00:22:21,679 --> 00:22:24,799 making real once it's actually been 467 00:22:24,799 --> 00:22:27,679 brought in once one of the threads once 468 00:22:27,679 --> 00:22:30,480 somebody has used one of those fields 469 00:22:30,480 --> 00:22:33,679 then there is zero overhead 470 00:22:33,679 --> 00:22:35,120 and of course this is going to give us 471 00:22:35,120 --> 00:22:37,039 the quicker startup and lower memory 472 00:22:37,039 --> 00:22:38,799 overhead. 473 00:22:38,799 --> 00:22:41,840 Um, you can use it with a from. 474 00:22:41,840 --> 00:22:44,480 That's a little um 475 00:22:44,480 --> 00:22:46,320 there was much debate when this was 476 00:22:46,320 --> 00:22:48,880 proposed about where is lazy with from 477 00:22:48,880 --> 00:22:51,520 going to happen. And that reminds me to 478 00:22:51,520 --> 00:22:55,120 mention that um there are other ways of 479 00:22:55,120 --> 00:22:57,840 doing lazy imports. There's the lazy 480 00:22:57,840 --> 00:23:00,080 loader in the standard library, but they 481 00:23:00,080 --> 00:23:02,320 don't work with from. 482 00:23:02,320 --> 00:23:04,720 So, we needed a new keyword to make it 483 00:23:04,720 --> 00:23:07,840 work with from. 484 00:23:07,840 --> 00:23:10,559 Um but you can't use lazy on a star 485 00:23:10,559 --> 00:23:13,200 import. 486 00:23:13,200 --> 00:23:16,720 Uh imports can uh inside functions class 487 00:23:16,720 --> 00:23:19,039 bodies try accept blocks uh can't be 488 00:23:19,039 --> 00:23:21,200 lazy. 489 00:23:21,200 --> 00:23:24,880 It doesn't cascade recursively. So if 490 00:23:24,880 --> 00:23:27,039 this one's lazy that one may or may not 491 00:23:27,039 --> 00:23:30,200 be lazy. 492 00:23:30,240 --> 00:23:32,640 And uh the important point here is that 493 00:23:32,640 --> 00:23:35,520 they're resolved at access. 494 00:23:35,520 --> 00:23:37,360 So the first time you use something out 495 00:23:37,360 --> 00:23:39,600 of that module that's when it gets 496 00:23:39,600 --> 00:23:41,760 imported 497 00:23:41,760 --> 00:23:44,320 or you can call resolve if you want to 498 00:23:44,320 --> 00:23:47,840 force it to happen. Now 499 00:23:47,840 --> 00:23:52,640 uh more notes it occurs at use time not 500 00:23:52,640 --> 00:23:56,400 at the lazy import time which means uh 501 00:23:56,400 --> 00:23:58,159 one of the downsides one of the things 502 00:23:58,159 --> 00:24:00,080 that you need to be careful of is that 503 00:24:00,080 --> 00:24:03,440 module not found error could happen 504 00:24:03,440 --> 00:24:05,600 somewhere else. 505 00:24:05,600 --> 00:24:08,000 For example, if I do a lazy import of 506 00:24:08,000 --> 00:24:10,480 not there, no problem. 507 00:24:10,480 --> 00:24:15,440 Well, not yet. But it won't crash there. 508 00:24:15,440 --> 00:24:18,159 It won't module not found there. It'll 509 00:24:18,159 --> 00:24:21,520 module not found once you go to actually 510 00:24:21,520 --> 00:24:24,000 use something out of the module. For my 511 00:24:24,000 --> 00:24:25,840 money, that's probably the most um 512 00:24:25,840 --> 00:24:29,360 significant aspect of um lazy loading 513 00:24:29,360 --> 00:24:31,840 and why I might not choose to use lazy 514 00:24:31,840 --> 00:24:34,400 loading everywhere. 515 00:24:34,400 --> 00:24:38,400 So it fails there, not there. And that 516 00:24:38,400 --> 00:24:40,480 could have some um error catching 517 00:24:40,480 --> 00:24:42,080 issues. 518 00:24:42,080 --> 00:24:45,600 It's very nicely suited to typeing type 519 00:24:45,600 --> 00:24:47,120 checking 520 00:24:47,120 --> 00:24:50,000 because um in this case it doesn't even 521 00:24:50,000 --> 00:24:52,720 have to go and import. 522 00:24:52,720 --> 00:24:55,120 So the um obviously the type checker 523 00:24:55,120 --> 00:24:58,000 will need to but my program that's using 524 00:24:58,000 --> 00:25:00,480 those types now doesn't get any overhead 525 00:25:00,480 --> 00:25:03,200 from that. Although annotations have 526 00:25:03,200 --> 00:25:05,919 been um lazy for a while. The downside 527 00:25:05,919 --> 00:25:07,679 of lazy is that you're going to only be 528 00:25:07,679 --> 00:25:09,792 able to use it if you move to 315. 529 00:25:09,792 --> 00:25:11,279 [laughter] 530 00:25:11,279 --> 00:25:13,360 Some of you might be stuck on older 531 00:25:13,360 --> 00:25:16,799 versions of Python. 532 00:25:16,799 --> 00:25:20,480 He says um knowing it's everybody. 533 00:25:20,480 --> 00:25:23,600 But um so what can we do? Well uh 534 00:25:23,600 --> 00:25:27,760 upgrade to 315. Easy. Or you could go 535 00:25:27,760 --> 00:25:31,120 and use the lazy modules. 536 00:25:31,120 --> 00:25:34,000 Do that before your import. Setting that 537 00:25:34,000 --> 00:25:37,279 global variable will then um make all of 538 00:25:37,279 --> 00:25:40,559 these ones now lazy. That's a nice 539 00:25:40,559 --> 00:25:43,279 solution for backwards compatibility. 540 00:25:43,279 --> 00:25:48,120 Back to old versions like 313. 541 00:25:48,240 --> 00:25:51,120 Or you can do global control. 542 00:25:51,120 --> 00:25:53,919 You got the tac x again for CPython to 543 00:25:53,919 --> 00:25:56,240 set lazy imports to a mode. I'll show 544 00:25:56,240 --> 00:25:58,320 you what that is. You could set the 545 00:25:58,320 --> 00:26:02,240 environmental variable or using cis you 546 00:26:02,240 --> 00:26:04,000 could set lazy imports. In all of those 547 00:26:04,000 --> 00:26:07,520 cases, mode is normal as in behave like 548 00:26:07,520 --> 00:26:11,840 lazy tells it to or everybody is lazy or 549 00:26:11,840 --> 00:26:14,880 nobody is lazy. 550 00:26:14,880 --> 00:26:16,799 You can if you need to. I haven't 551 00:26:16,799 --> 00:26:18,960 explored this at depth but uh there are 552 00:26:18,960 --> 00:26:22,320 some more advanced feature filters. Um 553 00:26:22,320 --> 00:26:25,120 you can set it so that uh you get very 554 00:26:25,120 --> 00:26:28,159 close control over how the um lazy 555 00:26:28,159 --> 00:26:30,960 import works. 556 00:26:30,960 --> 00:26:32,559 Some fancy words you'll come across. 557 00:26:32,559 --> 00:26:37,360 Lazy I mentioned eager is the opposite. 558 00:26:37,360 --> 00:26:40,799 Elleading um is a very common word in 559 00:26:40,799 --> 00:26:44,720 C++ actually but um means leaving it out 560 00:26:44,720 --> 00:26:48,159 and that's what the lazy is doing and 561 00:26:48,159 --> 00:26:50,960 raify to make it concrete to make it 562 00:26:50,960 --> 00:26:56,520 real in our case to actually load it 563 00:26:56,559 --> 00:26:59,919 or don't use AI. After I wrote this talk 564 00:26:59,919 --> 00:27:01,520 I thought maybe I should just run it 565 00:27:01,520 --> 00:27:03,919 through um some AI check that I've 566 00:27:03,919 --> 00:27:05,919 covered everything. So I asked the 567 00:27:05,919 --> 00:27:07,200 question, what are the most important 568 00:27:07,200 --> 00:27:11,960 points with Python's new lazy keyword? 569 00:27:14,898 --> 00:27:18,159 [laughter] And of course, it's not 314. 570 00:27:18,159 --> 00:27:22,758 So I asked it, are you sure it's in 314? 571 00:27:22,758 --> 00:27:24,778 [laughter] 572 00:27:25,919 --> 00:27:28,080 And cudos, they admitted they were 573 00:27:28,080 --> 00:27:31,600 wrong. Too long didn't listen. Use lazy 574 00:27:31,600 --> 00:27:33,440 where it's relevant, particularly for 575 00:27:33,440 --> 00:27:36,400 command line processing. 576 00:27:36,400 --> 00:27:38,640 Um, particularly for startup. Watch out 577 00:27:38,640 --> 00:27:40,240 for import errors. You're going to have 578 00:27:40,240 --> 00:27:42,400 to be careful about that. And, uh, that 579 00:27:42,400 --> 00:27:44,480 will give you quicker startup and lower 580 00:27:44,480 --> 00:27:47,200 memory overhead. 581 00:27:47,200 --> 00:27:49,120 Too long, didn't listen. Document your 582 00:27:49,120 --> 00:27:52,880 own work. Use AI carefully. Use lazy 583 00:27:52,880 --> 00:27:55,919 evaluation yield where it's relevant. 584 00:27:55,919 --> 00:27:58,880 And use lazy imports where they're 585 00:27:58,880 --> 00:28:01,200 relevant. 586 00:28:01,200 --> 00:28:03,440 There's some details. This was done on 587 00:28:03,440 --> 00:28:05,840 pre-release software. Although by the 588 00:28:05,840 --> 00:28:07,919 time any of the video goes out, it might 589 00:28:07,919 --> 00:28:10,960 be uh it might be live benchmarks were 590 00:28:10,960 --> 00:28:13,679 done there. Your mileage may vary, but I 591 00:28:13,679 --> 00:28:16,480 got good uh good good um performance 592 00:28:16,480 --> 00:28:19,520 startup using lazy. There's some of the 593 00:28:19,520 --> 00:28:22,559 um benchmarks 594 00:28:22,559 --> 00:28:26,399 for more information. Oops. 595 00:28:26,399 --> 00:28:29,039 Uh 810. And it's worthwhile noting that 596 00:28:29,039 --> 00:28:32,399 the earlier PEP 690 which was to make 597 00:28:32,399 --> 00:28:35,039 lazy which was to make imports always 598 00:28:35,039 --> 00:28:39,200 lazy um by default was in fact rejected 599 00:28:39,200 --> 00:28:44,120 for good reasons that were listed there. 600 00:28:45,760 --> 00:28:50,584 Thanks for coming to my talk. [applause] 601 00:28:55,120 --> 00:28:57,679 Thanks to the uh Python AU team, the AV 602 00:28:57,679 --> 00:29:00,240 team, the um the venue I also meant to 603 00:29:00,240 --> 00:29:02,240 add in there as well, volunteers and the 604 00:29:02,240 --> 00:29:04,880 session chairs and uh of course to the 605 00:29:04,880 --> 00:29:06,880 Python core team and all the 606 00:29:06,880 --> 00:29:10,320 contributors. Um you can contact me at 607 00:29:10,320 --> 00:29:14,120 my company plus.com.au/cont. 608 00:29:14,399 --> 00:29:16,080 I think we're out of time. 609 00:29:16,080 --> 00:29:17,279 Yeah, I don't think we'd have time for 610 00:29:17,279 --> 00:29:18,799 questions unfortunately. I can take uh 611 00:29:18,799 --> 00:29:20,960 questions um offline after 612 00:29:20,960 --> 00:29:23,520 out out in the corridor. Um here is your 613 00:29:23,520 --> 00:29:25,279 delightful mug. Thank you. There's a 614 00:29:25,279 --> 00:29:28,575 cracker of speech. [applause]