1 00:00:04,960 --> 00:00:19,999 [Music] 2 00:00:20,560 --> 00:00:25,599 I love that intro welcome back to the 3 00:00:22,760 --> 00:00:28,160 second talk of shiny block uh on Deck we 4 00:00:25,599 --> 00:00:32,480 have no CTS with what python can learn 5 00:00:28,160 --> 00:00:32,480 from other languages please welcome 6 00:00:36,320 --> 00:00:42,120 Noah see excellent I am indeed Noz I'm 7 00:00:39,960 --> 00:00:43,640 an S geom magical Labs we do computer 8 00:00:42,120 --> 00:00:45,440 vision and augmented reality stuff for 9 00:00:43,640 --> 00:00:47,360 Ikea but I'm not here to talk about that 10 00:00:45,440 --> 00:00:49,559 today and I'm also not really here to 11 00:00:47,360 --> 00:00:51,280 talk about python python is great it's 12 00:00:49,559 --> 00:00:52,879 my primary tool for solving most 13 00:00:51,280 --> 00:00:54,359 technical challenges but there's a lot 14 00:00:52,879 --> 00:00:55,800 of other programming languages out there 15 00:00:54,359 --> 00:00:57,800 and some of them have features or 16 00:00:55,800 --> 00:01:00,559 workflows that python 17 00:00:57,800 --> 00:01:02,039 lacks the goal of this talk is not to 18 00:01:00,559 --> 00:01:03,920 immediately Advocate that we turn each 19 00:01:02,039 --> 00:01:05,519 of these features into a pep we want to 20 00:01:03,920 --> 00:01:07,000 broaden our exposure to programming 21 00:01:05,519 --> 00:01:09,080 Concepts and talk about the trade-offs 22 00:01:07,000 --> 00:01:10,680 being made if any of these ideas really 23 00:01:09,080 --> 00:01:13,080 grab you try messing around with them in 24 00:01:10,680 --> 00:01:15,360 a library or make a patch or cpython but 25 00:01:13,080 --> 00:01:17,200 really we're just here to learn I'm 26 00:01:15,360 --> 00:01:18,720 going to begin with PHP and I don't mean 27 00:01:17,200 --> 00:01:21,360 this ironically or to be some kind of 28 00:01:18,720 --> 00:01:22,720 language hipster PHP is pretty cool I 29 00:01:21,360 --> 00:01:24,720 spent the last few years on a side 30 00:01:22,720 --> 00:01:26,200 project almost entirely in PHP and it's 31 00:01:24,720 --> 00:01:27,840 given me a refreshed 32 00:01:26,200 --> 00:01:30,119 appreciation the biggest thing I've 33 00:01:27,840 --> 00:01:32,280 grown to like about it the simplicity 34 00:01:30,119 --> 00:01:34,280 each file maps unambiguously to a single 35 00:01:32,280 --> 00:01:36,520 URL and deployment is as simple as 36 00:01:34,280 --> 00:01:38,159 updating that file in any way you prefer 37 00:01:36,520 --> 00:01:40,680 most editors these days support remote 38 00:01:38,159 --> 00:01:43,439 editing via SFTP so you just click on 39 00:01:40,680 --> 00:01:45,119 new file you start coding and that's it 40 00:01:43,439 --> 00:01:47,719 this puts even low boilerplate web 41 00:01:45,119 --> 00:01:49,240 Frameworks in Python to Absolute shame 42 00:01:47,719 --> 00:01:50,680 and once you get going changes in the 43 00:01:49,240 --> 00:01:52,560 code they just show up you don't need to 44 00:01:50,680 --> 00:01:54,960 restart a server or configure automatic 45 00:01:52,560 --> 00:01:58,200 reloads or whatever you just write code 46 00:01:54,960 --> 00:01:59,560 and it runs simple as that in Python we 47 00:01:58,200 --> 00:02:02,240 like to say that explicit is better than 48 00:01:59,560 --> 00:02:04,399 implicit it and overall I agree but man 49 00:02:02,240 --> 00:02:05,960 our juggling Imports annoying sometimes 50 00:02:04,399 --> 00:02:07,439 even with editor help you've got a dance 51 00:02:05,960 --> 00:02:08,560 of you write a new line of code you 52 00:02:07,439 --> 00:02:09,800 realize you don't have the import in 53 00:02:08,560 --> 00:02:11,239 place you scroll up to the top of the 54 00:02:09,800 --> 00:02:12,440 file you add the import you scroll back 55 00:02:11,239 --> 00:02:14,959 down to where you were you've lost your 56 00:02:12,440 --> 00:02:16,640 train of thought it's really jarring 57 00:02:14,959 --> 00:02:19,000 autoloaders bridge this Gap while 58 00:02:16,640 --> 00:02:21,480 keeping things mostly explicit if you 59 00:02:19,000 --> 00:02:23,400 enforce a onetoone mapping between uh 60 00:02:21,480 --> 00:02:24,959 code symbols and file system paths you 61 00:02:23,400 --> 00:02:26,840 know exactly where a symbol load is 62 00:02:24,959 --> 00:02:28,519 going to end up this is also deeply 63 00:02:26,840 --> 00:02:30,720 integrated into the PHP package manager 64 00:02:28,519 --> 00:02:31,920 called composer toe bake the mapping 65 00:02:30,720 --> 00:02:33,440 between those code symbols and the 66 00:02:31,920 --> 00:02:35,160 underlying file system paths so the 67 00:02:33,440 --> 00:02:37,160 import doesn't even have to Traverse a 68 00:02:35,160 --> 00:02:38,440 package directory I don't actually know 69 00:02:37,160 --> 00:02:39,640 if I would honestly prefer this in 70 00:02:38,440 --> 00:02:40,680 Python but it's at least something to 71 00:02:39,640 --> 00:02:43,360 think 72 00:02:40,680 --> 00:02:44,599 about the standard library for PHP is a 73 00:02:43,360 --> 00:02:46,400 little bit different from python it's 74 00:02:44,599 --> 00:02:48,319 evolved towards a single Niche web 75 00:02:46,400 --> 00:02:49,959 application development so it biases 76 00:02:48,319 --> 00:02:51,959 towards things needed in that space so 77 00:02:49,959 --> 00:02:53,920 for example my SQL and postgress clients 78 00:02:51,959 --> 00:02:56,120 come by default there's also a high 79 00:02:53,920 --> 00:02:57,560 performance HTTP client and then beyond 80 00:02:56,120 --> 00:03:00,360 that there's this thing called the PHP 81 00:02:57,560 --> 00:03:02,040 extension community library or Pele an 82 00:03:00,360 --> 00:03:03,879 extension PHP is very similar to an 83 00:03:02,040 --> 00:03:06,159 extension library in Python but the big 84 00:03:03,879 --> 00:03:08,799 difference between PE and pii is that 85 00:03:06,159 --> 00:03:11,120 for the a lot of the big core supported 86 00:03:08,799 --> 00:03:12,920 extensions the documentation for them is 87 00:03:11,120 --> 00:03:14,280 Right alongside the main PHP docs you 88 00:03:12,920 --> 00:03:16,040 don't have to search for a library and 89 00:03:14,280 --> 00:03:18,519 then find its read me or read the docs 90 00:03:16,040 --> 00:03:20,560 or whatever it's all just there Peck 91 00:03:18,519 --> 00:03:22,720 effectively bridges into a broader 92 00:03:20,560 --> 00:03:24,680 secondary standard 93 00:03:22,720 --> 00:03:26,440 library and alongside the standard 94 00:03:24,680 --> 00:03:29,560 Library being adapted for its major use 95 00:03:26,440 --> 00:03:31,120 case PHP as a language is itself too 96 00:03:29,560 --> 00:03:33,000 it's web first so there's a simple 97 00:03:31,120 --> 00:03:35,280 templating framework baked directly into 98 00:03:33,000 --> 00:03:36,760 the language in Python we have we have F 99 00:03:35,280 --> 00:03:38,239 strings now and they've matured over 100 00:03:36,760 --> 00:03:40,280 time we've definitely started moving in 101 00:03:38,239 --> 00:03:43,280 this direction but relatively complex 102 00:03:40,280 --> 00:03:46,560 PHP code is again going to run circles 103 00:03:43,280 --> 00:03:48,720 around Python's explicitly simplest web 104 00:03:46,560 --> 00:03:50,560 framworks Ruby is probably the second 105 00:03:48,720 --> 00:03:52,239 most language used over my career and 106 00:03:50,560 --> 00:03:53,480 while the days of python and Ruby being 107 00:03:52,239 --> 00:03:55,239 thought of as relatively neck and- neck 108 00:03:53,480 --> 00:03:56,840 have wed as Python's taken over more and 109 00:03:55,239 --> 00:03:58,159 more niches it's still a vibrant 110 00:03:56,840 --> 00:04:00,319 language in 111 00:03:58,159 --> 00:04:01,400 community symbols are thing in a lot of 112 00:04:00,319 --> 00:04:03,439 languages but I'm going to highlight 113 00:04:01,400 --> 00:04:05,680 them here at their simplest symbols are 114 00:04:03,439 --> 00:04:07,439 just fancy strings but internally 115 00:04:05,680 --> 00:04:09,040 they're D duplicated so checking 116 00:04:07,439 --> 00:04:11,079 equality between two symbols is a 117 00:04:09,040 --> 00:04:13,760 constant time operation we do have this 118 00:04:11,079 --> 00:04:16,040 in Python cy. intern and intern strings 119 00:04:13,760 --> 00:04:17,759 but they're very rarely used but there's 120 00:04:16,040 --> 00:04:19,959 this deeper level to symbols having a 121 00:04:17,759 --> 00:04:21,519 dedicated syntax for this makes it e 122 00:04:19,959 --> 00:04:23,960 easier to differentiate between text 123 00:04:21,519 --> 00:04:26,759 strings and for lack of a better term 124 00:04:23,960 --> 00:04:28,240 symbolic strings these often serve very 125 00:04:26,759 --> 00:04:29,600 different functions in code and even if 126 00:04:28,240 --> 00:04:31,919 they're the same underlying data type 127 00:04:29,600 --> 00:04:33,160 they they really shouldn't be mixed we 128 00:04:31,919 --> 00:04:35,160 do already kind of have this a little 129 00:04:33,160 --> 00:04:37,199 bit in Python with the uh keyword 130 00:04:35,160 --> 00:04:39,039 argument syntax those are still strings 131 00:04:37,199 --> 00:04:40,479 under the hood but they're clearly 132 00:04:39,039 --> 00:04:42,320 intended to be used for a different 133 00:04:40,479 --> 00:04:44,560 purpose and you don't uh you create a 134 00:04:42,320 --> 00:04:45,960 boundary between what kinds of use cases 135 00:04:44,560 --> 00:04:47,960 you want those strings to be 136 00:04:45,960 --> 00:04:50,560 used blocks are something much more 137 00:04:47,960 --> 00:04:52,400 specific to Ruby deep down we do have 138 00:04:50,560 --> 00:04:54,000 this in Python you can write a Lambda 139 00:04:52,400 --> 00:04:56,600 expression as an anonymous function 140 00:04:54,000 --> 00:04:58,919 value uh but blocks do a lot more than 141 00:04:56,600 --> 00:05:00,400 that first off they're not limited to a 142 00:04:58,919 --> 00:05:01,880 single expression that's handy for 143 00:05:00,400 --> 00:05:04,440 anything complicated but more 144 00:05:01,880 --> 00:05:06,560 importantly that calling syntax with do 145 00:05:04,440 --> 00:05:09,440 you can hang a block off any function in 146 00:05:06,560 --> 00:05:10,960 Ruby now you can pass around Lambda 147 00:05:09,440 --> 00:05:12,560 literals in Python it's technically 148 00:05:10,960 --> 00:05:14,600 possible we all sometimes do it when 149 00:05:12,560 --> 00:05:16,759 we're writing sort keys but the utility 150 00:05:14,600 --> 00:05:18,160 falls off really quickly after that and 151 00:05:16,759 --> 00:05:20,000 so Community Practice is that you'll 152 00:05:18,160 --> 00:05:22,319 write a named inline function and then 153 00:05:20,000 --> 00:05:24,080 you'll pass it around as a value totally 154 00:05:22,319 --> 00:05:25,960 works but it does have this problem that 155 00:05:24,080 --> 00:05:27,240 the read order is Now inverted from the 156 00:05:25,960 --> 00:05:29,360 execution 157 00:05:27,240 --> 00:05:30,800 order and this gets even worse when we 158 00:05:29,360 --> 00:05:32,720 start talking about method chaining 159 00:05:30,800 --> 00:05:34,319 something Ruby really excels at I'm not 160 00:05:32,720 --> 00:05:35,919 even really going to touch the python 161 00:05:34,319 --> 00:05:37,520 buil-in functions which are completely 162 00:05:35,919 --> 00:05:39,840 backwards from this and I hate it but 163 00:05:37,520 --> 00:05:42,160 you can write a method chaining API in 164 00:05:39,840 --> 00:05:43,800 Python for instance the Jenga omm but 165 00:05:42,160 --> 00:05:45,520 blocks allow it to go a lot further 166 00:05:43,800 --> 00:05:47,520 without additional 167 00:05:45,520 --> 00:05:49,199 effort and another language that has a 168 00:05:47,520 --> 00:05:51,720 different take on this is Dart and it's 169 00:05:49,199 --> 00:05:53,880 double do cascading operator this allows 170 00:05:51,720 --> 00:05:55,440 interrupting a method chain to go one 171 00:05:53,880 --> 00:05:57,400 level up so to speak like in a file 172 00:05:55,440 --> 00:05:59,400 system path performing a sequence of 173 00:05:57,400 --> 00:06:01,319 operations on the same object rather 174 00:05:59,400 --> 00:06:03,199 than to propagate the chain through 175 00:06:01,319 --> 00:06:05,479 every Link in it this allows method 176 00:06:03,199 --> 00:06:06,960 chaining in Dart with zero extra work by 177 00:06:05,479 --> 00:06:08,880 API 178 00:06:06,960 --> 00:06:10,319 authors another place really makes 179 00:06:08,880 --> 00:06:12,479 excellent use of blocks is its version 180 00:06:10,319 --> 00:06:14,120 of the Builder pattern many complex 181 00:06:12,479 --> 00:06:15,919 object instructors take a block which 182 00:06:14,120 --> 00:06:18,560 exposes a little configuration API 183 00:06:15,919 --> 00:06:21,160 almost a DSL this can allow for very 184 00:06:18,560 --> 00:06:22,800 complex initialization uh while still 185 00:06:21,160 --> 00:06:24,479 being Compact and without sacrificing 186 00:06:22,800 --> 00:06:26,039 flexibility for an usual conditions and 187 00:06:24,479 --> 00:06:27,639 it's very nice for things like static 188 00:06:26,039 --> 00:06:29,960 analysis type 189 00:06:27,639 --> 00:06:31,759 checking going a bit broader than Ruby 190 00:06:29,960 --> 00:06:33,880 as a language one big thing that Ruby 191 00:06:31,759 --> 00:06:35,280 has as a community that I wish python 192 00:06:33,880 --> 00:06:37,240 was better at is the Ruby for good 193 00:06:35,280 --> 00:06:39,520 organization it's a dedicated support 194 00:06:37,240 --> 00:06:41,280 structure for Ruby projects work with 195 00:06:39,520 --> 00:06:43,199 which work with specific nonprofit 196 00:06:41,280 --> 00:06:44,639 organizations we have a lot of paths for 197 00:06:43,199 --> 00:06:46,440 advancing python itself and some of the 198 00:06:44,639 --> 00:06:48,039 bigger languages like Jango but 199 00:06:46,440 --> 00:06:49,479 sometimes it's nice to do real tangible 200 00:06:48,039 --> 00:06:51,800 good in the 201 00:06:49,479 --> 00:06:53,240 world after Ruby the next logical place 202 00:06:51,800 --> 00:06:54,680 to look for ideas are the JavaScript and 203 00:06:53,240 --> 00:06:56,280 typescript worlds I'm not going to 204 00:06:54,680 --> 00:06:58,080 repeat every feature shared by all these 205 00:06:56,280 --> 00:07:00,240 languages like how JavaScript also has a 206 00:06:58,080 --> 00:07:01,560 great Anonymous function syntax we'd be 207 00:07:00,240 --> 00:07:02,960 here all day I'm just going to focus on 208 00:07:01,560 --> 00:07:04,919 some of the interesting 209 00:07:02,960 --> 00:07:06,599 bits this one has been discussed at 210 00:07:04,919 --> 00:07:08,000 Great length in the python Community but 211 00:07:06,599 --> 00:07:10,680 I personally think they should be added 212 00:07:08,000 --> 00:07:12,680 and it's my talk so one more time null 213 00:07:10,680 --> 00:07:14,479 cesing operators are very similar to an 214 00:07:12,680 --> 00:07:16,479 or but they're checking explicitly for 215 00:07:14,479 --> 00:07:19,280 nulles rather than any kind of falsy 216 00:07:16,479 --> 00:07:20,759 value safe navigation operators build on 217 00:07:19,280 --> 00:07:22,440 top of that you can access a deeply 218 00:07:20,759 --> 00:07:23,680 nested chain of fields but if anywhere 219 00:07:22,440 --> 00:07:25,440 there's anywhere in the chain there's a 220 00:07:23,680 --> 00:07:27,800 null the whole thing stops and just 221 00:07:25,440 --> 00:07:29,800 returns a null right there as you can 222 00:07:27,800 --> 00:07:31,199 see in this very small example safe 223 00:07:29,800 --> 00:07:32,720 navigation operators dramatically 224 00:07:31,199 --> 00:07:35,240 streamline code this is something I 225 00:07:32,720 --> 00:07:37,400 deeply miss when I'm working in 226 00:07:35,240 --> 00:07:39,440 Python typescript has always had a fine 227 00:07:37,400 --> 00:07:41,400 line to walk it applies type semantics 228 00:07:39,440 --> 00:07:43,080 to JavaScript but it can't fundamentally 229 00:07:41,400 --> 00:07:45,199 reshape the language or be too 230 00:07:43,080 --> 00:07:47,039 alienating so they knew the majority of 231 00:07:45,199 --> 00:07:48,280 object passed around within a codebase 232 00:07:47,039 --> 00:07:49,919 were going to be the JavaScript 233 00:07:48,280 --> 00:07:52,879 equivalent of just a plain dict no 234 00:07:49,919 --> 00:07:54,800 matter what they also wanted to allow 235 00:07:52,879 --> 00:07:56,680 typing information be gradually added to 236 00:07:54,800 --> 00:07:59,039 a code base out of this comes the 237 00:07:56,680 --> 00:07:59,960 synthesized requirement to support type 238 00:07:59,039 --> 00:08:02,560 DEC 239 00:07:59,960 --> 00:08:04,680 against arbitrary inline dicks in Python 240 00:08:02,560 --> 00:08:06,759 terms this is kind of similar to a data 241 00:08:04,680 --> 00:08:08,520 class but it's completely ad hoc and 242 00:08:06,759 --> 00:08:10,639 without requiring either the upstream or 243 00:08:08,520 --> 00:08:12,560 Downstream code to change this certainly 244 00:08:10,639 --> 00:08:14,319 isn't as nice as a fully typed code base 245 00:08:12,560 --> 00:08:16,319 but it gives a smoother on-ramp to doing 246 00:08:14,319 --> 00:08:18,720 one bit of code at a 247 00:08:16,319 --> 00:08:20,400 time I'm kind of cheating here we do 248 00:08:18,720 --> 00:08:22,400 have promises in python as part of the 249 00:08:20,400 --> 00:08:24,280 con Futures library and perhaps their 250 00:08:22,400 --> 00:08:26,639 moment is over anyway uh with the 251 00:08:24,280 --> 00:08:30,319 continued up uptake in explicit asyn A 252 00:08:26,639 --> 00:08:31,960 we as Chris so rightfully pointed out uh 253 00:08:30,319 --> 00:08:33,519 most of those apis are now what you'd 254 00:08:31,960 --> 00:08:35,519 use in Python and even in other 255 00:08:33,519 --> 00:08:36,719 languages too but they're still worth 256 00:08:35,519 --> 00:08:39,320 studying even as only part of our 257 00:08:36,719 --> 00:08:40,800 Collective history promise chaining is a 258 00:08:39,320 --> 00:08:42,599 compact way to handle multiple 259 00:08:40,800 --> 00:08:44,760 interacting concurrent operations 260 00:08:42,599 --> 00:08:46,120 without dedicated syntax I'm pulling my 261 00:08:44,760 --> 00:08:47,800 punches with this a little bit this is a 262 00:08:46,120 --> 00:08:49,279 really simplistic example and in 263 00:08:47,800 --> 00:08:51,080 practice many promise chains were a lot 264 00:08:49,279 --> 00:08:52,920 harder to read but perhaps the technique 265 00:08:51,080 --> 00:08:55,880 we'll find another application 266 00:08:52,920 --> 00:08:57,200 someday on the topic of concurrency go 267 00:08:55,880 --> 00:08:58,519 it's no secret that go structured 268 00:08:57,200 --> 00:09:00,360 concurrency has made it a frequent 269 00:08:58,519 --> 00:09:01,600 choice in complex system code and 270 00:09:00,360 --> 00:09:03,079 honestly I think Python's already 271 00:09:01,600 --> 00:09:05,240 heading in a lot of the same 272 00:09:03,079 --> 00:09:07,399 directions if you've seen anything about 273 00:09:05,240 --> 00:09:09,240 go it's probably this go routines are 274 00:09:07,399 --> 00:09:10,680 concurrency mechanism more or less the 275 00:09:09,240 --> 00:09:12,519 same as we have with async functions 276 00:09:10,680 --> 00:09:14,360 except they're truly concurrent and 277 00:09:12,519 --> 00:09:16,519 channels are cues to move small bits of 278 00:09:14,360 --> 00:09:18,360 data between them I think this model is 279 00:09:16,519 --> 00:09:20,079 about to get very interesting in python 280 00:09:18,360 --> 00:09:21,760 as we've seen the addition of both Gil 281 00:09:20,079 --> 00:09:23,600 isolated sub interpreters and the new no 282 00:09:21,760 --> 00:09:25,839 Gill mode there's a future where we get 283 00:09:23,600 --> 00:09:27,720 something very similar to the code on 284 00:09:25,839 --> 00:09:30,040 screen but with full multicore 285 00:09:27,720 --> 00:09:31,519 concurrency 286 00:09:30,040 --> 00:09:33,560 runtime type checks are something python 287 00:09:31,519 --> 00:09:35,200 has always kept at arms length would you 288 00:09:33,560 --> 00:09:36,839 technically have it there's that runtime 289 00:09:35,200 --> 00:09:39,720 checkable decorator that comes from the 290 00:09:36,839 --> 00:09:41,600 typing module uh but as the docs warn 291 00:09:39,720 --> 00:09:43,680 you very emphatically all this does is 292 00:09:41,600 --> 00:09:45,839 check that the right method names exist 293 00:09:43,680 --> 00:09:48,000 not their type signatures compare this 294 00:09:45,839 --> 00:09:49,399 To Go's runtime casts which do a more 295 00:09:48,000 --> 00:09:50,640 complete check and they can either fail 296 00:09:49,399 --> 00:09:52,760 with an error message or just straight 297 00:09:50,640 --> 00:09:54,800 up crash your program whichever you 298 00:09:52,760 --> 00:09:56,640 prefer this would requ that there would 299 00:09:54,800 --> 00:09:57,560 be something in cpython itself that 300 00:09:56,640 --> 00:09:59,680 understands how to compare type 301 00:09:57,560 --> 00:10:02,040 signatures but perhaps we've come enough 302 00:09:59,680 --> 00:10:02,920 in our type hinting journey to be ready 303 00:10:02,040 --> 00:10:05,720 for 304 00:10:02,920 --> 00:10:07,440 that in a totally different direction go 305 00:10:05,720 --> 00:10:09,920 is among the Best in Class alongside 306 00:10:07,440 --> 00:10:11,680 rust with preparing easy Standalone 307 00:10:09,920 --> 00:10:13,760 executables as well as crossplatform 308 00:10:11,680 --> 00:10:15,760 compilation in the server world this 309 00:10:13,760 --> 00:10:17,360 makes deployment really easy inside 310 00:10:15,760 --> 00:10:19,560 minimalist containers all you need from 311 00:10:17,360 --> 00:10:21,920 the OS is some TLS certificates maybe a 312 00:10:19,560 --> 00:10:23,560 time zone definition file or two and for 313 00:10:21,920 --> 00:10:25,480 command line tools you can distribute a 314 00:10:23,560 --> 00:10:27,560 single binary without concern for the 315 00:10:25,480 --> 00:10:29,360 system Library versions or anything else 316 00:10:27,560 --> 00:10:31,120 uh briefcase has relatively recently 317 00:10:29,360 --> 00:10:32,160 added some simple CLI packaging support 318 00:10:31,120 --> 00:10:35,279 and I'm hopeful that it will improve 319 00:10:32,160 --> 00:10:37,920 things here make Russ make this 320 00:10:35,279 --> 00:10:39,760 better uh unic kernels build on static 321 00:10:37,920 --> 00:10:41,040 compilation and take it a level deeper 322 00:10:39,760 --> 00:10:42,800 rather than linking in the language 323 00:10:41,040 --> 00:10:44,519 runtime and maybe libc and some other 324 00:10:42,800 --> 00:10:46,720 files what if we statically link an 325 00:10:44,519 --> 00:10:48,120 entire operating system unical 326 00:10:46,720 --> 00:10:49,760 Frameworks take your app code and they 327 00:10:48,120 --> 00:10:51,600 turn it into a bootable OS image 328 00:10:49,760 --> 00:10:52,360 designed to run in a hypervisor instead 329 00:10:51,600 --> 00:10:54,399 of 330 00:10:52,360 --> 00:10:56,279 Linux while containers kind of took the 331 00:10:54,399 --> 00:10:57,639 sales out of this technique uh it can 332 00:10:56,279 --> 00:10:58,800 still matter when you want to get every 333 00:10:57,639 --> 00:11:00,959 last bit of performance out of your 334 00:10:58,800 --> 00:11:03,000 Hardware while also ensuring absolute 335 00:11:00,959 --> 00:11:04,680 maximum security isolation there are 336 00:11:03,000 --> 00:11:05,920 tools out there like uncraft that can do 337 00:11:04,680 --> 00:11:07,519 this today but they're all general 338 00:11:05,920 --> 00:11:08,920 purpose tools they lack the Deep 339 00:11:07,519 --> 00:11:09,959 integration into python to really make 340 00:11:08,920 --> 00:11:11,880 them 341 00:11:09,959 --> 00:11:13,200 shine if you're only here for things 342 00:11:11,880 --> 00:11:14,800 that have even a tiny chance of 343 00:11:13,200 --> 00:11:15,680 happening in Python I wish you well but 344 00:11:14,800 --> 00:11:17,639 now I want to look at a little bit of 345 00:11:15,680 --> 00:11:19,360 the long taale weirder features you 346 00:11:17,639 --> 00:11:21,000 maybe have heard about but it's really 347 00:11:19,360 --> 00:11:22,360 unlikely that python will actually 348 00:11:21,000 --> 00:11:24,440 probably discuss adding these at any 349 00:11:22,360 --> 00:11:26,839 point uh even against those long odds I 350 00:11:24,440 --> 00:11:29,320 still think there are things here to 351 00:11:26,839 --> 00:11:32,320 learn on the complete opposite end from 352 00:11:29,320 --> 00:11:34,399 packaging is easy on liners Pearl has a 353 00:11:32,320 --> 00:11:36,320 lot of interesting Design Elements but 354 00:11:34,399 --> 00:11:38,519 by far the most useful for me day to-day 355 00:11:36,320 --> 00:11:40,480 is Pearl pie it's a sequence of command 356 00:11:38,519 --> 00:11:42,519 line arguments that says take this list 357 00:11:40,480 --> 00:11:44,560 of input files run this expression 358 00:11:42,519 --> 00:11:46,560 against every line of every file and 359 00:11:44,560 --> 00:11:48,880 then write the results back to those 360 00:11:46,560 --> 00:11:50,880 files taken together this allows for a 361 00:11:48,880 --> 00:11:53,320 super set of things like said and O and 362 00:11:50,880 --> 00:11:54,720 Bash but in an incredibly compact 363 00:11:53,320 --> 00:11:56,120 package and without the Myriad of 364 00:11:54,720 --> 00:11:58,600 Provider differences between all those 365 00:11:56,120 --> 00:11:59,880 tools that have occurred over time now 366 00:11:58,600 --> 00:12:01,880 making a python version of this in a 367 00:11:59,880 --> 00:12:03,560 library would be easy and they are out 368 00:12:01,880 --> 00:12:05,600 there you can use them but one of the 369 00:12:03,560 --> 00:12:07,279 real values of pearl pie you can drop me 370 00:12:05,600 --> 00:12:09,360 on to pretty much any server made from 371 00:12:07,279 --> 00:12:11,519 1995 onwards and there's probably going 372 00:12:09,360 --> 00:12:13,120 to be a pearl binary on there somewhere 373 00:12:11,519 --> 00:12:14,560 maybe if we added this to python in the 374 00:12:13,120 --> 00:12:17,279 standard library now it could be 375 00:12:14,560 --> 00:12:19,800 similarly Omni present in 10 376 00:12:17,279 --> 00:12:21,720 years link is short for language 377 00:12:19,800 --> 00:12:24,839 integrated query and it's basically what 378 00:12:21,720 --> 00:12:26,639 if SQL was our API this is most direct 379 00:12:24,839 --> 00:12:28,079 when it's used as a type of omm and that 380 00:12:26,639 --> 00:12:30,760 is definitely the most common use case 381 00:12:28,079 --> 00:12:32,839 for it but C took this even further and 382 00:12:30,760 --> 00:12:35,560 you can build arbitrary providers on top 383 00:12:32,839 --> 00:12:37,000 of link to make it do anything you want 384 00:12:35,560 --> 00:12:38,480 python has taken some baby steps down 385 00:12:37,000 --> 00:12:39,839 this path we have cross Library 386 00:12:38,480 --> 00:12:42,160 standards for data frames and you can 387 00:12:39,839 --> 00:12:44,320 put duck DB on top of those to get SQL 388 00:12:42,160 --> 00:12:45,920 like exploration uh but what if that was 389 00:12:44,320 --> 00:12:47,639 a language syntax that anything could 390 00:12:45,920 --> 00:12:50,079 plug 391 00:12:47,639 --> 00:12:51,519 into call with current continuations 392 00:12:50,079 --> 00:12:53,680 will take some explaining so just bear 393 00:12:51,519 --> 00:12:56,120 with me at a basic level it's a kind of 394 00:12:53,680 --> 00:12:57,720 non-local return like an exception and 395 00:12:56,120 --> 00:12:59,720 indeed we can do a very basic 396 00:12:57,720 --> 00:13:02,680 implementation on this in Python using 397 00:12:59,720 --> 00:13:04,320 exceptions so we take a function we want 398 00:13:02,680 --> 00:13:06,120 to run that function the function will 399 00:13:04,320 --> 00:13:08,279 receive one argument which is itself a 400 00:13:06,120 --> 00:13:10,440 callable when the function wishes to 401 00:13:08,279 --> 00:13:12,079 return it should call that callable with 402 00:13:10,440 --> 00:13:14,480 the parameter being that the value that 403 00:13:12,079 --> 00:13:16,320 it wants to return this alone would be 404 00:13:14,480 --> 00:13:17,959 pretty boring though the real power of 405 00:13:16,320 --> 00:13:20,120 continuations is that in some languages 406 00:13:17,959 --> 00:13:22,920 they can be moved around stored as 407 00:13:20,120 --> 00:13:24,279 variables or even serialized to disk all 408 00:13:22,920 --> 00:13:25,920 allowing you to jump right back to the 409 00:13:24,279 --> 00:13:27,399 point of the code where the continuation 410 00:13:25,920 --> 00:13:29,680 was generated this makes it something 411 00:13:27,399 --> 00:13:31,240 like a structured go-to imagine being 412 00:13:29,680 --> 00:13:32,839 able to save and restore the state of a 413 00:13:31,240 --> 00:13:34,279 generator function as if were any other 414 00:13:32,839 --> 00:13:35,320 object uh I wrote that line but you 415 00:13:34,279 --> 00:13:37,760 don't really have to imagine because 416 00:13:35,320 --> 00:13:39,560 Chris showed us how to do that but what 417 00:13:37,760 --> 00:13:41,560 if it wasn't like 418 00:13:39,560 --> 00:13:44,000 that 419 00:13:41,560 --> 00:13:46,000 um while continuations are mostly 420 00:13:44,000 --> 00:13:47,560 associated with scheme they are very 421 00:13:46,000 --> 00:13:49,800 effectively used in the small talk web 422 00:13:47,560 --> 00:13:51,600 framework Seaside in seide the whole 423 00:13:49,800 --> 00:13:54,480 state of the application is managed via 424 00:13:51,600 --> 00:13:56,399 pickable continuations so in that small 425 00:13:54,480 --> 00:13:58,680 talk code up there that invocation of 426 00:13:56,399 --> 00:14:00,519 Color Picker this is inside a web app so 427 00:13:58,680 --> 00:14:02,160 that with Color Picker is going to 428 00:14:00,519 --> 00:14:04,000 return an HTP response to the client 429 00:14:02,160 --> 00:14:06,040 telling some JavaScript to please open a 430 00:14:04,000 --> 00:14:08,560 modal showing a Color Picker wait for 431 00:14:06,040 --> 00:14:10,360 the user to do a thing get a response 432 00:14:08,560 --> 00:14:11,839 then send that back as another request 433 00:14:10,360 --> 00:14:13,880 up to the server where the server will 434 00:14:11,839 --> 00:14:16,360 unpickle the the continuation and pick 435 00:14:13,880 --> 00:14:18,040 up right where it left off in the code 436 00:14:16,360 --> 00:14:20,399 so this is all the benefits of the 437 00:14:18,040 --> 00:14:23,199 cleanliness of a single page client side 438 00:14:20,399 --> 00:14:25,560 app but in server side 439 00:14:23,199 --> 00:14:27,040 code and because I really love how small 440 00:14:25,560 --> 00:14:29,560 talk does flow control here's a really 441 00:14:27,040 --> 00:14:30,959 rough Port of some of it to python the 442 00:14:29,560 --> 00:14:32,759 short and important version of this 443 00:14:30,959 --> 00:14:36,079 small talk doesn't have special Syntax 444 00:14:32,759 --> 00:14:39,000 for flow control so for example if is a 445 00:14:36,079 --> 00:14:40,360 method of The Bu object and so is while 446 00:14:39,000 --> 00:14:43,000 there's another an example of each of 447 00:14:40,360 --> 00:14:44,800 those up there if you can read them uh 448 00:14:43,000 --> 00:14:46,199 in Practical implementations these don't 449 00:14:44,800 --> 00:14:47,759 actually happen they get compiled into 450 00:14:46,199 --> 00:14:49,600 special constructs because we want code 451 00:14:47,759 --> 00:14:51,480 to run quickly but it's a great example 452 00:14:49,600 --> 00:14:53,560 of doing more with less in language 453 00:14:51,480 --> 00:14:55,880 design and if you want to go even more 454 00:14:53,560 --> 00:14:57,160 minimal you can look at tiny fourths you 455 00:14:55,880 --> 00:14:58,560 can bootstrap a whole language 456 00:14:57,160 --> 00:15:01,079 interpreter with a few hundred bytes of 457 00:14:58,560 --> 00:15:02,560 assembly 20 to 30 keywords from those 458 00:15:01,079 --> 00:15:04,360 you build a basic parser and then an 459 00:15:02,560 --> 00:15:06,839 interpreter Loop and then some more 460 00:15:04,360 --> 00:15:08,000 control flow and then an entire program 461 00:15:06,839 --> 00:15:10,480 fourth Kernels have been written as 462 00:15:08,000 --> 00:15:12,240 small as 400 bytes of machine code 463 00:15:10,480 --> 00:15:14,000 minimalism isn't really a specific goal 464 00:15:12,240 --> 00:15:15,480 of python but it's a good reminder of 465 00:15:14,000 --> 00:15:17,240 how little is needed for a productive 466 00:15:15,480 --> 00:15:18,480 system what would a minimal python look 467 00:15:17,240 --> 00:15:20,480 like what's something that would be just 468 00:15:18,480 --> 00:15:21,720 powerful enough to write all of the rest 469 00:15:20,480 --> 00:15:23,880 of 470 00:15:21,720 --> 00:15:25,600 python another interesting blend of 471 00:15:23,880 --> 00:15:27,720 language features and Frameworks is LL 472 00:15:25,600 --> 00:15:29,920 Lang's open telephony platform or 473 00:15:27,720 --> 00:15:31,959 OTP speciic specifically the supervisor 474 00:15:29,920 --> 00:15:34,279 system earling programs are to use 475 00:15:31,959 --> 00:15:36,720 Python terms a series of interacting 476 00:15:34,279 --> 00:15:38,279 async tasks all running in parallel we 477 00:15:36,720 --> 00:15:40,440 can do that in Python today but what 478 00:15:38,279 --> 00:15:41,880 happens when one of those tasks crashes 479 00:15:40,440 --> 00:15:44,480 it's often difficult to sort out how to 480 00:15:41,880 --> 00:15:45,920 respond exactly OTP applies similar 481 00:15:44,480 --> 00:15:47,920 Concepts from the server and container 482 00:15:45,920 --> 00:15:49,639 management world but to individual tasks 483 00:15:47,920 --> 00:15:51,959 within a complex application we can set 484 00:15:49,639 --> 00:15:53,880 the supervisor to restart a failed task 485 00:15:51,959 --> 00:15:55,279 automatically or have a custom restart 486 00:15:53,880 --> 00:15:57,120 Behavior like waiting a certain amount 487 00:15:55,279 --> 00:15:59,720 of time or we can set up a dependency 488 00:15:57,120 --> 00:16:01,959 tree so that if any in the tree crashes 489 00:15:59,720 --> 00:16:04,040 it restarts the entire set to ensure 490 00:16:01,959 --> 00:16:05,759 consistency this is how llang builds 491 00:16:04,040 --> 00:16:07,519 incredibly High uptime systems like 492 00:16:05,759 --> 00:16:09,680 phone switches without magical 493 00:16:07,519 --> 00:16:11,680 programmers who don't write 494 00:16:09,680 --> 00:16:13,319 bugs this could mesh well with the sub 495 00:16:11,680 --> 00:16:15,040 interpreter work we looked at before and 496 00:16:13,319 --> 00:16:17,079 in fact Go's co- routines and channels 497 00:16:15,040 --> 00:16:18,759 were heavily influenced by otp's server 498 00:16:17,079 --> 00:16:20,120 and mailbox model there could be a 499 00:16:18,759 --> 00:16:21,680 future where we have something like task 500 00:16:20,120 --> 00:16:25,040 groups not just as a synchronization 501 00:16:21,680 --> 00:16:27,120 mechanism but also for runtime 502 00:16:25,040 --> 00:16:28,560 supervision python has made incredible 503 00:16:27,120 --> 00:16:29,839 inroads as being the language of choice 504 00:16:28,560 --> 00:16:31,639 for s scientific Computing and data 505 00:16:29,839 --> 00:16:33,360 science but in almost every one of those 506 00:16:31,639 --> 00:16:35,319 applications you'll find Fortran under 507 00:16:33,360 --> 00:16:37,120 the hood most people think of Fortran as 508 00:16:35,319 --> 00:16:39,639 part of our technical past but it's very 509 00:16:37,120 --> 00:16:41,680 much alive and for good reason forr is 510 00:16:39,639 --> 00:16:43,639 almost perfectly designed to be able to 511 00:16:41,680 --> 00:16:45,519 write complex mathematical algorithms 512 00:16:43,639 --> 00:16:47,680 which can be compiled to the fastest 513 00:16:45,519 --> 00:16:49,319 possible implementation on each platform 514 00:16:47,680 --> 00:16:51,040 so rather than maintaining a separate 515 00:16:49,319 --> 00:16:53,959 linear algebra implementation in 516 00:16:51,040 --> 00:16:55,880 assembly on every OS we have a single 517 00:16:53,959 --> 00:16:58,319 one in Fortran and we trust in the tool 518 00:16:55,880 --> 00:17:00,319 chain even C can't compile things as 519 00:16:58,319 --> 00:17:02,360 effectively 4 Trend in a lot of cases 520 00:17:00,319 --> 00:17:04,799 despite most of us thinking of C as the 521 00:17:02,360 --> 00:17:06,839 lowest level thing out there specialized 522 00:17:04,799 --> 00:17:09,039 use cases need specialized 523 00:17:06,839 --> 00:17:11,160 tools and while Fortran is still alive 524 00:17:09,039 --> 00:17:12,720 and well cobal is mostly though not 525 00:17:11,160 --> 00:17:14,799 entirely in the rearview mirror at this 526 00:17:12,720 --> 00:17:16,120 point but like we talked about with PHP 527 00:17:14,799 --> 00:17:17,760 it's fun to look at language features 528 00:17:16,120 --> 00:17:19,919 that grow from a tool with a single 529 00:17:17,760 --> 00:17:21,360 primary purpose in Cobalt I think the 530 00:17:19,919 --> 00:17:24,199 most interesting part is the data 531 00:17:21,360 --> 00:17:26,439 division in modern terms every Cobalt 532 00:17:24,199 --> 00:17:28,199 program carries around the schemas of 533 00:17:26,439 --> 00:17:29,520 the databases it expects to read from 534 00:17:28,199 --> 00:17:30,640 and write to 535 00:17:29,520 --> 00:17:32,280 while these days it would more often be 536 00:17:30,640 --> 00:17:33,880 a network API rather than a structured 537 00:17:32,280 --> 00:17:35,400 file on disk We have basically the same 538 00:17:33,880 --> 00:17:37,559 problems to solve with producers and 539 00:17:35,400 --> 00:17:38,799 consumers of data agreeing on schemas 540 00:17:37,559 --> 00:17:40,840 while still allowing that schema to 541 00:17:38,799 --> 00:17:42,520 evolve over time Cobalt's implementation 542 00:17:40,840 --> 00:17:44,200 isn't perfect it comes from a time where 543 00:17:42,520 --> 00:17:46,120 those schema changes were expected to 544 00:17:44,200 --> 00:17:47,440 take months instead of hours but I've 545 00:17:46,120 --> 00:17:49,160 worked on a lot of projects that are 546 00:17:47,440 --> 00:17:50,799 decades newer and have substantially 547 00:17:49,160 --> 00:17:53,000 worse schem of 548 00:17:50,799 --> 00:17:54,559 management homomorphic encryption is 549 00:17:53,000 --> 00:17:56,120 probably the most out there of all these 550 00:17:54,559 --> 00:17:58,600 it's barely even a programming feature 551 00:17:56,120 --> 00:18:00,919 and more of a cool math trick the idea 552 00:17:58,600 --> 00:18:02,400 is doing computation on encrypted values 553 00:18:00,919 --> 00:18:04,200 without decrypting them so this means 554 00:18:02,400 --> 00:18:06,000 that you have data processing code that 555 00:18:04,200 --> 00:18:07,880 takes encrypted data that it does not 556 00:18:06,000 --> 00:18:10,000 have the decryption keys 557 00:18:07,880 --> 00:18:11,440 for the core way that this works is 558 00:18:10,000 --> 00:18:13,919 instead of thinking of your code AS 559 00:18:11,440 --> 00:18:15,520 lines of code compiling to machine 560 00:18:13,919 --> 00:18:17,159 instructions that are evaluated on some 561 00:18:15,520 --> 00:18:18,760 kind of virtual machine we're instead 562 00:18:17,159 --> 00:18:21,080 going to compile your code into 563 00:18:18,760 --> 00:18:22,600 effectively a virtual Asic digital 564 00:18:21,080 --> 00:18:24,960 circuit Gates that'll Implement a 565 00:18:22,600 --> 00:18:26,240 homeomorphic encryption flow given those 566 00:18:24,960 --> 00:18:27,840 constraints there are of course very 567 00:18:26,240 --> 00:18:29,280 hard limitations in the kind of 568 00:18:27,840 --> 00:18:31,799 computation that you can do and also 569 00:18:29,280 --> 00:18:33,320 it's still pretty slow but in an 570 00:18:31,799 --> 00:18:34,640 increasingly privacy conscious World 571 00:18:33,320 --> 00:18:35,880 maybe this is worth more of a look from 572 00:18:34,640 --> 00:18:38,480 all of 573 00:18:35,880 --> 00:18:40,000 us I started off by saying I wasn't 574 00:18:38,480 --> 00:18:42,080 aiming for you to go off and turn these 575 00:18:40,000 --> 00:18:44,400 ideas into peps and while that is true I 576 00:18:42,080 --> 00:18:45,480 wish it wasn't a few of these ideas 577 00:18:44,400 --> 00:18:47,400 could probably be prototyped in 578 00:18:45,480 --> 00:18:49,320 libraries and gain some traction there 579 00:18:47,400 --> 00:18:51,480 but most of these to really succeed they 580 00:18:49,320 --> 00:18:52,679 would need a core language change the 581 00:18:51,480 --> 00:18:54,200 process for that has improved over the 582 00:18:52,679 --> 00:18:56,360 years but the steering Council has to 583 00:18:54,200 --> 00:18:58,440 walk a really fine line adding anything 584 00:18:56,360 --> 00:19:00,720 into cpython is a big commitment it 585 00:18:58,440 --> 00:19:02,559 can't just be experimental and it'll go 586 00:19:00,720 --> 00:19:04,440 away in a little bit so this leaves us 587 00:19:02,559 --> 00:19:05,799 in kind of a bind to get peer support 588 00:19:04,440 --> 00:19:07,640 for a change we need to prove that it's 589 00:19:05,799 --> 00:19:08,919 a good idea and for that we need people 590 00:19:07,640 --> 00:19:10,240 to be able to play with it but for 591 00:19:08,919 --> 00:19:12,039 people to be able to play with it we 592 00:19:10,240 --> 00:19:13,400 need to get a Core change in and we 593 00:19:12,039 --> 00:19:14,480 can't do that until we have peer support 594 00:19:13,400 --> 00:19:17,120 and now we're 595 00:19:14,480 --> 00:19:18,600 stuck macros are a language construct to 596 00:19:17,120 --> 00:19:20,240 allow metaprogramming inside the 597 00:19:18,600 --> 00:19:21,840 language itself adding a new 598 00:19:20,240 --> 00:19:23,480 experimental syntax or changing some 599 00:19:21,840 --> 00:19:26,039 syntax that's already there or writing 600 00:19:23,480 --> 00:19:27,400 your code in rout 13 the sky the limit 601 00:19:26,039 --> 00:19:30,159 the two best places to look for ideas 602 00:19:27,400 --> 00:19:31,600 about macros are rust and lisp C does 603 00:19:30,159 --> 00:19:33,120 heavily feature macros but it takes a 604 00:19:31,600 --> 00:19:34,799 much less structured approach treating 605 00:19:33,120 --> 00:19:37,000 source code more as just text to be 606 00:19:34,799 --> 00:19:38,919 templated uh and that does technically 607 00:19:37,000 --> 00:19:40,960 work but Lis and rust show us a deeper 608 00:19:38,919 --> 00:19:43,200 power defining macros in terms of the 609 00:19:40,960 --> 00:19:44,720 symbols of a language but not its syntax 610 00:19:43,200 --> 00:19:47,080 so that we can create our 611 00:19:44,720 --> 00:19:50,360 own python does have a proposed macro 612 00:19:47,080 --> 00:19:52,039 system heavily influenced by rusts but 613 00:19:50,360 --> 00:19:53,600 it has fallen into the same trap as we 614 00:19:52,039 --> 00:19:54,960 were trying to escape by having a macro 615 00:19:53,600 --> 00:19:56,720 system in the first place and has 616 00:19:54,960 --> 00:19:59,360 received little discussion over the 617 00:19:56,720 --> 00:20:00,880 years I want to talk about lisp does 618 00:19:59,360 --> 00:20:02,480 macros before we can do that we need to 619 00:20:00,880 --> 00:20:04,039 talk about how lisp code is structured 620 00:20:02,480 --> 00:20:05,720 and before that we need to talk about 621 00:20:04,039 --> 00:20:07,799 how python code is structured so like 622 00:20:05,720 --> 00:20:09,679 most other languages Python's parer 623 00:20:07,799 --> 00:20:11,360 produces an abstract syntax tree this 624 00:20:09,679 --> 00:20:13,360 isn't bite code this is a highly 625 00:20:11,360 --> 00:20:15,799 structured representation of your code 626 00:20:13,360 --> 00:20:17,559 text and it's ready to be handed off to 627 00:20:15,799 --> 00:20:20,000 the compiler and other layers for 628 00:20:17,559 --> 00:20:21,960 forther execution or or 629 00:20:20,000 --> 00:20:24,400 optimization lisp does have something 630 00:20:21,960 --> 00:20:26,600 like that but it's way simpler lisp has 631 00:20:24,400 --> 00:20:28,840 almost no actual syntax everything in 632 00:20:26,600 --> 00:20:30,080 lisp is one of two things an atom which 633 00:20:28,840 --> 00:20:32,720 is their word for a symbol which we 634 00:20:30,080 --> 00:20:34,919 talked about before or a pair of two 635 00:20:32,720 --> 00:20:36,679 things Each of which can again be either 636 00:20:34,919 --> 00:20:39,000 an atom or a pair of two 637 00:20:36,679 --> 00:20:40,799 things this is just the barest bit of 638 00:20:39,000 --> 00:20:43,080 structure but it also means that macros 639 00:20:40,799 --> 00:20:44,400 and lisp can do almost anything as long 640 00:20:43,080 --> 00:20:46,320 as the input and output are both s 641 00:20:44,400 --> 00:20:47,799 expressions and basically everything can 642 00:20:46,320 --> 00:20:49,960 be an S 643 00:20:47,799 --> 00:20:52,559 expression the way def macro Works in 644 00:20:49,960 --> 00:20:54,440 lisp so we've parsed the code into an S 645 00:20:52,559 --> 00:20:56,159 expression and something is going to 646 00:20:54,440 --> 00:20:58,640 start spidering out over that code 647 00:20:56,159 --> 00:21:01,320 looking for special atoms def macro it's 648 00:20:58,640 --> 00:21:02,840 self is a special atom and it takes the 649 00:21:01,320 --> 00:21:05,520 name the parameters and the body of the 650 00:21:02,840 --> 00:21:07,640 macro and it registers that name as a 651 00:21:05,520 --> 00:21:09,480 special atom and it's going to continue 652 00:21:07,640 --> 00:21:11,440 spidering out of the code if it sees 653 00:21:09,480 --> 00:21:13,679 that name it'll say it's a special atom 654 00:21:11,440 --> 00:21:15,640 I know what to do I will go find the 655 00:21:13,679 --> 00:21:17,000 body of that macro I will take the 656 00:21:15,640 --> 00:21:18,960 arguments which remember are still 657 00:21:17,000 --> 00:21:21,480 symbolic the code isn't running it's 658 00:21:18,960 --> 00:21:23,400 just been parsed so we have the symbolic 659 00:21:21,480 --> 00:21:25,279 arguments we'll slam them into something 660 00:21:23,400 --> 00:21:27,279 we'll evaluate the body of the macro 661 00:21:25,279 --> 00:21:28,720 we'll get back another expression and 662 00:21:27,279 --> 00:21:31,360 we'll just plug it right in where 663 00:21:28,720 --> 00:21:33,480 macro's special atom 664 00:21:31,360 --> 00:21:35,440 was the important takeaway here is that 665 00:21:33,480 --> 00:21:37,039 macros break the usual flow of things 666 00:21:35,440 --> 00:21:39,120 usually our code is going to move 667 00:21:37,039 --> 00:21:41,039 linearly from tokenizing to parsing to 668 00:21:39,120 --> 00:21:42,520 compiling to executing there's a couple 669 00:21:41,039 --> 00:21:44,400 of newer steps in there you'll see jit 670 00:21:42,520 --> 00:21:46,120 compilers and stuff but the key with 671 00:21:44,400 --> 00:21:48,880 macros is they put a little subl Loop 672 00:21:46,120 --> 00:21:50,320 inside the parser step compiling and 673 00:21:48,880 --> 00:21:52,200 executing the body of the macro and 674 00:21:50,320 --> 00:21:53,960 returning the output to the parser this 675 00:21:52,200 --> 00:21:55,400 may seem like a minor thing but it's the 676 00:21:53,960 --> 00:21:57,320 pressure relief valve that lets us 677 00:21:55,400 --> 00:22:00,480 extend the parser without explicit 678 00:21:57,320 --> 00:22:02,320 support from the language 679 00:22:00,480 --> 00:22:04,080 rust has two main types of macros 680 00:22:02,320 --> 00:22:05,559 procedural macros are the equivalent of 681 00:22:04,080 --> 00:22:07,159 what we saw in lisp uh there's a couple 682 00:22:05,559 --> 00:22:08,880 flavors depending on exactly what kind 683 00:22:07,159 --> 00:22:10,919 of parsing you want to hook into but 684 00:22:08,880 --> 00:22:12,559 they all take a stream of tokens and 685 00:22:10,919 --> 00:22:14,400 they return a stream of tokens which 686 00:22:12,559 --> 00:22:15,559 means they can do basically anything 687 00:22:14,400 --> 00:22:17,360 they can even operate on things that 688 00:22:15,559 --> 00:22:19,159 aren't valid rust syntax in the first 689 00:22:17,360 --> 00:22:20,480 place and that's cool sometimes but most 690 00:22:19,159 --> 00:22:22,559 of the time when we're writing a rust 691 00:22:20,480 --> 00:22:24,559 macro we just want to slightly tweak the 692 00:22:22,559 --> 00:22:25,919 syntax that's already there and we use 693 00:22:24,559 --> 00:22:27,120 declarative macros with this thing 694 00:22:25,919 --> 00:22:30,080 called macro 695 00:22:27,120 --> 00:22:31,960 rules declar macros are very similar to 696 00:22:30,080 --> 00:22:33,760 Python's match case statements but again 697 00:22:31,960 --> 00:22:35,840 the code isn't running it's just been 698 00:22:33,760 --> 00:22:38,400 parsed so the parameters are symbolic 699 00:22:35,840 --> 00:22:41,000 expressions or types and the code block 700 00:22:38,400 --> 00:22:42,760 is returned rather than being executed 701 00:22:41,000 --> 00:22:44,760 it does support a little bit of like 702 00:22:42,760 --> 00:22:46,400 templating expansion basically although 703 00:22:44,760 --> 00:22:48,440 I can't really go into the full power of 704 00:22:46,400 --> 00:22:50,799 this in 30 seconds so hopefully this 705 00:22:48,440 --> 00:22:52,320 gives you just the barest idea the core 706 00:22:50,799 --> 00:22:54,039 idea is that basically anything can be 707 00:22:52,320 --> 00:22:56,880 prototyped inside a macro without 708 00:22:54,039 --> 00:23:00,200 explicit support from the rust 709 00:22:56,880 --> 00:23:01,520 team so why at all of this personally I 710 00:23:00,200 --> 00:23:03,279 just think it's fun to see what else is 711 00:23:01,520 --> 00:23:04,720 out there but if that's not enough I 712 00:23:03,279 --> 00:23:06,640 certainly hope that learning about these 713 00:23:04,720 --> 00:23:09,120 patterns and systems can help you better 714 00:23:06,640 --> 00:23:10,640 organize your code and apis in python or 715 00:23:09,120 --> 00:23:11,919 at least shows you what other tools are 716 00:23:10,640 --> 00:23:13,960 out there and in the end that makes us 717 00:23:11,919 --> 00:23:16,559 all better developers thank you very 718 00:23:13,960 --> 00:23:16,559 much any 719 00:23:19,080 --> 00:23:24,200 questions thank you Noah we do have time 720 00:23:22,000 --> 00:23:24,200 for 721 00:23:26,200 --> 00:23:30,440 questions okay we have a we have a 722 00:23:28,159 --> 00:23:30,440 question 723 00:23:30,960 --> 00:23:35,919 hello um of those lists you mentioned 724 00:23:34,400 --> 00:23:38,159 this is python ideas but not python 725 00:23:35,919 --> 00:23:40,279 ideas which of those python ideas do you 726 00:23:38,159 --> 00:23:42,440 think would be most likely to be 727 00:23:40,279 --> 00:23:43,880 implemented or to to to actually land in 728 00:23:42,440 --> 00:23:46,440 core and which one do you think would be 729 00:23:43,880 --> 00:23:48,360 the highest yield if it were reflecting 730 00:23:46,440 --> 00:23:49,840 on Chris's comments about the fact that 731 00:23:48,360 --> 00:23:52,360 generators were implemented which then 732 00:23:49,840 --> 00:23:54,960 made all these other things possible 733 00:23:52,360 --> 00:23:57,120 um I think safe navigation I mean I 734 00:23:54,960 --> 00:23:58,559 wasn't kidding that I think they are it 735 00:23:57,120 --> 00:24:00,480 is it is a mistake that we have not 736 00:23:58,559 --> 00:24:03,840 included them um I think that would 737 00:24:00,480 --> 00:24:05,320 probably be the highest value one uh it 738 00:24:03,840 --> 00:24:08,039 it makes it much more likely that people 739 00:24:05,320 --> 00:24:11,520 will write good error checking in deeply 740 00:24:08,039 --> 00:24:13,080 Nest exploring deeply nested objects um 741 00:24:11,520 --> 00:24:14,320 which is a thing that a lot of code 742 00:24:13,080 --> 00:24:16,480 these days does especially as we're 743 00:24:14,320 --> 00:24:18,240 trying to push more people into using 744 00:24:16,480 --> 00:24:20,840 structured typing things like data 745 00:24:18,240 --> 00:24:22,760 classes or adders we can't just call do 746 00:24:20,840 --> 00:24:25,200 getet on there and assume that it'll 747 00:24:22,760 --> 00:24:26,360 figure itself out um so I think safe 748 00:24:25,200 --> 00:24:29,440 naav operators for the second one the 749 00:24:26,360 --> 00:24:33,880 one that is most likely I I don't even 750 00:24:29,440 --> 00:24:37,679 know anymore uh the the the core team is 751 00:24:33,880 --> 00:24:37,679 an inscrutable box to a lot of 752 00:24:42,080 --> 00:24:47,720 us uh somebody is pointing that way 753 00:24:44,840 --> 00:24:47,720 pointing 754 00:24:55,080 --> 00:24:59,679 yep yeah hi um so you talked about what 755 00:24:58,399 --> 00:25:01,240 you'd like to see added to the language 756 00:24:59,679 --> 00:25:02,919 I'm interested if you've got any ideas 757 00:25:01,240 --> 00:25:04,720 of things you'd like to see removed 758 00:25:02,919 --> 00:25:07,039 maybe something that's non-standard 759 00:25:04,720 --> 00:25:08,600 compared to other languages that you'd 760 00:25:07,039 --> 00:25:10,679 like to see standardized across the 761 00:25:08,600 --> 00:25:13,080 board 762 00:25:10,679 --> 00:25:14,480 uh in in Practical terms I would like 763 00:25:13,080 --> 00:25:18,279 nothing removed because I remember the 764 00:25:14,480 --> 00:25:20,480 Python 3 uh migration period and 765 00:25:18,279 --> 00:25:22,880 breaking compat like that should never 766 00:25:20,480 --> 00:25:24,279 happen again um and I'm pretty sure that 767 00:25:22,880 --> 00:25:26,799 we have all convinced ourselves that it 768 00:25:24,279 --> 00:25:28,640 never will again so in Practical terms I 769 00:25:26,799 --> 00:25:31,840 think anything that has been out there 770 00:25:28,640 --> 00:25:34,760 that ship has sailed 771 00:25:31,840 --> 00:25:37,480 um if I if I could wave a magic wand 772 00:25:34,760 --> 00:25:38,600 though uh the one I actually ask that 773 00:25:37,480 --> 00:25:40,760 question when I'm doing interviews the 774 00:25:38,600 --> 00:25:42,880 big one would be packaging uh I think no 775 00:25:40,760 --> 00:25:45,200 one is under any impression that python 776 00:25:42,880 --> 00:25:49,240 packaging is in an amazing State um I 777 00:25:45,200 --> 00:25:52,039 would make that not I would I would make 778 00:25:49,240 --> 00:25:54,399 python push all of that into a better 779 00:25:52,039 --> 00:25:55,720 Direction um if I could remove one thing 780 00:25:54,399 --> 00:25:57,760 it would probably be multiple 781 00:25:55,720 --> 00:26:00,480 inheritance I think it does more harm 782 00:25:57,760 --> 00:26:02,919 than good and always has um class 783 00:26:00,480 --> 00:26:04,960 decorators should have been the correct 784 00:26:02,919 --> 00:26:06,880 solution there and I think most people 785 00:26:04,960 --> 00:26:08,480 these days they use that instead but 786 00:26:06,880 --> 00:26:11,240 multiple inheritance just breaks a lot 787 00:26:08,480 --> 00:26:13,279 of stuff in mysterious ways uh my 788 00:26:11,240 --> 00:26:15,080 understanding of that is that g read a 789 00:26:13,279 --> 00:26:16,559 paper thought it was really cool and 790 00:26:15,080 --> 00:26:18,600 implemented it that night and it was 791 00:26:16,559 --> 00:26:20,440 early on enough in the the python 792 00:26:18,600 --> 00:26:23,080 ecosystem that no one could tell him no 793 00:26:20,440 --> 00:26:25,080 so he just merged it um basically 794 00:26:23,080 --> 00:26:26,600 because he thought it was shiny which 795 00:26:25,080 --> 00:26:29,600 not really how we do language design 796 00:26:26,600 --> 00:26:29,600 anymore 797 00:26:30,159 --> 00:26:35,399 hi I'm one of the duck DB devs I'm 798 00:26:32,200 --> 00:26:37,120 curious to see what you would what you 799 00:26:35,399 --> 00:26:39,039 think that would look like integrating 800 00:26:37,120 --> 00:26:41,600 duck DB or another SQL engine into 801 00:26:39,039 --> 00:26:45,159 python itself uh probably a lot like it 802 00:26:41,600 --> 00:26:46,679 does in C um you know link there is a 803 00:26:45,159 --> 00:26:48,840 special keyword I think it is literally 804 00:26:46,679 --> 00:26:50,360 just select because they wanted to model 805 00:26:48,840 --> 00:26:53,039 it off SQL because that's what most 806 00:26:50,360 --> 00:26:54,880 people know and once it sees that 807 00:26:53,039 --> 00:26:57,000 keyword it moves into an alternate 808 00:26:54,880 --> 00:27:00,559 parsing mode that again very closely 809 00:26:57,000 --> 00:27:02,320 resembles SQL and it would just probably 810 00:27:00,559 --> 00:27:04,840 the simplest version is just that would 811 00:27:02,320 --> 00:27:06,840 be a very fancy quoting syntax that 812 00:27:04,840 --> 00:27:08,000 would just hand that off to something 813 00:27:06,840 --> 00:27:09,760 else there would be a provider 814 00:27:08,000 --> 00:27:12,279 registered um we've talked about this I 815 00:27:09,760 --> 00:27:14,640 think uh a bit with tagged strings of 816 00:27:12,279 --> 00:27:17,120 various types um being able to register 817 00:27:14,640 --> 00:27:20,080 like we have F strings and R strings you 818 00:27:17,120 --> 00:27:23,440 could have a duck string um and that 819 00:27:20,080 --> 00:27:25,080 would certainly be a lot closer uh but I 820 00:27:23,440 --> 00:27:27,440 I like things like typechecking and it 821 00:27:25,080 --> 00:27:29,600 would be a lot closer to being a core 822 00:27:27,440 --> 00:27:32,640 language Fe if it was more deeply 823 00:27:29,600 --> 00:27:32,640 exposed as part of the 824 00:27:37,360 --> 00:27:41,159 language thank you very much I think 825 00:27:39,399 --> 00:27:45,640 that's 826 00:27:41,159 --> 00:27:45,640 it give it up to Noah