All right, so I'm going to kick off this session on the unexpected demise of open source libraries, software, and well, a bunch of other things that you'll learn in a few minutes.  As a teenager, I guess like a bunch of people here in this room, I was able to connect using open source software, the movement itself, everything with like minded individuals, people who are thinking like me, we're sharing code, we're building things, we're able to experiment and have access to a safe environment, safe playground of our own. It enabled me to learn, improve upon my code and others and learn from them. And it gave me access to software that I would otherwise not have access to, essentially providing me for opportunities for growth, as well as opportunities to make an impact in the world itself. Now, I bet you're probably asking and trying to reminisce, you know, what was your first open source project? Were you involved in one? And so here's mine. This is, you know, the why I'm saying this. My open source project was back then 2007. Started this called Daleradios, which was, this is like my pillar project that says the everything of basically PHP, spaghetti code together with HTML, a bunch of security vulnerabilities in it and, you know, a lot of fun as a teenager, not a teenager at this point, but doing all of this in the open. This is a software that basically manages radio servers, right? It's a web application thing. And it was a very niche thing. It was like for Wi-Fi hotspot, you know, back then when the internet wasn't as available as it is today, it allowed those hotspot Wi-Fi systems to basically make a living through essentially being able to provide this Wi-Fi service with, you know, printing a username and password and making this possible. It grew to over half a million downloads from straight, this is straight from SourceForge, so it doesn't count any clones of like, you know, subversion back then or Git today and so on. So people literally went on to SourceForge, downloaded the project and created a business or something of a Wi-Fi hotspot with it. For me, the impact that I was showing, was witnessing back then was at one point I was thinking, hey, I'll go to LinkedIn and see, you know, who uses this software. And it was amazing essentially to see people who had this as part of their curriculum, right? Like as part of their experience. Like they are now Delaradius operators. So this is how I made my, I would say impact. But as you can see, we're talking about the unexpected demise of open source software, right? This is mine. This is my example. No different. I have stopped maintaining it after about five or six years. I'm no longer actively maintaining it. And you could see that obviously the SourceForge is also like less popular to these days. But it is essentially kind of unmaintained, deprecated. It leaves off today of Git and GitHub. But it's not as maintained as it is. So how does that affect and impact every one of us? My name is Irantal. Thank you for coming to my session. I'm a developer advocate at SNCC where we build developer tooling for developers, help them stay secure, all of those kind of things. I'm very active in open source related movements, anything on the JavaScript ecosystem like the Node.js, OpenJS Foundation, OWASP and things like that. Very happy to collaborate and share ideas after this talk if you have anything about this that you're interested of. But truly why we're here is and how this is connected to licensing is an interesting perspective of, you know, how open source kind of maybe, I think, perhaps just my opinion, but developed and like why it became so popular. From 2015, this is usually people in this conference show an up to the right growth of supply chain security vulnerabilities. Well, this is not that one, but it does show you an example of the affiliation of specific licenses in open source. And maybe perhaps an interesting insight here is the fact that the MIT license, which is known to be very permissive license, is catching up a bunch of those projects. That bunch is specifically 45% of them. In a more recent study by Tidely, which is another company working with open source maintainers and developers and, you know, doing all of that, they actually cite that about 90% of projects with known licenses just because there are some projects out there in libraries that do not have a license attached to them. That's a red flag. But aside from that, the fact that we know that 90% of software libraries, again, with known licenses are using permissive licenses is also interesting. This is, for example, on NPM, 1.8 million packages out of 2.2 million of them basically telling you, hey, you can take my license and do whatever you want with it. So are we taking open source for granted? See a few faces here. Usually people nod and agree and sigh because we all kind of feel maybe we have. But really what happens when we do is kind of the rigs that we're taking and what's going on, what will be there tomorrow. And so this is where I'm showing you a few stories that I have on this topic. One is the story of Left Pad. If you're within the JavaScript ecosystem, you might have heard about it maybe in the news. I'll go into why it happened briefly, but then we can move to other stories from different ecosystems as well. For example, this story of Left Pad, that's the name of library that explains of how legal actions taken by a commercial body towards one open source developer resulted in breaking thousands of projects and builds and CIs across the ecosystem, such as Node.js and Babel and very, very popular projects. So how does that happen? Left Pad is, by the way, a very small library, footprint of 11 lines of code, depending on which version you look at, but that's essentially the gist of it. So let's talk about the typical software development team that some people might have in their heads when they're thinking about their team building products or whatever. So you think that the traditional first party code kind of dev team is they write, they sit, write code, or they don't magically write code. They need that extra magic that's called coffee. It goes in. They drink it. Magically, code goes out. So they do this all the day. Developers are like weird people, but we love them. We're part of them. We are developers ourselves, so we kind of understand how this works. They also do some other things to build their code. They're not always inventing it from scratch. That would be kind of like missing the point a lot. They are using a lot of open source software that other developers have built, so they do not need to build it themselves, which so far I probably haven't told you anything new. But perhaps an interesting insight is who are the maintainers behind those packages? What happens if they disappear tomorrow? What happens if their projects disappear tomorrow? Here's one story. This developer is part of your development team if you're building JavaScript projects. Do you know Azir? Let's get to meet Azir. He is part of your development team. Let's see why. Azir maintains a package called KIKNPM package, one of those two million packages on the ecosystem. He's the maintainer of other packages, but at the moment, who cares? Just KIK is the story here. But apparently, he attracted the attention of some corporate lawyers. Interesting. Why? Well, I didn't notice. I bet Azir didn't notice either. But apparently, KIK is also the name of some popular instant messaging app that has gone commercial or whatever. NPM has stepped in as the registry of the governing body or so of all of those millions of packages and stepped in and said, hey, would you want to rename your package so this other bigger commercial body can take the name of a brand that they use and so on. Azir didn't want to do that and he essentially refused to relinquish any control of the package or change the name. And so getting concerned of lawsuits and all of those legal actions that some companies have to their disposals versus us as maintainers who are essentially doing this as non-commercial work. And NPM has kind of like failed to kind of bridge what would be an okay remediation or mitigation of the story. What happened is they have forcibly removed control of KIK and pushed out to that commercial body. And as an act of protest, Azir said, I am going to remove all of my modules from NPM and I do not want to push any open source code to this registry anymore. Went on and did that. He also maintains 250 other node modules as we've just said before. One of those is apparently Left Pad. It's 11 lines of code but it gets 2.5 million downloads and it broke thousands of builds and CI ecosystems the moment this was gone. You can imagine your team's push code. CI kicks in, builds the software, downloads from NPM, all of those NPM packages. One does not exist anymore. 404. Everything breaks. Everyone rushed to figure out what to do with this. This has some specific security interesting concerns. For example, what happened if that Left Pad name doesn't exist anymore? Could I as a malicious actor now quickly publish a malicious package and add it and now it's published and those take it? So this brought a bunch of new learnings on how the ecosystem and the registry actually needs to cope with cases like this. For us as maybe corporates or like people who depend on this from the consumer side of things, there are other learnings that we could take in. One of them was the fact that many companies, many teams and organizations who build upon open source code were not actually using one of those ways of having an internal private proxy and internal registry for them not just to have their own IP of private packages that they maintain but also to essentially have a bridge, have kind of like this caching layer which seems very, very a mundane thing and an obvious thing to do when you build systems but how about for your artifacts of open source packages? So Verdaccio is one of them. Essentially what it does, you would want to be able to run an NPM install with one of the package managers. This shows PNPM as an example. It goes to the NPM registry and fetches library and give it to you. So far so good but there's no caching here. So Verdaccio came into the picture. It's an open source project. It exists also for quite a while before the story and so on. It's, you know, pluggable. It's open source. It has zero dependencies. The idea is that you use this in order to essentially be able to cache dependencies. And so then your workflow is a bit different. Your team, whichever NPM package manager they use, they essentially move it to Verdaccio as a regular proxy. It goes out to the upstream registries, which of those that you maintain or configure and brings it back and you can spin it off as an NPM package as a standalone CLI or as a Docker image, if that's more easier for you to maintain. So one of the learnings of organizations was essentially to adopt a tool like Verdaccio for those dev terms. So that's how Left Pad got into the incident whole of fame kind of story. But we're moving on to another story. This one is a story of how you would essentially perhaps remove yourself from the open source ecosystem in order to make the world a better place. Let me ask you here. How many people here who would have been running successful open source projects, hundreds of contributions, thousands of dependent projects, right? Millions of downloads. It's super successful, but you would feel very much obligated to just stop, just remove it, stop maintaining it, make it unavailable so that your carbon footprint on the earth would essentially get lowered, would perhaps be non-existent. This is the story of that kind of maintainer. He was brave enough to kind of like put his access on the sidelines for perhaps a greener planet earth. Meet François. Back in 2011, he created the Faker Library on the PHP ecosystem. Essentially, the Faker Library as its name is a useful tool for developers because when we need to create tests, we need to use some kind of maybe random data. For example, if we're needing values like first name, last name, countries, whatever to fill a form in a database, seeding data, whatever, we might need a way to generate this automatically. Therefore, this package is called Faker, very genius here. He created this project back then. It of course grew in success. It became kind of like a very popular project on the PHP ecosystem. It got specific even extensions to Python and other kind of like SDKs in other languages, JavaScript included which we'll talk about next. It had a bunch of like contributions in terms of the data that it actually faked. It grew in support of what it could fake. It could fake phone numbers and hello messages in different languages. It really provided you plethora of strings or metadata that you could actually use as a way to fake a data if you need it to. As a dev tooling dependency, if you used it, it's not as big in size. It perhaps have weighted something like three megabytes if you size the whole thing up, which if you think about it, it's not an issue like you download VS code or whatever and that's like hundreds or megabytes and electron ops or whatever. No one thinks about this, but by 2019, this grew up to 120 million downloads overall. So many projects, so many dependent projects and contributors part of this. At this point, we are moving on to figuring out something that's like very important to us ourselves. How often are you considering the fact that the size of the software you use is actually something to think about, to be concerned of? Aside from say front end performance optimizations, which is a whole different topic, but about the consumption of the software itself. We just mentioned the use of Verdatio and caching registries for things like being able to have deterministic installs and no surprises on the network and stuff like that, but this wasn't due to the size overall. It was for other reasons. So here, for Ensoir found this, I would say, inefficient problematic issues with his dependency. And over the years, he noted that he had probably kind of attributed something like emitted essentially, something like 11 metric tons of CO2 equivalent, you know, the carbon footprint.  With that, we have to wonder what happens next to Faker PHP library. He had maintained other popular libraries before. One of them is Propel. It's a database or MSQL database kind of extension. And he had really bad experience handing this over when he wanted to move over from Propel and start a new project and not maintain it anymore. It was so weird, so bad experience that the gist of it was the following, right? He went to his friend and said, hey, could you please maintain Propel for me? Friend said, yes. After a while, that friend handed it off to his friend and said, hey, would you want to maintain Propel for me? Said, yes.  I'm going to rewrite it. Six years after, no rewrite. Of course, nothing really happens. And that's kind of like the end of the story there for the SWAT list, who had learned that handing over open source projects is also nothing is a thing to do, thinking about legacy and all of those kind of things, the legacy of the project. So he archived the project, said to everyone goodbye. As with open source, the GitHub repository goes. No new releases, no new pull requests for Faker. We're already at the point of the story where he decided not to maintain this anymore. It still continues to function unlike the composer, the registry, the library where you could still download it, but essentially there's no new development going on there. And so kind of like he left it with a note of, as it is with open source, people are still afraid to fork it, create a new project. Of course, if you do that, you essentially, for Faker, for example, you lose all of the, I would say, the currency of open source, all of the stars and the popularity and everything around it with GitHub and things like that. So this was also his ending note for new maintainers, hopefully for them it works out better. Some learnings here. One is appreciating maintainers. They spend a lot of time, they try to figure out ways to be able to be constructive to the ecosystem, but not just the ecosystem itself, but maybe to the planet as well, making things better. So perhaps helping support climate crisis is something we should all think about. Our third and last story for today is going to be a recent one that had also caused a lot of breakage and interesting different opinions from the ecosystem of different folks, depending on where you're coming from exactly there. So we are all using open source software here. How many times have we considered about giving back? What are we giving back? And I was in a few talks in this in the morning here today, today's sessions, and I've heard about open source transparency, funding. There's a lot of issues there. I was at theories, I talk about the role of open source foundation and how they help and the whole money perspective of it there. This isn't an easy one, but it's a struggle for many, many maintainers. Unlike the other stories though, I mean, some might have had a good ending story. I promise this one has a positive, happy ending. Okay? So Meet Mr. M, he's known today as Mark, so I could probably iterate between those two titles. He's an open source developer, a maintainer of open source projects of others, not just the one that we'll talk about. And so he maintains a library called Faker.js. Incidentally, it's not the same idea, but not the same project, not the same person. The Faker.js one, as I introduced the one before, you can assume it's the same one. It allows you to do fake data for database or whatever you use it for. But it's for the JavaScript ecosystem, so a whole different project, a whole different maintainer, a whole different story in this case too. So we won't confuse it, but we will show that it was as popular as the one before, as the other Faker project. So very popular. And like many open source maintainers, Mark is helping developers of Fortune 500 companies and Fortune 50 and so on with their work day to day. They're all ultimately depending on this in their test or whatever to essentially help the business grow, generate more money and so on. But maintainers don't get anything out of it, right? They essentially are working and are largely underfunded, if at all. So on November 2020, to make a statement and send a message, this maintainer had opened an issue in their GitHub repository stating that they will no longer be providing any free work. As you can tell from the GitHub issue responses, the emojis at the bottom of that issue queue, it was largely accepted by the community. So apparently, Mark was heard. Was he heard? Did anyone actually care? Would anyone take any action on what was stated there? Well, two years further, January 5th, 2022, correct, this year. This maintainer publishes a new version of this Faker.js library with a semantic version of 6.6.6. Yes, some laughs and everyone can imagine where this is going, I guess. This new 6.6.6 version completely nullified or, as a lack of a better word, removed any code, any source code that was actually usable, any functional code at all, any installation if you had to try to install NPM install Faker.js at 6.6.6, which is the command to install this version, would result in nothing that's actually usable because there is no source code there. As a secondary effect, they also forced push a commit to the GitHub repository, as you can see here, which again removed all the code and perhaps added some clues into what's going under with the end game commit message, but this is what happened. Now, this seems, I would guess, based on the laughs and some of the reaction here, this seems rather aggressive statement, right? Did anyone actually care? Let's talk a bit about what's going on there. Well, Faker.js 6.6.6 is broken. It's a broken package. It doesn't really work if you try to install it, but the way that projects work in NPM is essentially if you had an existing project that uses Faker, you would have to explicitly tell it to use that latest version, okay? Because the semantic version resolution of those dependency versions doesn't just take the latest of everything. It takes the latest of December or the minor patch or whatever you configure it or whatever the default is, but usually it's not the latest major. So based on the fact that Faker 553 was actually the latest stable major version, publishing a new Faker 6.6.6 probably wouldn't have caused any issue for existing projects, not existing, okay? Plus a lot of the time, hopefully developers these days know to use lockfile to pinder dependencies. So again, lower impact of what was going on there and so on. So I don't know. Perhaps nobody really felt the pain. Perhaps a small number of users only felt the pain, and maybe this was talked and was on chatter on things like hacker news and Twitter, but it didn't really provide the message or the effect, I guess, that Marek was intended to express. So we talked about all of those cases, but we know, remember, we said Marek was an open source developer maintainer and as such, they usually maintain other dependencies. Again, similar from other stories that we talked about today. They're usually not, you know, one dependency and I'm gone. These other dependencies called colors. Colors gets 100 million downloads. That's a very big number. That's a very big number of downloads, okay? We'll see in a second who was impacted from this, large organizations that you all know their names here, maybe used their services as well. So with the intro of made about Sember and how that ecosystem work in JavaScript, colors latest version that was stable and well was 1.4.0. And 1.4.1 is a new batch version, which if you lock your dependencies and you want to have deterministic installations, when you do an NPM install, you'll probably not get 1.4.1. But if any other changes would request it, they might change the lock file depending on the NPM install command you ran, but also new installations would essentially easily grab 1.4.1. So the surface, the attack surface or the blast radius here is completely different from before and to kind of like the up and the right kind of impact that this would actually make when it happens. So what was in 1.4.1 that Murak pushed outside? Let's take a look at the source code. Can read it up, read it to you, but I'll also like give you a second to appreciate the elegance of this beautiful code. So adding an infinite loop to the code base gets triggered on every use of this library. So whatever top usage, your code, your another dependency that uses colors, whatever, every usage of the library would actually trigger this part of the code base. Essentially, it's breaking any other library that is dependent on it, because then you have a whole kind of denial of service happening for the app itself. It cannot be used. If you're using it in some server side, you couldn't understand the impact if it's even a CLI or an app, it's just as much frustrating for your users when your app is simply not reactive. So with that, 100 million downloads a month have a more significant impact if we do this. I've kind of like trimmed the infinite code here to what it would actually print to the screen, but actually it was a bit more Zalgo kind of text into the screen, and it would make it look really bad. But essentially, all of the developers are now using this. So when this went out and this incident happened, you could see not a lot after that faker thing with the nullified repository was going out, it actually impacted Mary, who is using Amazon's AWS CDK, which is dependent on colors. It was actually also impacting Mina, who was also using one of Heroku's Oculus libraries, was again dependent on colors. They were all impacted by this. If you were a developer using the just testing framework from Facebook or Meta these days, you would also be impacted by this because that's also dependent on colors. So this had obviously caused a lot of issues in the ecosystems and chatter and, you know, this was a very big incident happening. Not so long ago too, we just said 2022. The interesting insight also to make here is the versioning numbers and how fast this incident actually propagated and impacted users. So what you're looking at here is the downloads of the last seven days, note the version numbers that were problematic, 1.41, and then 1.42, which also had an issue. Mark specifically also added that denial of service code to other parts of the code. And you could see for the amount of days and hours it was published, it was very, very, very fast adopted by the community, showing you how much we depend on open source. Very much. So maybe some learnings here. Use a lock file to pin down dependencies. This is usually a thing that is created automatically these days and developers should know about it. I am also part of the open SSF package best practices working group. So it's something we've also noted there. If you have developers in your team, please have them go through and review all of those best practices, things we've laid out. But this kind of makes sense. The thing is this is kind of a proactive way of managing your dependencies. But sometimes, for example, for Mina's case, he was dependent on using some project that was dependent collars, she was already having collars as part of their dependency. So if she locked it, that would actually put her in more issues. You need to remove it. So another interesting best practice to know about is package managers have a way to essentially have, this is sort of a reactive mitigation. They have a way, this is specifically the NPM package manager in some others like QR and NPM have this way to say, hey, sometimes packages resolve to a dependency, say collars 414. But I want you, due to package manager, to always override whatever they want with this other version because I know this other one is problematic or whatever. This is a way of doing that. So that's another learning that the community had to understand of how to be actively work out the issue here. Other issues or other suggestions I will make is it is not always a good idea to stay on the bleeding edge and have automatic updates. So while automatic updates are great, we kind of need to have a bit of buffer time. This is something we learned at SNCC when we have the bots open up full request to provide you with security fixes for the vulnerabilities in packages that you use. We also do that for package upgrades, just generally do that. But we've learned a few years ago, based on past incidents like event stream and others that were there in 2018 and 2019, that we need to provide developers with some buffer time. So essentially, what we want to do is say, hey, you've seen how fast 1.4 and 1.42 were having thousands and tens and hundreds of thousands of downloads. What we want to do is the bot will open upgrade suggestions for new versions of package you're using, but it will do so after 21 days, okay? Because we want to give time out for the community and the maintainer itself in case they were accidentally shipping a breaking change, in case this had some zero day whatever in it. I want to give developers this time, so please also kind of upgrade your dependencies smartly and responsibly, not just blindly upgrade everything. At that point, you just might be getting a malicious package as well. So I promised a fairytale ending. What happened with Faker, going back to Faker, but with Faker, what happened is the following. The community had an amazing group of heroes stepping up and saying, hey, Faker is a very popular project. This is, again, Faker.js, very popular project. We still want to use it. It really helps us. We use it at the company and whatever. So they kind of like, organically formed up and said, hey, let's create a new Faker.js organization, a scoped registry entry. It's a new entity. They forked all the work that Mark was actually doing at the original Faker library. So all of his contributions are still attributed and part of the source code. And they've created a whole new project in GitHub repository to maintain that Faker functionality. So this exists. Amazing, amazing work to all of those heroes who made that possible for everyone else. Maybe a few more thoughtful kind of like learnings as we reach the end of this talk. One is think about open source due diligence when you use software, right? It sounds to an extent a bit obvious, but as developers, we usually adopt packages by the blog post that says, hey, I use this and that for my tutorial, we copy paste, we use it. My friend from a different company, my colleague, the other team, whatever, it kind of works like that. And maybe at times you search for something, like say you'd search for request, which is a popular open source library in JavaScript for doing HTTP client side requests. It's like the browser's fetch or whatever existed before it. So obviously it was needed. See 15 million downloads. And then you say, hey, of course, 15 million downloads, what can go wrong? Like if it works for other 15 million developers, I guess I can use it. Except if you open this, at least now, this wasn't true for all of the time that this project existed. But for the last couple of years, if you open this in this tool called Sneak Advisor, it's a free tool that you could just Google and go into, you could search this request package and you will see that, for example, the maintenance part of it, the maintenance frequency, virtually is nonexistent across the whole year. Like last change two years ago, last commit two years ago, it's not existing. So why would you adopt and use this project next? So our kind of like tell signs for using packages usually are about popularity and stars and whatever. But those could sometimes be very deceiving, which is why kind of like we recommend this way of like having trying to score packages and provide kind of like this held score of the packages that you use. Another different example is, hey, sometimes this package makes sense for me because I looked at its maintenance, it gets regular commits, it's actively maintained. And if there's like a new vulnerability, they will probably fix it pretty quick. Latest versions show up that like there are no vulnerabilities detected directly or indirectly, so maybe I will use it. And so this takes the discussion a little bit from not just due diligence as developers when you want to adopt new packages or move to a new dependency, but also some people have been talking here a long time about SBOM and software bill of material. I won't go into that, we're kind of like ending this note, but I want to give you something else to think about. Not just software bill of material, but perhaps software bill of health. How healthy are the open source projects that you use? A typical JavaScript open source project has probably thousands of dependencies down the chain of a tree of them. What happens if one in the middle has an issue? It's just un-maintained for the last two years. What can you do about it? You can't blame the open source developer who the maintainer itself, they are literally volunteering their time to help you do whatever you need. So think about this a little bit and let maybe that sink in. So open source is great, just don't forget. The only things that last forever are dependencies, I guess not. Air miles I checked because I flew in a couple of times after COVID, they don't last forever either, trust me. Cat videos in YouTube do last forever, that's for the sake of every one of us here. So with that said, open source software is awesome, have fun with it. If you have any questions, I'm here and thank you for listening to my talk. I think we have time for questions, right? Yeah, of course. I'm just checking if this works. A document by the OMB based on the Joe Biden's executive order on supply chain. One of the things that I'm talking about is self attestation. Now self attestation of that my product, my component, my whatever is okay safety wise. Who would do that if maintainers are responsible to absolutely nothing? So maintainers are not concerned in the organization itself for absolutely nothing before that order itself, right? They literally tell you if you're using an open source package with an MIT or a battery license, you are free to do with it whatever you want. I do not take any responsibility for it. So regardless of that document, maintainers are not the person to reach out to or put the blame or demand on. You're effectively just making the matters worse when we're demanding more and more from maintainers and essentially giving nothing to help support them. I think maybe back to correlate what we learned here back to that executive order is essentially thinking, as I said, not just as bomb like your bill of material, which is important and so on, I won't dive into it, but also that health, right? Like when you use packages and developers do use packages. So the as bomb itself says, you know, I'm using these three ingredients in my product. It doesn't say what's the status of those ingredients. And there are these like other other standards kind of getting in like VEX, which is the exploitation and other like vulnerabilities of these S bombs. Great. Still, it doesn't mean say anything to the company, to the business, if they have some trickle down dependency, five layers deep that essentially did not receive any commits in the last five years. If tomorrow a new vulnerability will get discovered there, there's essentially no one to go and push a new fix. What do you do? You rush off to find alternatives, patch it, et cetera. So this is what I'm trying to go to here. This health package scoring kind of thing rather than the vulnerabilities and everything else, which I think we've kind of as an industry with S bomb and VEX and whatever with SCAs and all of these tools, we've kind of like figured it out to an extent. Thank you for the question. Yeah, I guess we will. Any other questions? Ask about log files. Yes, log files. Yes. Upstream uses something which is a bit more advanced. Wouldn't you break your own code? When you lock your dependencies? Yeah, and I mean there are no real standards for ones to use in your dependency and you lock it and provide it with a lower dependency. You mean specifically with regards to the overrides that I was giving? Yeah, yeah, yeah, yeah. Oh, okay, because otherwise it's a bit, not really the question because when you lock the dependencies you're locked and that's what you get and you've tested that the project works this way. So with the overrides, yes, you essentially have to know that you're not breaking it. To an extent, it's not that much of an issue because if you're overriding it, it's most like 99% with a reason and you know you're overriding it with locking it to a stable version. You know what works. Usually the community also knows what to recommend if you need to override it. So that's not much of an issue and I think also Sember is kind of like a practice that usually works. I will say TypeScript has shipped some versions with minor changes that were breaking changes, but overall the ecosystem, of course like this might be different for Java or Ruby or whatever, but for JavaScript we kind of know how Sember works and we can to an extent depend on it. It's still semantic and not really anything explicit. So you kind of like take it with a grain of salt. Hi, cheers. Great talk. Thank you. I was going to say I was a little bit sad about your happy ending in that it wasn't really a happy ending for Marik and that that kind of gets me onto a point that I thank you. I think one point that you've missed, I think you had some great advice for consumers but I think the one thing that to my, oh god, I'm steaming up, the one thing to my mind that was missing was to fix the problem at source you have to help the maintainers and this is almost like in response to your question where you're getting a little bit frustrated that maintainers are washing their hands of some implied obligation. They don't have an obligation implied or otherwise. As consumers I feel we have the implied obligation to help the maintainers. So if there are security issues we should be rather than pointing at them we should be helping them. I am a hundred percent with you in that. I'm a maintainer myself and I have a lot of friends who maintain software. There would be no one else more excited and appreciative of any of that working out amazing for everyone else. The issue essentially is that it's not as easy to fix. When that happened as a community for you know communities that I live in I've actually raised the topic and asked what we can do. Some interesting ideas were by the way doing something like bug bounties for security but actually for issues or features. So if you wanted something to get developed you could say hey this is my issue I've put you know 100 dollars whatever around it and if you can like build it or whatever contributors build it they get it. It's something that we drive through the platforms. There are a lot of people here from like Open Collective or GitHub funding and sponsors and stuff like that. The ability to fund maintainers has existed for a while. It's just like not happening to an extent where it's actually fruitful for them. So it's not that we need to raise awareness of helping maintainers. I think everyone know they should do it. We're still not doing it as like top level organizations and I think that's a problem that we have yet to have a good fix for. We have to stop I think right you gave me like the stuff thing but I'm here like let's talk so. Yes we can do that. Thank you everyone.


Hey everyone, welcome back to figure fantasy. We have here a new stage, which is the yellow alert We'll start off with our easy stage Okay, so for this one we have Koroko, so Koroko should be placed on the upper lane To fulfill this object in the first one and you have to clear this in 20 stages. Oh 20 seconds. Sorry So I don't think this will be a problem because this is pretty much very easy Um, just have to clear this in 20 seconds. That's it So let's try the next one out Okay, our next one would be hard and let's see my lineup. Okay, so for the next one you need to Defeat the crazy bunny in 15 seconds. So you need to put Koroko again in the middle Because she has The ability to attack the last enemy in that row So as long as you put her in the middle I think you'll be fine. So you have a silly arena and you have Mako in the middle Okay, so I think we're good Also three star clears and we'll proceed to the last one last stage guys is going to be tormented and let's see my lineup Okay guys. So for my final lineup, this is it So you have two healers in the back.  So she will solo that one while the rest will try to Make sure that they can clear the top row In record time. Okay, five seconds to go And we are good Okay guys, so that is it three star clears. Thank you very much for staying this far. So take care. Stay safe This is the warden and I'm out of here


The Programme and Budget Committee of WIPO met from the 29th of August to the 2nd of September. The Director General opened the session with a comprehensive overview of the financial and programmatic results. Member States noted the positive results and the surplus of 70 million Swiss francs for the biennium. The Director General then presented his medium-term strategic plan for 2016 to 2021. The Member States provided their comments and concluded that the assemblies of the organization should note the report. The Programme and Budget Committee then went on to discussing the reports of the external auditor, the internal auditor, as well as the Independent Advisory and Oversight Committee and furthermore went on to review a number of financial management proposals, the first being the proposal to contain and manage after-service health insurance liability for the organization and here WIPO's approach was endorsed in terms of its engagement with the UN system and the common approach to managing such liabilities. The second proposal was related to hedging and this was noted and lastly there was the discussion on the review of the methodology for allocating the income and expenditure of the organization to its unions and this discussion will continue and will be taken up further in the assemblies next month. The WIPO Secretary also provided a comprehensive final report on the construction projects which are now completed and the assets are fully in use. We also updated the Programme and Budget Committee on the status of the implementation of the Enterprise Resource Planning Systems. Finally, the Member States engaged in the discussion on governance and here the conclusion was to continue discussions in the next session of the PBC with the Secretariat contributing through a presentation on WIPO's constitutional reforms. Last but not least, the Member States engaged throughout the week in informal and formal consultations on the proposals to open new external offices and here the decision was to continue informal consultations in the lead up to the assemblies with the next session of the assemblies taking up the matter further.


You are about to hear a romantic drama, such a charming young man, from Street and Smith's Love Story magazine, featuring the Love Story girl in the role of Eleanor Page. Yes, this is the love story of Eleanor Page, secretary to that immensely wealthy widow, Mrs. Alonzo P. Winters. We find Eleanor and Millie, who is the downstairs maid in Mrs. Winters' spacious library. Millie is putting up fresh curtains. Eleanor is typing. It's early afternoon. There. Now that's the last of them, praise be. Nothing makes me busier than standing on a sep ladder hanging curtains. Well, I do look lovely, Millie. Thank you, Miss Page. You know, I always think that next to fresh flowers nothing spruces up a room as much as fresh curtains. Yes, and only flowers is easier. I'm turning in the drive. The Mrs. and that good for nothing jiggaloo. She's gone and got herself. She ought to be ashamed of herself at her age, too. Now, Millie, Mrs. Winters isn't so old. Well, she's old enough to be his mother, if you ask me. Millie. Yes, Miss. What makes you think that, Mr. Baxter, is a jiggaloo? What else would it be? Well, I don't know. He might be a visiting relative or something. Well, you don't pay relatives $100 a week just for visiting.  Nobody. She left his checker line there for him on the mantelpiece last Friday, and I saw it. $100 a week. What does he do for it? Does he wash the car? Does he answer the door? Does he take the dog's walk-in? He does not. Well, she probably hires him more as a companion. Companion is right. She don't never put a foot outside this house or what he's tagging along. He's with her every minute of the day when she plays golf, when she goes to church, when she goes to town, when he takes lunch at the club, when she goes to market it, even when she steps out to pick a couple of flowers. There's Mr. John Baxter as close to her as her own shadow. Wonder what she does with them nights? Millie. Oh, you needn't look so shocked. It's the talk of the town. The butler over at Peabodies was just telling Cook that night before last... Millie, I'm not going to listen to any more backstairs gossip about anything connected with Mrs. Winters. Well, if you ask me, you're kind of stuck on them yourself. Certainly not. It's not that I blame you much. He's not bad looking. But don't let Mrs. Winters catch at it, not if you want to keep your job. Millie, don't you think you'd better take that ladder away? You've quite finished in here. No. Well, very well, if that's the way you're going to take a little bit of friendly advice, I'm going. And I'm taking the ladder with me, never fear. Jigaloo, I don't believe a word of it. Still, she does pay him a hundred a week. And he's always with her. What the heck? It's no concern of mine. Grat it. How do you spell metabolism? Now, wait a minute. M-E-T-A-B-N-O. What is it, an A and a-N-O? Need any help? Oh, how do you spell... Oh, it's you. John Baxter Esquire at your service. Never mind. I'll look it up in the dictionary. You wouldn't know anyway. Know what? How to spell metabolism. M-E-T-A-B-O-L-I-S-M. Thanks. And there's something else I know. Yes? You have the most amazing blue-green eyes I've ever seen. Thanks, but don't you think it's a little too early in the day for compliments? Well, I know, do you? Much. I thought most girls loved them, anytime at all. I'm not a girl. And this is Windows Secretary. Oh, just a machine? Exactly. With the waste of time to compliment a machine. Oh, I wonder. This is the machine age, they tell me. Personally, I've always been crazy about machinery. Will you please go somewhere else? Can't you see I'm busy typing? I'll go. Just as soon as I try a little experiment I've had in mind ever since I came here four weeks ago. What's that? This. You keep away from me.  Just my scientific mind. I simply had to find out. Find out what? If you're always a block of ice. Oh, really? And you're not. Oh, decidedly not. Why do you... Oh, there you are, John. I've been looking all over for you. Oh, yes, Mrs. Winters. I promised Mr. Lens down at the mill I'd bring him those papers this afternoon, but I have such a wretched headache. Well, why not let me take them for you, Mrs. Winters? Would you, my dear, I'd appreciate it. Of course I would. Good. John can drive you. The air will do you both good. Right. I'll go get the car. But Mrs. Winters, I'm quite capable of driving myself. It's not necessary, but Mr. Bass fiddle sticks. I won't need him. I'm going to take a nap. A little young companionship will do you good, Eleanor. And John is such an attractive young man, don't you think? Well, I really haven't had time to notice. You young people always so unobservant.  Nice day, isn't it? Very. Well, May's my favorite month. I said May is my favorite month. I heard you. Well, you're not a very chatty young lady, are you? I don't believe in distracting the driver. Well, we've delivered the papers. Now I've got to get home. I have a good deal of typing to do before dinner. Why are you stopping here? Now, this is where we get up. And just why do you think I should get out? Well, see the sign over that door? The Old English Tea Shop. Mrs. Winters told me to take you to tea somewhere. This place seems to be as good as any. I don't like tea. Well, then you can have pink lemonade or ginger beer or anything else your little heart desires. But out you get if I have to carry you. It wasn't so bad. Two cups of tea and three slices of toast with jam. Not bad at all for a young lady with a firm prejudice against the Old English custom of drinking tea. Well, it did taste sort of good after all. Of course it did. You know something? What? I'll bet a lot of your other prejudices are just as open to persuasion. Oh? Mm-hmm. I'll bet you could even learn to like me if you tried hard enough. Sorry, I haven't the time. And besides, aren't you forgetting that Mrs. Winters has first call on your... your attention?  Don't you know that my relations with Mrs. Winters is strictly business? I should say they are. She pays you $100 a week for them.  Come to think of it, I think maybe you're the funniest female I've ever met. You know, maybe that's why you're the only one I've ever really been in love with.  You don't know what you're talking about. Oh, don't I? Certainly not. Look here, Eleanor. Let's get this thing straight. I love you. Rubbish. And what's more, I've got a pretty strong hunch you kind of care for me.  Oh, of course you do. You let me know that when I kissed you in the library. I did no such thing. Mm-hmm. Yeah, I'd swear I was right. Still, I'm perfectly willing to be convinced. Shall we try it again? Certainly not. What would people think? Well, who's going to see? These high-backed benches make a very good screen.  It's getting late. I'm going out to the car. No, no, no, you're not. Not until I prove my point.   I always will. You want to make any better? You get out of my way. We've at least seven more miles to go. I was a fool to keep you out so late. You're telling me.  Naturally. Well, why do you keep watching the rearview mirror like that? Well, there's a dark green car back there. It's been following us for the last five miles. Well, what are they? I don't like it. They haven't any headlights. That's not very sinister. It isn't very dark yet. Surely you don't see. Oh, what was that? Duck, get down the floor. What? There's a round hole in the windshield. I know it. Now shooting at us. Duck, down on the floor, dog gunner. The glass cut you? No, at least I don't think so. Good. Hand me the revolver that's in that side pocket. You're not going to shoot them. If they don't get me first, give me that gun. Here. Oh, you're slowing down. They'll catch up. I want to get them within range. They're getting awfully close. Keep down now, I tell you. There's a police booth around the next bend in the road. Do you think they're here for shooting? They're getting closer. Closer. Now. You got them. That car smashed into the telegraph post. Oh, John, it was horrible. Easy. Take it easy. It's all right now. Here come the police. Hey, you, what do you think you're doing? Oh, hello. Backside and recognize you at first. Hey, what's going on here? It's the Carpetty Gang. The one that's been threatening Mrs. Wonders. Oh, I see. And they must have took this young lady for her and tried to pull off the snatch, huh? Snap. He means kidnapping. Lucky for you, Miss, you're keeping company with one of the best little old pistol shots in the country, or you wouldn't be here now. Oh, John. Well, I'll be mosing along, helping the rest of the boys to unwrap that telephone pole. John, then you were really Mrs. Winter's bodyguard all along. Oh, yes, in a way. Although it's not my regular profession, I just signed on for the duration of the war, as you might say. You see, my old man's a great friend of the commissioners, and when I found they needed a good shot to protect Mrs. Winter's, well, I was only too happy to oblige.  Oh, well, that wasn't entirely your fault. They thought it would be a good idea to spread that rumor, so the gang wouldn't be scared off. I must say I wasn't too keen about that angle of the case, but, well, it did have its compensations, meaning a certain young lady named Eleanor.  What, you mean kissing you? No, that is... I mean this gangbusting business. Oh, that. Yes, that. Well, John, darling, you might have been killed.  Oh, you know I do.  I never did, not really. And you wouldn't object too strenuously if I said I wanted to kiss you again?  That's all I wanted to know. You have been listening to a romance featuring the Love Story Girl and presented with the permission of Street and Smith publishers of Love Story Magazine. Listen for the Love Story Girl in a new romance next week.


Hi everyone. In this tutorial, we're going to talk about the bubble sort algorithm in Python language. First, we're going to talk about the bubble sort algorithm in generally, and then we're going to implement bubble sort in Python language. Bubble sort works in a way that it compares each pair of adjacent items and swap them if they are in the wrong order. For example, suppose that we have a list with five elements 5, 4, 1, 3 and 2, and in this example, we want to sort this list in ascending numerical order to get as the solution list, which is going to contain numbers 1, 2, 3, 4 and 5. Bubble sort works by comparing adjacent elements and swapping them if they are in the wrong order. Let's see how bubble sort algorithm works. First, we're going to compare numbers 5 and 4. In this case, number 5 is greater than number 4, so we're going to swap them. Then we're going to compare number 5 with number 1. Again, here we have a situation that number 5 is greater than number 1, so we're going to swap them. Then we're going to compare numbers 5 and 3. They are in the wrong order. We're going to swap them. And finally, we need to compare numbers 5 and 2. And again, we're going to swap them because number 5 is greater than number 2. And that's the finish of round 1. After this first round or first iteration, we have one number that is sorted. In this case, it's number 5, so we do not need to work with it anymore. Now let's start again in the next iteration with comparing these two numbers. And again, number 4 is greater than number 1, so we need to swap them. Again, we're going to swap here numbers 3 and 4 and numbers 2 and 4. I made this example for this video to be a little bit difficult so that we can see more easily how bubble sort actually works. And again, it's the end of the second iteration in which we've sorted another element. And now we're going to check rest elements and compare them in order to sort them. Now, in this case, we're going to compare numbers 1 and 3. And they are not in the wrong order because number 3 is greater than number 1, so we do not need to swap them in this case. But what about numbers 3 and 2? They are in the wrong order, so we're going to swap them. And again, the third number is sorted. And finally, in the fourth iteration or in the fourth round, we need to compare these two numbers. Number 2 is greater than number 1, so we do not need to swap them. And that's it. Our list has been swapped in ascending numerical order. List with which we're working in this example has five elements. And the bubble sort algorithm works that in the case when we're having five elements, first we need to have four comparisons to compare first and second element, second and third and so on. And then we're going to have one element which is sorted. And then we need to have three comparisons. And in the next iteration, we have two elements that are sorted and we need to have two comparisons. And finally, we need to have just one comparison and then all elements are going to be sorted. Our list has five elements. I'm gonna start to type the bubble sort code and I'm going to use this same list in this example. When we're implementing the bubble sort algorithm, we need to have two loops, inner loop and outer loop. The outer loop is going to have four iterations because we're going to change four times the number of comparisons. As you remember, at first we had four comparisons, then three, two and finally one outer loop tells us how many times we want to change the number of comparisons of list elements. I'm gonna continue implementing bubble sort code. I'm gonna write, for example, function, let's call it bubble sort, which is going to have an argument in this argument. We're going to put a list. We need to have two four loops. The outer loop is going to tell us how many times we want to change the number of comparisons of list. So I'm going to use a variable, for example, number of comparisons. And if we're having five elements, we need to have four different comparisons. I'm gonna get the number of items in our list by using the function lan. The length of the list is going to have five elements. And we need to subtract number one, because we're going to have four times changing the number of comparisons of the list. Then again, the inner loop is going to have again five minus one or four iterations. In the first iteration, we're gonna have four comparisons. In the second, we're going to have three in the third two. And in the last, we're going to have just one comparison. Let's back to our code. So I can use this outer list to get at the same time the number of comparisons in our inner list. So I'm going to loop this list in opposite direction. Okay, now let's write our inner for loop for item in range number of comparisons. Then we're just going to check if two adjacent elements are in the wrong order. And if they are, we're just going to swap them. I'm gonna ask if adjacent elements are in the wrong order. If they are, we're just going to swap them. This is the code for swapping two elements of the list. And that's all code. Now I'm going to check if our algorithm is working by trying to sort our list one. And I'm gonna print the result our algorithm is working. Also, I do not recommend you to use this bubble sort in practice, because it's very slow. You can use it just in few cases. One of them is that if you know that almost all elements in your list are sorted, and just few elements of this list are not in the right order. In the right order. And if they are not in the right order, that they are very close one to another. That's all in this video. Don't forget to subscribe.


A lot of stuff about pattern matching and related things on the type level dot board blog which you can check out later. And this work kind of falls out of it and addresses a common misconception about how pattern matching works, which we'll see in a second. But first of all, I should mention, if you're watching this on a video, this talk is about Scala 2.11.4. This is always changing. This was different in Scala 2.10. The information I'm going to tell you was not true in 2.10. I got to give you a different set of information today. And it will probably not be true in 2.12. In fact, I know that it won't be true in 2.12 because they are definitely changing now this course. Okay, this is just a bit of a review. This is just a basis of the Scala let's call, I would say basics, but I mean, like rules of the Scala language that are not entirely basic. First, we have the idea of a subsumption in our subtyping. So this thing, duck face, less than colon, duck face represents a subtyping relation. It means that x, here, x duck face y means that x is a subtyping y. Now that includes the possibility that x and y are the same type. It's possible in this relation that x and y are the same type, but they may not. As it turns out, it's more useful to talk about subtype or equal rather than strict subtype, which means it's a subtype. That is, it has a duck face relation, but it's not the same type. So that brings us to Seamless and Types. Every time you create a value of a stable type, such as when you declare this val x is string. When you say x colon string down here, what you're also saying is that x dot type is a singleton type, which is the singleton type of the definition x. That singleton type is a subtype of string. That is the x dot type, duck face string. Moreover, it's a strict subtype. X dot type is always a subtype of string where a string is not a subtype of x dot type, all right? Any time you create a value, you're creating an associated singleton type, which is a subtype of whatever inferred or ascribed type that you give to that definition. And here we have a pattern. I just wanna give you the names of the parts of the pattern because I'm going to use them without explaining what they are if they're on. We have the theme here that you're matching is called the selection. And then the things here on the left sides of the rocket ships are the patterns. And we call it equals greater or rocket ship. And I don't think that's the official name probably. And the thing on the right hand side of the rocket ship is the block. So we look at patterns sometimes and say, are these, this is just structural checking. We're just checking whether it's a particular subtype or we're just checking that it has a particular subtype and then calling some methods to get pieces out of it. So it's like, oh, well, you can do that in Java. You just write this kind of thing, right? The problem is that it doesn't have a logical implication that this Java doesn't understand this logical implication that when this instance of check passes, select your instance of box, therefore you know in the body here in this block that the value selector, it's singleton type is a subtype of box. So the confusion that people run into when they try and use types and try to match means it's here. This is the most common one by far. So we have a value, we have an argument X of type T that is to say X dot type is a subtype of T. And we try to match it and do something different based on what the pattern match means. So we say, okay, well in this first case, well I, so X must be an int, therefore the type T must be the type int. And in the second case, well X is a stream, therefore the type T is the type stream as well. And actually, Scalacy gives you the Sarah. And today Sarah, we're gonna see some errors that are good for Scalacy to give you and some errors that Scalacy should not give you and some errors that Scalacy gives you, well Scalacy doesn't complain at all but we really think it really should complain. And here's one that it should absolutely give you. It says that you can't do these things, you can't make these assumptions. Now this one works, this one is sort of similar. But we put that type in a type parameter instead. And we kind of box it up. So we have box do, it has two subtypes int and str2. The thing to note is here, we have, we don't have T, we say that this case is the same case as the stream case. And when we do basically the same thing, we check the end case and we check the stream case, we can do the application that we're trying to do in the last definition. All right, well before we get to why that works, let's talk about why the first function is bad. So we have this value gg, it has a singleton type, gg.type. We take that singleton type and we pass it as the type parameter to double one. There's only one value of a singleton type. And in this case, in the case of gg, it's the stream gg. Orges is not uptype gg.tip. We have made the type system on-sand. In other words, the singleton type of four character streams whose characters are all gs is not a subtype of gg.type. Which is what we claimed here. Incidentally, just to go a bit further, Scala CD seems to put inline ability into the singleton type system just a little bit. So when you make this declaration, we do the doubling here, the unsafe doubling, but it throws away the result and gives us the original one instead. Which is, it's right, it should do this. And it's another reason that you should not try and outsmart the type system when you aren't absolutely sure that what you're doing is the right thing because you usually aren't. All right, if you're not satisfied with using singleton types to demonstrate it, I'll just put it into element form, all right? Here's our goal. We're gonna be talking about goals. We're trying to prove this stream in the string case in the subtype of t. All right, so imagine that singleton types of our argument X is the set of elephants. It's a type, types of sets of values, well, well. And we can say that elephants are gray. Therefore, the set of elephants is a subset of the set of breakings. We can say that the set of elephants is also a subset of animals. And here, animals stand in for streams and breakings stand in for teams. So we prove that this set, X dot type, is a subset of these other two sets. We have proved that those sets are the same set. We're nowhere close to proving that. They could be the same set. They could be overlapping. They could be not overlapping at all. All of these are possible. It just so happens that there are gray animals so that they do overlap in this case. But that's not required by a solid type system. Okay. This is why the second function that we wrote works. Because this error happens. We try to create another kind of box too. We have a string case and we need a case. And we tried to create one that would claim to have both cases here. We said this is both a string and an inbox. In other words, we have both of these subtyping relations are true. But this doesn't compile. You can't create this class. And it gives this error message which I don't understand why this is the error message that it gives. But the outcome is that it gives the rule that we need. And this is the rule. If you remember nothing else from this talk, then you should remember that, you should remember the rule of this rule and how the power matching works. It's the injectivity rule, right? Giving you the freedom to do multiple subclassing classes with different type parameters built in which many people ask for on the scholar user mailing list. Many people have asked for it. Would take away your freedom to do sensible pattern matches. Freedom is slavery. The rule is here. If you have a value y, and you have some trait or abstract class, this is important. It's a trait or an abstract class or a regular class. It's a k of some type parameter r. If you know that y, that y has type k of s and for some s, and you know that y has type k of t for some t. And you also know that the types s and t are equal. And that's a little obscure. So let's put it a couple of different ways. Every time you take the type constructor k, which falls out of the trait or class k and apply to a different type t, you end up with a different type k of t. In other words, we get just the rule that's being enforced by the type error that we saw earlier, which is that if you have two different types, s and t, or string in this example, there are no values of the type of k of s with k of t. Or in our example, there are no values of the type box two of string and box two of interval. It's not allowed. So as a result, you sort of just do the contrapositive and say, well, if we have a value of this type, this kind of intersection type, and we know as a consequence that the type parameters are the same. So I said that it was important for it to be the traits or classes earlier, and this is why. Scholar lets you talk about types and innums like this one as like fully fledged types with a kind of their own. And here's an example. This type constructor is not injective like traits and classes are. So if we say k of anything, really we end up with set of columns because that's what's on the right-hand side. We don't use t anywhere. So if we have this like k of int, then we have set of elephant. Obviously, the type set of elephant is inhabited. Even if there are no elephants, you can still have an empty set. We'll get into how you can get elephants later. So now we can finally go back to double two and talk about why it works. And it takes you a little while to get there, but it will always take you a little while to get there. If you take the existing rules that you understand about how subtyping works and then you add in this new rule of injectivity, which I've just presented, then you should be able to make all sorts of interesting derivations about what your patterns mean when you are matching values. So let's do the derivation here. Why does this work? All right, our goal again as with double one is that string is a subtype of t in the case of stir two of s. All right, we know that x subtype is a subtype of stir two. That's the implication of the pattern. We matched the case stir two, therefore we know it's a stir two. We know that stir two is a subtype of box two of string because that's what's said in the extends clause when we declare stir two. Therefore, because of one and two, by the transitivity rule of the subtype of relation, we have that x as type of box two of string. And yes, you do actually have to go through all that. You don't get quite enough information if you go. We also know because of function declaration that x is a box two of t. That is, it seems like it's subtype of that. That's just in the argument text of addition. You said x is a box two of t, therefore that's the premise. We can combine those using our transitivity rule, sorry, our injectivity rule. We have a value x which is of pipe box two of string and of pipe box two of t. It's a actual trait or class, therefore we know that we can use the injectivity rule to prove that string is equal to t. As a subtype of that string is equal to t, it's just the sub case of string is a subtype of t. So we're done. You can return a string in that case and satisfy the requirement to return a t. All right, and you might think, well that's just weird GADT stuff that you were doing up there. That's like something people don't run into ever. You can use this all the time but if you do pattern matching at all, okay? You just weren't quite aware of it. You absolutely need it and we'll see why in a second. This is like your basic ADT, right? You think, oh, you don't need any fancy injectivity for this to work at all. That's for a word, you need to do well, of course. All right, so basic ADT, all right? List, it's either an empty list, nano or it cons, which is an element and another list, right? Surely you've done this if you've done the ADTs. And both of them, there's no concrete type in here anymore. It's just t being passed through and everything. Okay, so you're supposed to put on this type. We take a list of t and we return an option of t. It's if we got an empty list, then we have none. If we have cons, then we give that head up, right? So the tricky part here is proving this. X has to be a t for this return type to be satisfied. And you need to do all this in order to get there. Absolutely, so let's do it. So we need X to be a t, in other words, X is singleton type is a subtype of t. And that's the X that we got when we applied the cons pattern, where we matched the cons pattern values. All right, so what do we have? We have that whole list, the argument, is if singleton type is subtype of list of t, that's from the function, all right? We also have, from the pattern match, that it is a subtype of cons of q. We don't know it's cons of t yet. All right, we're not quite there. We know that it's cons of q for some unknown type. We're gonna say this is existential. We introduce a new existential type and say that list of type, in addition to being a list of t, it's a subtype of cons of q for some type q. We keep talking about that, all right? We also know that cons of q is a subtype of list of q and that just comes from the definition of cons. It extends, all cons of t extends list of t, therefore cons of q and list of q. So we take these two and we combine them again using the transitivity rule. And now we have that list is of type of list of q, which is the same one we introduced earlier. Now we already knew that list was a type of list of t. So now we apply injectivity and finally, we have that existential we introduced earlier is the same as the t that we took in as type parameter to our head option function. We know from the pattern where we pulled out of the cons that x has type q and from the equality we derive from transitivity and injectivity and all that good stuff, we finally have that x satisfies the return type. In other words, we take the x and put it in sum, we have an option of t. So, you think, well, we can get away with that one. Again, proof by contradiction, we can't get away without using injectivity to make this derivation. So let's look at a counter case. Let's say that we decide to make Scala more pragmatic or practical or whatever. And oh, it's convenient to be able to extend the traits in classes multiple times with different type parameters. So let's go ahead and do it. All right, we've got a cons. It's just like the normal cons. We've also said it lists a class order. That's convenient. So let's take that cons and do some fun stuff with it. All right, so we do head option. We make a list that has a stream high there and I like using the stream high there for these examples. And okay, every tree cons of string, is a list of string because we extended cons and cons extended list and transitive involved a lot. And accordingly, you get an option of stream back which is some of high there. All right, now let's do it again. But we'll put a slightly different description here. All right, so we have our tree cons. It's the same. It's a tree cons of string because we gave it a stream. That's where it incurred. But every tree cons of any type is a subtype of a list of class orders. So we went ahead and we put it up to list of class orders. So the type parameter that we incurred is not string anymore, it's class order. And accordingly, the return if spell allows to file this. Again, I have to emphasize this is hypothetical only because you're not allowed to do this. The return type of this would be in that universe. Option of class order is some high there. So therefore the stream high there happens to also be a class order. I hope this is not a sense. You don't need a value. We put a value in our earlier cases. But you don't need one. Here's a case that doesn't use a string. That is, our data structure doesn't contain it. It's, as they would say, isomorphic to Boolean. It's an, this puts a lie to using simple isomorphisms in a system like Scala where you have parametric volume. Because we can introduce things that are obviously isomorphic to Boolean because they're only two values, but they actually give us more things. They give us more features. In other words, the thing we've been trying to do, which is to like say that this is evidence of what this type parameter is. When we match gimme int, that is evidence that the type parameter t is equal to int by the same kind of derivation that we've already been doing. Incidentally, you do have to kind of know what you're doing here because Scala can't quite figure it out. You can write this without the description t, then it will just infer a return type of any. Also, and the reason for that is kind of this. The type of quality that you work out by doing a pattern match only exists within the block. So here we prove inside this block, t is equal to int. And we prove within this block t is equal to string. You honestly can't do that outside the pattern match, outside the block, on the right hand side of the appropriate profit chip. So t is a phantom. Out-of-type parameters that have no data associated with them is how you do this kind of thing. You can add information about type level expectations that you have at your data layer, right? So it's encoding actual, safe runtime type information. This is the only way to do it. Reflection is not safe. This is safe. Absolutely. We know it is because we did all the logical stuff. All right. So here are some things that don't work. All right, it'd be nice to be able to write equals come equals this way. This is how you basically write leadness type of quality. And if you could do it this way, it's called. All right? It means that if you have a value t of what t and p becomes this quality case, biological implication, the types t and p are the same type. Because we can only instantiate it with e-key ruffle, which just takes one type parameter and passes it in for both cases. All right? And so you should be able to use that to do this match right here and substitute this t for p given a t of t and p. But you can't do that. You get this error. It'd also be able to be really nice, especially for a scholarly stream. Paul, Chisano, and Rudard are complaining about this one all the time. If we're able to introduce new type parameters in some classes here, they don't have to pass it up. Right? So here we have this extra s. And we do here in this list and here in this function. But we don't pass up the s because we're actually not gonna need it. Our purpose of this is to introduce the existential. So we'd say, well, the way that you evaluate this, this is just like a math application. You will list the best and a function from s to t. You never want to get a list of t up, right? And there it is, that's our evaluation. And that compiles, but not for a really good reason, right? The reason that it compiles is because the type that it pulls out that it substitutes for s is any. So this is any to say because any list of any type is any, that's fine. This any does not say. This function takes s. This function doesn't take any. And the return type should be something like this at the end of the bottom. List of s and s to t are some type s, which is much like the existential q introduced earlier. This would be appropriate return type. And in fact, you can use this bug in Scala C to write on safe course. All right, you could do all this for covariant and contrarian parameters too, but it takes way longer and it takes long enough just to explain how to do this for invariant parameters, which are much simpler. You don't want to use covariants and contrarians. Anyway, that's your tariff. They are so complicated. No idea. Wow, we still haven't worked out a correct model to talk about variance and higher times in Scala. It's crazy. Yeah. Anyway, this is safe. This is a safe in 2.11. It's not safe in 2.10. It's finally safe though. Basically what we're saying is we have some value and if it happens to have the type nil dot type, which is the single type that comes out of the definition of nil, which is just the one that's in Scala's collection in the loop, then we, hey, we've got the same as the type pattern in MASH. Give it back to nil dot type because this binding has the type nil dot type, which is what you expect from a type pass. Indeed, if you pass an empty vector to that, it uses the fallback case instead and returns nil, which prints like this open ground, close ground. So that's good. And if we give it nil, it says the single type pattern match. Great. All right, let's do it again for our as pattern instead. Very similar. This binding right here, X, gets the type nil dot type. So, let's give an empty vector in. Oh, well, this will match because obviously empty vector is a list. Wait, what? Yes, wait, what is the correct response to encounter this with a person? All right, as it happens vector, the empty vector is not upside nil dot type, but it just gives X that binding. It just gives it to us. That's kind of because as David McIver noted in 2008, that's what. It happened six years and four days ago, right? Okay, six years and four days ago. Instantly, this is going to be very annoying to fix. It just might take us years and years and years to fix this problem. It is totally unclear what type X you have in this match. So first, let's talk about cons, the one that we introduced earlier. So when you do a match on cons, where you say case cons or whatever, that's of the kind we introduced earlier, as a absolute typo implication. If we successfully match cons, not because we used unapplied, but it's a similar rule. We know that the selector's type is a subtype of cons for some existential. But when we use an as pattern, the as pattern with an associated value pattern, where we're just matching like, is it equal to this value? We're actually using object equals, the one from Java that was invented in like 1995 or whatever it was that Java was created. We do everything we need to know about type systems back then. So I'm sure it's a perfectly sound design. So it could say, oh, is it EQ? Is it Hamilton type patterny equivalent to nil? If it did that, then this would be fine. But that's not why it does it does this. Is it any kind of Gen C? Is it empty? Okay, and it's nil. Every, yeah. Okay, so we can get the type model implication out of that. And this is what, this is what Darmark-Iver meant by, it's in totally unclear, all right? It's this type, this Gen Seq thing, that's the type that the pattern binding X should have when you say X at nil, that is case X at nil. It should be Gen Seq of Q for some existential type Q. So there's nothing in the encoding of nil or anything that says that's what the application is. So there's no way that the pattern matching system can find that out. We're talking about lists in general, it's the same problem. If you have any kind of list and you put it in a value pattern, it just checks whether it's Gen C and it has the same elements, which I'm sure are compared by a method that's just as sound. Oh yeah, yeah, we can trick, we can do any kind of trick we want just by exploiting this single bug in Scala C. This is the case where we make these two empty buffers, right? This is a buffer, right? You can't possibly put any value to the buffer. So there are no functions of type A and B for some unknown types, A and B. We've got this other empty buffer, A's, and you've got a value like this, right? It's identity function, all right? So let's say, okay, Scala C, I've got this A and B's buffer, right? Does it have the type of the A A's buffer? Oh yeah, they're equal, so they must have the same type. So now this A and B has two funnels and one of them says, you know, you put values in a funnel. One of them says, no, you can't put any values because you don't have a value like this. And the other one says, yeah, give me identity function. So we put it in, in the R-friendly new funnel that we introduced here. Drop an identity function in there. Number five, your detection of A and B's for A and B's. And then we go ahead and grab that because we have a function back off the other side. The one that says, hey, there are no values of this type, but I have one, so here you go. And yeah, we then use the back function to tell the scholar component that all streets are elements. All right, let's talk about some long term. This is a design space. This is not a fixed bug. This is where if you want to go further with this, then you should start thinking about what you think this should do. You're taking what you know about deriving implications, the typo loan implications of doing pattern matches. Well, it could just be the selector's type, which in the case of the function we wrote as N, it's not very convenient. It sounds, it's not very convenient. I'm kind of in favor of it anyway though because value patterns are terrible. All right, here's what Ordersky said. Around the same time, around the same time back in 2007, I think. Yes, what this does is that when you either decoded what I'm reading again, I already did that last week. So, yeah, I fully sympathize if you're having trouble decoding what's going on there. It's written in standard ease, just a little bit, but what it's saying is that when we have a value pattern like nil, if we put an at sign before and a pattern binding, then before we say that this case in the pattern match passes, we also ask whether it has the runtime type. It has the static type. That is, you have nil dot type. This is the type pattern associated with that is like colon nil dot type. So whenever we put x path nil, we say, okay, nil equal to it, but according to object equals. Oh, is it? Okay. Well then it also does it pass the type pattern. Nil dot type, which is using eq to reference equality, which is sound. Yeah, that does not work very well because it means whenever you put a as binding in front of a value pattern, that's totally different semantics than when you just have a value pattern. Let's see, you can also do this. This is kind of, I mentioned earlier the problem that was that nothing communicated to the outside world that Gen C was the type of implication of that equals method returning true. And so I just say coded here. This is just like a type of function. We say list is associated with Gen C for an existential type. And we say that like list of the type list that we defined earlier, that's associated with list from existential type. And you can kind of write these and this doesn't really work because implicit lookup doesn't work the way that it really means to you for this work. But theoretically you could create a universe where this sort of works. It wouldn't prevent it from lying to the type system still. But we wrote Gen C over there. And that's correct. It happens to be correct in this case. But there's nothing checking that I put the right thing. Let's see, we could stop using object equals for value patterns and introduce something very similar which says, okay, well, you have to do this runtime type check first before you can do this equals, basically. This is what this is saying. It's very similar to the previous case. It says, well, first check that it's a Gen C and then we can do the equals check. And then if that passes, then we already knew that it was a Gen C. So we can go ahead and give that as binding the stack type Gen C for something existential. I don't know. That'll work either, you know. This is, as Odersky said, this will be more and more likely to take more than this. All right. The thing here to remember is that what are presumably, they'll have to fix it eventually or it'll never get fixed on them. And if it does get fixed, then it will definitely get fixed. So it's definitely an area to pay attention to. So, just a quick review. Pattern matching and types all tied together. You can't really use pattern matching without its type level implications. The essential rule that is missing when you're talking about the rules of subtype relations is injectivity. That's what makes all of this fit together. The uses of this are unknown and that they grow as the type system gets better. When the bugs I showed earlier are fixed, this system will get even more powerful. So the thing to do is to look at the patterns you have and think about if this pattern passes, what does that prove about my types? How can I use this proof in the design of my data structures? Because again, this is a sound way to get type level information into the runtime and it's the only sound way to do that. Incidentally, doing these kinds of things is not a violation of the Scholarzy no type test rule. It's not a type test. The explanation for why that is is too long. I just wrote a blog post on typelevel.org blog about why this is. And again, it would be a whole other talk. So I won't inline that here. You can check that out if you like. Anyway, that's it. Are there any questions people have for you for not to launch a peer-adjectivity rule? Talk about whether or not that's specific to the Scholar or if that's the general statement about types. I think I've still got to go back to the back to the specific statement. It's not specific to Scholar. It generally appears. For a while it wasn't known if this was true in Haskell, for example. Just because the way Haskell is designed, you should be able to write code that actually proves that it's true. And eventually, and other features were introduced in Haskell prove that it's true. That a real type is injected. The Haskell does it a little bit differently. I mentioned that synonyms have kinds, and therefore that's why you have to talk about traits and classes. But synonyms in Haskell don't have kinds. So you can only do this with real types, and every real type is injected as a result in Haskell. And it probably applies to most systems that have any kind of pattern matching. Well, the existing where you can go to this in this way probably has what amounts to an injectivity rule. Whether it's by construction or whatever.  You kind of need intersection types like with extents, with law, with law, to really have to worry about this. So in a lot of cases, it just says, well, you can't have intersection types, so you can't write this in the first place. Therefore, we have injected. Anything else? Okay, we're good.


Five foods that you should always have in your kitchen. I know life can get pretty busy and a busy schedule can often lead to very poor food choices. That's why I always keep these five essentials in stock and you should too. First of all, always have some dark bitter greens and lectin-free vegetables in your refrigerator. One of my favorite sayings is more bitter, more better. Interestingly enough, almost all long-lived societies have preferred very bitter greens in their diet, whether they're dark green leaves like arugula or Swiss chard or bok choy or radicchio, which many people call that Italian red lettuce, but is actually part of the chicory family. There are some great varieties of broccoli that are extremely bitter like broccoli rabe or broccoli rabe, and you can find it usually right next to the broccoli in most grocery stores now. More bitter, more better. The bitterness is a sign that there are lots of polyphenols in these products. And get used to that bitterness. Seek it out. The bitterness is what you're looking for. Also, one of my favorite sayings is if you eat dark green, you will become lean. Why? Because these polyphenols will uncouple your mitochondria. And we now know that the polyphenols in these dark bitter vegetables feed friendly bacteria, that polyphenols are some of the favorite prebiotics that bacteria need, and the bacteria in turn will turn these polyphenols into absorbable compounds that will uncouple your mitochondria. So it's always a great idea to keep these dark bitter vegetables in your refrigerator. And the great news is a number of these, if you buy them whole and please buy them whole, will keep for very long time at cool temperatures. In fact, one of the reasons that traditional cultures eat cabbages, which are also quite bitter, is that cabbages will store literally forever through an entire winter. So think of storageable leaves like cabbages, like radicchio, like bok choy. Those are the ones that'll keep in your refrigerator and they'll be ready at a moment's notice when you come home and need something to eat. Second, is certain nuts should always be available to you in your pantry. Nuts are a great way to get healthy fats and to help you feel full. Now, pistachios are one of my favorite and pistachios are the highest source of melatonin in a food that you can get. And melatonin is not the sleep hormone. People who've read Unlocking the Keto Code know that melatonin is actually the essential antioxidant in your mitochondria that protect your mitochondria from damage. Melatonin is an incredibly important protector of your brain, mitochondria. So have some pistachios. Macadamia nuts. Now, be careful with macadamia nuts. They're mostly mono-unsaturated fat. They also have a very cool omega-7 fat that's really good for blood vessel health and omega-5 fat that's good for blood vessel health. But if you're trying to maintain or lose weight, watch out for macadamia nuts. Walnuts. Walnuts are a great source of a short chain omega-3 fat called alpha-linolynic acid that is one of the best health promoters for uncoupling mitochondria that I've ever found. Study after study, particularly the Predomet study in Spain, showed that adding about a half a cup of walnuts to your diet dramatically improved memory in people 65 years of age or older. So my mix at my offices that every patient eats while they're waiting to see me is walnuts, macadamia nuts, and pistachios. Those are the top three. But there are others. Hazelnuts are great. Peely nuts. Many people think it may be the healthiest nut in the world. Check out episode 232 with Jason Thomas, the Peely Hunter, and see what we're talking about. Now, they're great pre-party appetizers. This is the season where we're always awash in parties and there are so many temptations. The problem is you're going to succumb to those temptations if you arrive hungry and if there's a drink in your hand. So what I do to prepare, and I actually did this last night, is I have a generous handful of my Gundry nut mix before we head to the party. I'm satiated. The alcohol is not going to be absorbed very quickly because my stomach is full. And then I'm not that interested in what is on the appetizer platters. There are some great nut butter alternatives. As many of you know, peanut butter is not a nut. Peanut butter comes from a peanut, which is a legume. They're loaded with lectins. The vast majority of us are sensitive to the peanut lectin. Almond butter is an okay alternative, but almonds have a lectin in their peel. There are several companies that now make peeled almond butter, and that's a go-to for many of my patients. But there are other alibi more expensive butters. Pistachio nut butter is great. Hazel nut butter is great. Peeling nut butter is great. Tahini, not from a nut from sesame seeds, is great too if you're looking for kind of that similar mouth feel as peanut butter. So get yourself some new spreads. Ditch the peanut butter. And please, if you're going to use almond butter, get the peeled almond butter that you can find in stores or on Amazon. Avocados.  You should have an avocado every day. Studies have shown that people who eat avocado every day lose weight compared to people who don't eat avocados. Studies have shown that avocados in a salad or mixed in with vegetables make you absorb more of the vitamins and nutrients and polyphenols in those food than if you didn't have the avocado. It's loaded with monounsaturated healthy fats like oleic acid, which is the major fat in olive oil. Loaded with antioxidants, vitamin C, vitamin K, and the B vitamins. There's more potassium in an avocado than a banana.  Should you use avocado oil and ditch the avocados? Well, while avocado oil is a good high smoke cooking oil, it doesn't have near the polyphenol content of olive oil.  Guacamole. Have some guacamole in the refrigerator. There are a number of companies that now make guacamole without tomatoes, which is not supposed to be in guacamole. Or use those avocados when they're starting to get really ripe and make your own guacamole. And use like Belgian endive as your dipping chip for guacamole and you'll get a win-win. Alright, MCT oil. It ought to be in all of our pantries. MCT oil, as you know, is medium chain triglyceride oil. You're going to get all the benefits of a ketogenic diet by using MCT oil without the hassle. Because MCT oil is rapidly absorbed through the wall of your gut, goes directly to your liver and makes ketones regardless of what else you're eating. So you don't have to go through the trouble of eating a very high fat diet or a low carbohydrate diet or even doing long-term fasting to get the benefits of MCT oil. You should also have extra virgin organic olive oil. And please buy it in small glass containers because once you open olive oil, it will start to go bad. And you should look to use up this olive oil very quickly.  Sesame seed oil.  We now have it available at Gundry MD. It's sourced from our same providers in Morocco that our olive oil is. It's another great addition to your diet and put it in salad dressings, pour it on vegetables. It'll add a great taste and it's loaded with fighters against these LPSs that get into your bloodstream and cause high blood pressure. Finally, dark chocolate. Have a collection of greater than 72% dark chocolate in your cabinet. Chocolate is loaded with polyphenols. Again, the higher the cacao content, the better it is for you. Have yourself one square a day. It's perfect for dessert, whether you want it or not. Look for stevia sweetened chocolate like lilies. Costco now carries a big bag of stevia sweetened chocolate chips by a company called Bake Believe. There are on the market alieolus sweetened chocolate. I'll mention one. I have no relationship with Gatsby chocolate is sweetened with alieolus. You can find it on Amazon. Check out my most recent episode all about the amazing benefits of chocolate to learn more. Recently, there's a new study making the rounds and this comes around every few years that there are levels of lead and levels of cadmium in chocolate. Somehow, this is exciting new news. Folks, we've known that there is lead and cadmium in chocolate ever since these levels have been measured. Do not let this fear-mongering dissuade you from the benefits that you will derive by eating dark chocolate. Study after study after study of people who have dark chocolate cacao in their diets.  So, please don't see this latest news about lead and cadmium in chocolate dissuade you from having chocolate in your kitchen and enjoying it every night. The next episode of the Dr. Gundry podcast is waiting for you now. Incredibly life-changing stressful events can have the effect of causing leaky gut in and of itself.