Good morning everyone. I've walked on stage without the clicker here. Did someone in a... voila. There we go. Most important thing. Welcome everybody. I see we've got a bunch of folks in the crowd. I think probably most of you are from Europe given that all the Americans are still sleeping in their hotel rooms right now. I strongly suspect. All right. There's a few of you here who are saying no, no, no. I'm up. I'm up. But welcome to our open source summit Europe. It's nice to be back in Europe seeing all of you. COVID has definitely given us a long break from seeing each other in person. How many people here... this is your first event since sort of pre-COVID. How many of you? Wow. Quite a lot. All right. Wow. That is amazing. Well, it is really, really good to be back face to face. And as you all know, business travel has gotten more expensive and much worse. So I really doubly appreciate all of you coming here today. I want to first start out by thanking our sponsors. In particular, I want to thank our diamond sponsors. Amazon Web Services is one of our first time sponsors. Google and also IBM. Without their support, we couldn't do these kind of events and we're really grateful for it. In addition, I want to thank our platinum sponsors, Erickson, Huawei, Intel and Open Oiler. Again, we would not be here without all the support of these sponsors. Finally, I also want to thank our program committee chairs who did an amazing job reviewing content for all 13 microconferences here at Open Source Summit.  And as I've gone around and visited the different microconferences, it's amazing how deeply people are engaged in all of these communities and still come together in the evening for our social events and have a ton of fun. So it's really gratifying to see that that is working. And I again want to thank those program chairs. A few more announcements. Our sponsor showcase is in the forum on the ground level. Please stop by and check it out. There are coffee breaks and ask experts sessions as well throughout the venue. The showcase opens daily at morning breaks and is open during lunch as well. You can find lunch concessions in the back of the room if you'd like to stay on site during lunch hour or you can go off and find lunch on your own. The Wi-Fi information is on your conference badge schedule there. So see if the Wi-Fi will actually work for you. I think it's been pretty consistent this week. So check that out. And then don't miss the onsite attendee reception and booth crawl this evening in the forum which starts after the close of breakouts this evening. Finally, I want to mention that we have an event code of conduct that everyone has agreed to abide to. You can find it both on our event website, but in short, everyone should be feeling welcome and included in this event. Please treat everyone professionally and with respect. And if you have any concerns at all, we have staff all over the building just please go and approach either the info desk on the ground level or the event team anywhere throughout the venue and they will certainly assist you. So again, welcome back everyone after a long break in seeing each other in person. Today we have three big announcements from the Linux Foundation that I'm super excited to show all of you. One of them, Mark Zuckerberg, broke the news on Monday on Facebook ahead of this event, but we'll talk a little bit more about that in a few minutes. But first, I just want to kind of look at where we've been over the last couple of years here during COVID and how excited I am to see each of you again here in person. You know, we have been super busy as we were all staying at home at the Linux Foundation working away. And at the beginning of the pandemic, we weren't sure what was going to happen. You know, our events team did this amazing job of, you know, dealing with winding down all of the different event commitments that we had, you know, helping renegotiate hotel venues, conference contracts and so forth. And after we kind of got through the storm of that initial period during COVID, we hunkered down and really went to work as an organization and as part of the broader open source community. And what I'm really happy to see and report is that the projects at the Linux Foundation are really having a huge impact in a massive variety of ways. You know, we're a nonprofit and open source is something that's a freely available public good that anybody can use for whatever they want to do. And when you're that kind of an organization, you don't really measure your success by the number of members you have or your financial position. Members are still important. Having money to be able to facilitate this kind of co development is also important, but the most important measure is impact. And if you go around today and talk with folks in the micro conferences that are going on or go to sessions about many of the Linux Foundation projects that are out there, you'll realize that these projects are having real meaningful impact across the world. You know, not just in really impactful horizontal technology, things like Kubernetes and Node.js, but also in vertical industries. Our Linux Foundation energy initiative is a great example of that. That project was born here in Europe with RTR in France, one of the grid operators there that decided they would open source the software that they're developing to make a smarter energy distribution system. By open sourcing that, they could co develop that software with other grid operators around the world in order to reduce the amount of energy that's wasted as it's distributed across the energy grid in order to help impact and improve climate change. It's an incredible effort. It shows where open source can directly have impact in our daily lives. Our Academy Software Foundation continues to make progress. This is something that took two years of negotiation across organizations like Disney and Pixar and Lucas Films to open source the software that's used to create the digital effects that all of you love when you go and watch a Star Wars or a Marvel movie. By having all of that software in open source, the film industry was able to improve the way that they create those special effects and has really had an impact in the quality and the beauty of the stories that they tell and that all of us love. It's just another example of where open source is having a direct impact on all of our lives. Our Linux Foundation Networking Project has had an impact in the telecommunication sector. That's gone through a multi-year transformation of abstracting hardware-based networking equipment into software-defined networks and then further automating the orchestration of that software so that it can be deployed easily and quickly to support the scale out of advanced 5G networks around the globe. It's an example where open source has really reduced the cost of network equipment and facilitation and improved the quality of the network for billions of mobile users worldwide. And you know, it's that kind of impact that we consistently measure ourselves by at the Linux Foundation. If you haven't seen our LFX platform yet, go check it out. This is a place where we measure our impact in a variety of ways, particularly Insights tool. You can go in, look either in aggregate or project by project at the number of developers in our ecosystems, the mean time to average pull request resolution for a project. Maintainer satisfaction surveys exist there and much, much more. And when I look at that data across the whole Linux Foundation ecosystem, almost every metric is up and to the right. And where we see projects struggling in terms of resolving code review issues because they don't have enough resources or they're falling behind on resolving pull requests. We're building new tools and new ways to work with those communities to help them advance and improve the developer experience for that important open source code development. And we'll see more and more of that as we continue to progress on that platform. And as the Linux Foundation continues to grow. So as I said, we haven't been wrestling on our laurels during COVID and I'm really excited to show you some new projects that we're rolling out this week. But before I do that, I do think it's important to talk about the one big challenge that open source is facing, particularly in light of the log forage security incident, which happened last December and has had major repercussions in terms of how people think of open source relative to security and trust. You know, I love to tell this story about how open source today is really the dominant way that software gets developed. And you can see that based on the impact that it brings to the table. 90% of the code and most modern technology products or services is open source code. And then maybe that final 10% is proprietary code that companies use to service their customers or some kind of special innovation that they're using on top of it. But almost every modern technology product service uses the hundreds of thousands of open source building blocks out there to really build the core of their products. And because it's so ubiquitous, it comes with a real security responsibility. That same kind of ubiquitous deployment happened at Microsoft kind of in the early 2000s and late 90s, where Microsoft was also this dominant platform for most modern computing systems. And I don't know if anyone remembers back in 2003, 2004 when Bill Gates wrote a letter to all Microsoft employees around cybersecurity and trustworthy computing. At that time, Bill Gates would write a letter every few years about an important thing that was happening in technology. Previously, he had talked about the impact of the internet or the importance of mobile computing. But this time, he was talking about security. And in that letter, he said, we are going to stop working on the software we're producing now until we do comprehensive code review, until we train our employees on secure coding techniques, until we dramatically improve how security works in the software development that we're doing at Microsoft. And at that time, Microsoft had about 50,000 employees, not all of them were engineers, but really everyone in the company was forced to go and do this comprehensive security effort. So to fast forward to today, where open source is this ubiquitous building block for most modern technology products or services. But instead of 50,000 people, open source is produced by, and this is according to the latest figure on GitHub in terms of the number of developers on that platform, which is just one measure of developers, is being produced by 75 million developers worldwide. Just at the Linux Foundation, we have 750,000 developers who work across all of our projects every single day. So in that world, we can learn from the substance of what Bill Gates was saying, we should all go and take secure coding courses. We should do a better job of testing code. We should have better CICD tools for making sure that we can catch security vulnerabilities. We should have better responsible disclosure policies. We should have a security mailing list that people know how to contact and so forth. But unlike Microsoft at that time that only had 50,000 employees where you could have said, hey, you either take this course or you're fired. How are you going to fire 75 million people if we don't do this work? And so the answer is, with that challenge, we have to create a culture of secure coding in open source. We have to think of better ways to transparently provide tools, audit services and funding to open source maintainers so that they can adopt that culture of secure coding. And we can have a new era of even more trustworthy software because unlike in the proprietary world where Microsoft did make real improvements to the security of Windows, in open source, we can actually all measure the improvements of security in open source and know it. It's totally transparent and visible to all. It's literally the best of both worlds if we can achieve it. This week, the open source security foundation is meeting here in Dublin as well. And I encourage you all to go look into the work of the open source security foundation and look at the 10 point comprehensive plan that that organization has developed. It is literally the first time stakeholders from major technology companies and leaders in government have gotten together and really written down what are the things we can do to create this culture of secure coding in open source to improve the trustworthiness of open source in a meaningful way. Educating developers for free, providing free tools to developers to improve their code and catch vulnerabilities. Providing cryptographic signing to package management tools so that we know that the distribution of software is safe. Creating software bill of materials metadata ubiquity using specifications like SPDX and instrumenting that into the entire supply chain. If we can achieve the goals within that plan, we will really not only meet the moment where people are looking at open source and wondering if it can be trusted, but we will usher in an even greater area of trustworthiness in open source. So I really encourage you to all check that out. Open source is without a doubt the most important way that people create software today. And with that, I want to introduce a new project at the Linux Foundation that is one of the most important projects in a certain sector of computing. And that is AI and machine learning. Today we're announcing, and this is where Zuckerberg jumped the gun on us, but we're still happy he posted, we're announcing that PyTorch is a new project at the Linux Foundation. And I'd like to invite Dr. Ibrahim Haddad up here to talk more about the PyTorch Foundation. Ibrahim currently serves as executive director of our Linux Foundation AI and Big Data Foundation, and he will also serve as executive director of the Python Software Foundation. The reason we're so happy to have Ibrahim helping us is because in particular Dr. Haddad has a PhD. And the world of AI and ML, if you don't have a PhD, you just don't seem to get the same kind of respect. I'm sort of persona non grata in that world. So with that, let me welcome to the stage Dr. Ibrahim Haddad. Good morning everyone. My name is Ibrahim Haddad. Thank you Jim for having me and I'm so glad I did my PhD. Hello to everyone joining us remotely as well. As Jim mentioned, I am the executive director of Alpha AI and Data and as of today also the idea of the PyTorch Foundation. I'm really glad to be here today to talk to you about the PyTorch Foundation and I think before I step into this, I would like to give you a little overview of how we got here. So the next foundation started investing in the AI, open source AI and data space in 2018. And we started to track open source project within that ecosystem. So what you see on the screen behind me is the open source data and AI landscape, which is available online. And when we started this exercise in 2018, we only had about 70 projects on that landscape. Fast forward four years today, we have over 330 projects on that landscape. These are key and critical projects in the whole ecosystem. They represent over 40,000 active developers contributing and have contributed so far over 500 millions lines of code. And what's really amazing is the pace of innovation where every week we're seeing on average one new million line of code added to the ecosystem across all of these projects. So it's really an amazing ecosystem, fast growing and representing thousands of organizations that are participating in it. So when we started LFAI in data, we started with nine members and one project. Today, through the Linux Foundation investment in the space, we're hosting 41 projects. And what I'm really proud most of is the fact that we have over 17,000 developers active in our communities. And these 17,000 developers, they're coming from over 550 organizations that are interacting with us on a daily basis across our projects. So for the past four years, we've been working to really address some challenges in the ecosystem with respect to fragmentation across projects, lack of collaboration, lack of cross-integration across projects, and lack of implementation of integrations. We've been addressing challenges with respect to open governance, with respect to managing projects assets and several others. And today, I'm really happy to be here because this represents another milestone for the Linux Foundation in terms of investing in the space and really a massive commitment to open source from Meta, the founder of the PyTorch project. So Meta started PyTorch project in the year of 2016. And for the past few years, it's been really a monumental project. It grew to represent a huge and built up a huge community of developers, thousands of organizations. And today, the announcement is basically transitioning the PyTorch project into the PyTorch Foundation. And the goal of the PyTorch Foundation would be to enable the project, to provide funds for the project in support its community, its needs, and to provide the services that the project requires to grow even further and transition it into a host that is a neutral foundation. What's really impressive further is the fact that the project has over 2,400 contributors to it. And there are over 18,000 companies and organizations that rely on PyTorch as a dependency for their projects for the AI services and stocks. So by any of the metrics mentioned on the screen, it's really a fantastic project and really the ideal project to have any foundation to ensure long-term sustainability for the project under a neutral host. For the past few months, we've been working with the founding members of today's PyTorch Foundation. You see them on the screen, Amazon, AMD, Google, Microsoft, Nvidia, and of course Meta. And it's been really an amazing experience to work with these organizations that are coming together to form the board members of the PyTorch Foundation and support financially the foundation in standing it up. And it's been six months of thousands of emails, a lot of phone calls, hundreds of Zoom calls, and everybody across all of these companies had a hundred percent full commitment in supporting the PyTorch project being in a foundation and transitioning it into open governance. So for those we've worked with in this organization listening to us today or maybe in the whole today, thank you very much. It's been really an amazing experience to work with you. From Linux Foundation, this is an additional investment on our side as we are further investing in the project, both in terms of resources and in terms of funding. So in addition to transitioning to the open governance model, we will be providing dedicated staff. As Jim mentioned earlier in a few minutes, I will be acting as the executive director of the foundation and we're also looking to hire staff to support the project and the foundation. So for those who are listening to us today, you can check out the career website if you're interested in an opportunity with the PyTorch Foundation. In addition, we have the LFX platform that will act as a portal for the community, providing various services, and at Linux Foundation, we will be supporting the PyTorch Foundation in various areas such as legal support, marketing, outreach, events, training, and even certification. On the training side, I'm happy to announce as well that yesterday we announced a new project that is a training course available for free, PyTorch for executives. So if you're interested and you're an executive in your organization, you're interested to learn more about the PyTorch and how it could help you be part of your building blocks internally, please sign up to the course. It's complimentary. And we have additional courses that we're working on that will come up and be available in the near future. Today, we only have humanists on stage. However, we have later on today at 3.15 p.m., we have a one-on-one sit-down with Sumit Chintala. Sumit is one of the co-founders of the PyTorch project. He is the lead maintainer and he is a senior AI researchers at Meto. He was with PyTorch since the beginning and even was torched before that and with its pre-disessors. I would love if as many of you can attend the session 3.15 later today, you will also have the opportunity to ask Sumit questions as well as myself and have an interactive session. Plus, we also have the PyTorch booth at the exhibition hall. So you're all welcome to pass by the booth. We will have PyTorch developers and maintainers that are available to address any questions you may have about the project. I think in closing, we will have a number of announcements in relation to the PyTorch project and the PyTorch Foundation. I would like to invite you to join our social media channels to visit our blog because this is where we will make these announcements. The announcement today is really historic. PyTorch is really a massive project, extremely successful and transitioning it to an open and neutral foundation is really a massive step towards even further success for the project and a clear commitment from the founding members of the PyTorch to open source and to the transition to open governance. So thank you to all of those who worked with us on this and I wish you a great conference. Hope to see you at 3.15 later tonight. Thank you. Congratulations again. I mean, this is an amazing project. You know, something like PyTorch and I think I may have said Python earlier because I had it on my mind, my young daughter was showing me literally before I got on stage some Python code she had written at school. But it's PyTorch. One of the things that's really interesting is PyTorch is a lot like kind of Kubernetes is in Cloudland, right? It's the sort of fundamental building block. And what's interesting is as you look at CNCF today, it's such a bigger ecosystem because all these different adjacent technologies blew up to make the deployment of Kubernetes in containers much easier. I mean, do you think we're going to see stuff like that happening around PyTorch as this whole ecosystem expands and, you know, the work in the open continues? Yeah, absolutely. I think one of the agenda items we have is enabling AI tooling around PyTorch. So, similarly, Jen, to what you said in terms of Kubernetes, and you've got all these different tools and projects around it, one of the goals that we aim for is continue, of course, the growth of the PyTorch project, but also work more actively on the ecosystem of tooling around it. So that when you pick up PyTorch, you've got a set of host of tooling that is available for you in supporting roles given whatever task you'd like to achieve. Absolutely. I mean, I can't wait to see how, you know, we can help grow this ecosystem and make, you know, AI and ML technology easier to create, easier to deploy, easier to maintain.  All right. Well, our next big announcement is about something that I think all of you can relate to. How many of you use a digital wallet? I can't really, I want to say that's like 70%, so quite a few. And how many here use an Apple wallet or an Android wallet? One of those two. Pretty much the same hands, right? You know, digital wallet technology is increasingly an important part of our lives, not just for payments, but today in the United States, two U.S. states are enabling your driver's license to become digital and be contained inside your digital wallet. Car companies are distributing digital keys. You can put the keys to your BMW in your digital wallet today. Membership cards to health clubs, your health and insurance information, all of these things are increasingly being contained in digital wallets. And today we're going to talk about a new project at the Linux Foundation in this area that we think will provide for a more open, equitable, and interoperable digital wallet ecosystem. Our next speaker is going to tell you a bit about it. Daniel Goldschleider is the co-founder and CEO of Yes.com and a advocate for digital wallets. He has been the big impetus behind bringing this project to the Linux Foundation and today we're going to hear from him about it. So please welcome, Daniel. Thank you, Jim. Thank you, everyone, for listening to this first presentation of the Open Wallet Foundation. It's really a privilege to introduce this to you, but before I do, I want to thank the Linux Foundation. The fact that you're here probably means that you're all in love with the Linux Foundation already, but in the event that you are interested to ever start something new, come find Mike and Scott and Todd, it has been nothing short of amazing to work with them in the past couple of weeks and it's really great that the Linux Foundation is going to be the home for this and I'm not just saying that because Jim is giving me 10 minutes of his keynote time. So what is the Open Wallet Foundation? It is a chapter of the Linux Foundation. It will have its own dedicated governments. It will have its own budget and it really has a singular mission. The Open Wallet Foundation is going to make it easy for third parties to publish their own wallet. And this is really critical. The Open Wallet Foundation is not going to publish a wallet. It's not going to issue credentials. It is not going to create standards. It is not trying to compete with W3C or the FIDO Alliance or the OpenID Foundation or Trust Over IP. We leave standards to the standardization organizations but we are going to use these standards to build a common core shared software that anyone can use to publish their own wallets. Now when you look at the open source core for these wallets we have a couple of goals. One is we want to enable a plurality of wallets and we want those wallets to be interoperable. We also want them to be secure of course and we want those wallets to be multi-purpose wallets. When you think about an analogy the one we've been using in the past are browser engines. If you're using Google Chrome or if you're using Microsoft Edge or maybe Mozilla Firefox you've taken advantage of browser engines. Products like Blink or Gecko. And these browser engines are supporting a lot of standards. They're supporting video codecs and they're supporting HTML and HTML5 and there are a lot of things that factor into browser engines. To us this is a role model for how we see wallet engines in the future. I talked about multi-purpose. I don't know how many of you are working on wallets but some of us in the space when we think about wallets we think about digital identity. We think about essentially a container to hold maybe an electronic driver's license or maybe a zero-knowledge proof for a government ID. And of course that is really important for wallets. Other people maybe in the financial industry when they think about wallets they don't think primarily about identity. They think about tokenized credit cards and debit cards. And maybe if you're in the automotive industry you think about wallets as an important place for car keys or maybe digital room keys or maybe a future home for FIDO pass keys. Imagine you're interested to buy a physical wallet and I'm trying to sell you a physical wallet and you like the design and you're interested to take the wallet and then I tell you oh but one thing I should tell you about this wallet will only work for your driver's license. It will not work for your credit cards. You would likely not be interested in that wallet, right? You would say what kind of wallet are you trying to sell me? You expect a wallet to work for anything. And before I flew to Dublin my youngest daughter asked me what this digital wallet foundation is about and I explained the same thing and I talked about FIDO pass keys and car keys and she said you forgot the most important thing. Photos. So I'm not sure if family photos of your kids are going to be part of it but the idea really is to have feature parity with physical wallets and the best wallets out there. Interoperable. Of course we're going to work with existing standards. We don't try to reinvent standards but really to use the best standards that are out there today and to ensure that we come up with open source software for these standards. We believe this is absolutely critical to achieve interoperability. I am a huge believer in open source software. I think open source software inherently provides an opportunity to create really safe and secure pieces of software but the intention of the open wallet foundation is also to act as a steward and as a shared effort to ensure that the resources that we are creating that the software we're creating is safeguarded as much as possible because obviously when it comes to wallet security is absolutely paramount. Of course this is going to be open source software so anyone can run, inspect, modify, redistribute the source code. You can sell your own copies of the code as long as you use the same license but we want to be open not just quote unquote in the license for the software. We want the open wallet foundation also to be a home for open discussion. Wallets are still pretty new. We are at the beginning of this game not the end and we really encourage anyone and everyone who's interested in this space to come together and have a discussion about what the technologies, the protocols, the standards are that should play an important role in the open wallet foundation. Today is the day where we announce the open wallet foundation. If this was a baby, the baby is not even born yet. We're going to formally incorporate hopefully before the end of the year but this is an announcement of a pregnancy basically. We were saying there are a number of parties that came together over the past couple of months to discuss the need for a shared foundation for wallets. If you're interested to be there this is essentially a warm welcome to join those discussions and to become part of what we're trying to do. If you're interested to learn more please come to our panel today just shortly after noon. We'll have I think almost 15 people talk about the open wallet foundation. You'll hear from a diverse group of people from some of the world's largest companies as well as some of the world's most influential not-for-profit organizations. And it's really a panel that is trying to convince you to join, to become part of the open wallet family. If you care about payments, if you care about digital identity, if you care about a plurality of wallets that are interoperable please do think about joining that panel discussion. And if you're interested to learn more we have a brand new email address that is up here info at openwallet.foundation. We are really interested to hear from you because at the very heart of what we're trying to do is a plurality of people. We're going to either be successful or we're going to fail because of the people who are part of this effort. If you care about the future that we started to describe here it's really up to you. It's up to all of us to come to the table and to be part of an effort to ensure that identity is something that belongs to all of us. Thank you very much. I love it. You know great things come from small beginnings and I think this is a pretty amazing beginning. You know the thing I love about this project is just the sheer ambition. And you know I've been working at the Linux Foundation almost 20 years now and I can't count the number of times I've heard things like oh you'll never be able to compete with proprietary operating systems. Oh free certificate authority that'll never work. You know and then Let's Encrypt became the world's largest certificate authority. Linux became the most dominant form of computing. Oh you're getting everybody to move off VMs to this way too difficult to use container orchestration tool that'll never work. And yet now Kubernetes and containers are the ubiquitous platform for modern computing. So I think we've got another one here it just in this sheer impact that something like this can create in people's daily lives and I am certain that we're going to be successful so I really appreciate you coming here and talking to this group today. Thank you very much for the invitation. All right thank you Jim. Cheers. All right.


Hello everybody! Watch this video to find out how to recover data from a RAID system based on a Western digital NAS, how to create a RAID, how to add a shared folder, and how to retrieve data from an inoperable NAS. Hello friends! If you need to recover deleted data, view or restore removed browser history. Hetman Software products will help you. Follow the link in the description, download the necessary program for free, install it, and analyze the disk. The utility will show you the data you can recover, so you will be able to view it or get it back. In our channel and blog, you will find solutions to any problem, from installing an operating system or configuring it, to fixing possible bugs and errors or optimizing mobile gadgets. Our specialists will answer any questions you ask in your comments under the videos or articles. A network storage for NAS for short is a computer device used as a file server to let various client devices access certain data. Usually, such devices are based on RAID technology, which enables them to combine several drives into one big storage space, as well as improve reliability and data security. However, even the most reliable RAID type in the world cannot prevent data loss completely. The chances of hardware and software errors, run configuration, accidental removal of files or disk formatting depend very little on how reliable your RAID setup is, and any of these scenarios may result in losing an entire pool of very important information. Recovering data from an S system involves taking the device apart, connecting the disk directly to another computer, and using specialized data recovery software to retrieve the information. NAS devices usually run on Linux, so their volumes are formatted in Linux-supported file systems such as EXT, XFS, and BetterFS. When choosing a data recovery tool, make sure to check file system support features. In today's video, we will explore a step-by-step data recovery process with the server WD-Share Space supporting the installation of four hard disks, module WD-A4NC40000. For starters, let's find out how to build a RAID array, for example, a RAID5 system. Open the Management menu for NAS WD-Share Space, then go to Advanced Mode, jump to the tab Storage, then click on the tile for Volume and RAID Management. By default, after installation of the operating system, it creates a spanned volume, with all the disks connected to the device at the moment. In other words, all available disks are combined into one. To change the RAID level, select the one you prefer. In my case, it is RAID5. Click Submit to proceed. You see the warning that all data will be erased, and it takes 16 to 17 hours to rebuild the RAID5 volume. Click OK. The rebuilding process begins. Note that the RAID configuration has been changed successfully, resinking and formatting is in progress. Here is the RAID5 volume, consisting of three disks, and the last column displays its status – Recovery. All you do now is wait for the process to be awkward. Then create a shared folder and write your data to the disk. While the RAID system is being rebuilt, let's enable the FTP network protocol to access the storage. Open the tab Network, jump to Services, and enable FTP by checking the corresponding box. Then click Submit. When the disk array is rebuilt, you will be able to create shared folders. Open Storage, jump to Folder Shares, click the plus button to add a new folder, give the name for this directory, some description, check Network Services, and click Submit to confirm your choices. Now it's time to configure access to this shared folder. I will enable public access by checking this box and clicking Submit. After that, it becomes accessible, so you can go to the network drive and write your data there. High-grade software failures, product configuration, accidental removal, or formatting may cause a major data loss from disk storage inside your NAS device. In any of these situations, you will need a reliable tool to get your information back. Headwind RAID Recovery is a comprehensive solution for NAS data recovery to help you restore your files in several different scenarios. The program supports the most popular file systems including those used in NAS devices. It features an automatic advanced scan mechanism that will file the information needed for recovery, such as RAID first sector number, block size, number, and order of disks. NAS information can be recovered based on single drive solutions and large disk arrays combined into various RAID systems. Bear in mind that before starting data recovery operations, you should prepare some free disk space with the capacity equal to the amount of data you are planning to recover from your NAS. Take the disks out of the NAS device and connect them to a Windows computer. Make sure that all disks are recognized by the Windows integrated disk management utility. Right-click on the Start menu and select Disk Management. If you are suggested to initialize the disks, don't agree. Disk can erase the remaining data for good. If you are trying to recover data from a RAID 5 system and the motherboard of the computer where you want to connect the disks doesn't have enough setup ports for all those hard disks, you can connect all but one disk because this RAID type remains operable even if one of the disks is missing. Install and run Hetman RAID Recovery. Thanks to its automatic scan feature, the utility will analyze the disks, read their service information, and rebuild the damaged RAID system. The brief RAID information is displayed below. If the program has read it correctly, if the properties were detected with errors, you'll have to build the array manually in the RAID constructor. Right-click on the disk and open its properties to see more details. Select the scan type and start the analysis. The program will analyze the disks and display their contents when the operation is complete. As you can see, it has found all the data stored on the disk array, and in the case with RAID 5, everything works even though one disk is missing. Select the files you want to recover, click Recovery, select what you want to save them, and click Recovery again. When the recovery process is over, you will find all of the files in the folder you have chosen. This program can also recover data after disk formatting or accidental removal of files. After the scan is over, you will see the deleted files. They are marked with the red cross. To help you search for specific photos, videos and documents, more efficiently, there is a nice preview feature. Select and recover accidental deleted data. When scanning a RAID that used to have an operating system, the program shows you several disk arrays, a mirror RAID containing the operating system, and a RAID 5 containing the data. If you want to recover information from a system folder, scan the mirror RAID which stores system files. When a RAID recover is very easy to use, it will automatically find the information needed for recovery such as RAID for sector number, block size, number, and order of disks. When a disk is damaged or service information is erased, the program may have difficulties with rebuilding the RAID automatically. However, you can do it manually, with the RAID constructor if you know the properties of this damaged array. Open the RAID constructor and select Manual node. In filling all the information you know, the RAID type, block order and size, add the disks it used to include, use the arrows to set their order, and replace the missing disks with empty drives by clicking the plus button. Usually, if you give correct properties, the newly built RAID system has at least one partition. Expand it to check for the folders that you need. If the folders you are looking for are displayed, then you have built this RAID properly. When all the properties are given, click Add for the RAID system to appear in the Drive Manager. For recovery, scan the array you have just added, look for the files you need, select and recount them. And that is all for now. Hopefully, this video was useful. Remember to click the Like button and subscribe to our channel. Push the bell button to receive notifications and never miss new videos. Click Comments to ask questions. Thank you for watching. Good luck.


So, we will start with the idea of continuation and then talk about the thing called continuation passing style and with time permits we will also look at implementing interpreters using continuation passing style and also try how we can implement called cc in your own like continuation in a language. So, yeah, so this is the idea the brief outline of the talk idea of continuations and we will spend a lot of time there and so we will use scheme. So, the scheme has this thing called called with current continuations. So, we will spend some time with that and we will also talk about tail call optimization already we there was another talk about tail calls and how to do tail calls we will see yet another way of achieving tail call optimization then if time permits we will write a toy scheme interpreter and implement the same using CPS and also implement called cc. Anyway, I will put the code out there if time is in sufficient little bit about me I am basically an electrical engineer mostly self taught programmer work for this company called conquer technologies where we are trying to scale the back end using some functional programming techniques and have contributed to a few free software projects. So, very brief introduction about scheme we will be using scheme here I think we have already looked at closure code and also other lists code in the other talks, brew states talk also had I think the more tense talk had some scheme code there. So, scheme is called by value it is eagerly evaluated and it has expressions. So, first the first thing in a expression is assumed to be a function and rest of them are operators and you can override that with the code and change code to data and back to code and there are very few built in constructs and other thing that we take for granted which is lexical scoping first appeared in scheme I think it first appeared in Algold, but yeah it is a one of the first list that got lexical scoping right and then functions as first class and usually these things are covered in most of the introductory programming courses that use list, but macros and call cc those are considered to be some of the difficult parts to understand in scheme. So, yeah one of the thing is what I am trying to cover in this lecture the other thing is that my goal for this talk is that you go back with some understanding of continuation I had a lot of difficulty understanding continuation. So, my goal is that you go back with some intuition about continuation so that you can look up you can look up by yourself and understand more and at any point of time place interrupt and ask questions during this talk or later or any point of time yeah. So, yeah this is the famous quote that is used at the starting of the r5 rs standard the scheme revised report on scheme programming languages should be designed not by piling features on top of features, but by removing weaknesses and restrictions that make additional features appear necessary. So, continuation is one such feature it is like one of the primitive things on top of which you can implement a lot of other control concepts we will see at least one or two of them ok. So, let us say we want to add two numbers very simple we just want to add two numbers. Let us say that you are reading the first number from somewhere and then you are reading the next number you are adding it and displaying it. So, read number could be so this could be say in a web scenario where you are asking input say toy example say you are asked to input first number on a web page you have to press a submit then you are asked to enter the second number again press submit and gives you a number two or whatever number 42 or whatever. So, when you press when you enter the first number and when you are asked the second number the web server has to remember that you have already entered the first number. So, there is a computation suspended out there which already has which knows what it needs to do once you have entered the first number right. So, this you can encapsulate it in a function that what it needs to do once I have read the first number it is nothing but a function takes the first number as a parameter then it reads the second number and thus the addition and gives you a result. So, continuations are nothing but rest the rest of the computation that you need to do but rest after what so after some context that is you have done some work now. So, once you have that value what you need to do to complete the rest of the program that is what is continuation. So, let us take the first expression there that is you are multiplying 3 and 4 adding it with 5 and giving back the result. Now, let us look at 3 when you are looking at 3 what is it what is it that you need to do to complete this computation which is nothing but at the point of 3 we have put a question mark there. So, given 3 I need to multiply it with 4 add it with 5 give me back the result. So, you can that is what is shown in the next 2 expressions. So, you if we is 3 then we compute it using a let expression there. So, let is nothing but syntactic sugar over lambda right that is you have a let you can transform it into a lambda expression it is a function application. So, once you are given 3 you just apply it and get the result. Now, if you really see that the function the first function the function the lambda expression. So, that is that is really the continuation that is what you need to do once you get the value 3. Is this clear this much of it is clear anything unclear about it. Yeah, so, forget about compiler right now think about a program execution in an abstract way. That is let you are sequentially executing a some program at some point what is the rest of the program can you encapsulate it in a in a function that is what continuation is continuation is nothing but a closure that takes one value as a parameter that value is nothing but the computation we have done as of now once I am given that value what do I need to do rest that is encapsulated by this function and that is what continuation is above any other questions is it clear whatever is whatever is explained as of now. So, now, if you see any program implicitly has a continuation only thing is that most of the languages are not explicit about it does not languages does not allow you to capture continuation into a variable. Continuations are not first class in most of the languages any C program or whatever program an assembly program you have continuation that is you always have a rest of rest of the computation right. So, let us take another example same the same expression. Now, let us say we are evaluating that expression before evaluating what what is the continuation of that let us say you are inputting that expression into a ripple what is the continuation of the program you have to just return the results right that is the continuation you just have to return the value. So, the continuation of that is an identity function. Now, let us say you are looking at the inside expression star 3 and 4 multiplied 3 and 4 what is the continuation of at that point it is once I get 3 and 4 multiplied I need to add that value with 5 and return the result that is a continuation of that program at that point. So, you can also say that lambda v plus v and 5 is the context of star 3 and 4 that is what do I need to do to get the entire result given that I am looking at 3 multiplied with 4. Now, let us go still further recursively now you are looking at 3 looking at the star 3 and 4 that is you are looking at it at the evaluation order from left to right let us say. So, when you are looking at 3 same thing repeats. So, I hope you get the idea. So, we are these continuations are only up to the printing of the result at the ripple if you really see the continuations go all the way up to the scheduler right. The scheduler is what is actually calling this program and actually running it. So, rest of computation is going all the way up to a process schedule yeah that is only if the order of evaluation yeah yes. So, if you are converting a program into a continuation passing style or into like explicit continuation then your order of evaluation is explicit any questions this point yeah yeah. So, it never returns if you really see you are actually calling the continuation of the program. So, here if you see the big expression at the first right continuation of that is nothing but a identity function right. So, given the value of that you. So, we are going only up to the ripple here actually there are lot of other things happening after that, but we are not capturing it here. So, there are other things like delimited continuations where you can actually put like you can focus on one portion of the program and say that this is what I really care about the continuation up to this point you could do that, but this is not delimited I am not covering delimited continuation here I am assuming left to right. So, if you actually convert a program into a continuation passing style you have to assume some or you have to make it explicit without that you cannot yeah. So, that is one thing I am assuming here now if you really see this is an alternate model of evaluation or it is an alternate model of thinking about how to do computing right. In a normal Born-Human architecture in a normal C or any Born-Human program execution model you have a stack and let us say function A called function B function A will have its return address pushed into a stack then it calls B then it returns back to the stack and pops out the return address and jumps into that value right. So, we are essentially modeling the same thing with continuation the stack and continuations can really be thought of alternate ways to think about the same thing yeah. So, some more examples to just drive the point. So, what is the context of chart 3 and 4 in this expression. So, as a first step what we do is we replace the expression of interest with a question mark our expression of interest is chart 3 and 4. So, we get that second expression now try to simplify that expression do exactly what we discussed last time that is you wrap the whole thing in a lambda that is your continuation. Now, 0 5 is not 0 right you simplify that. So, the if condition will fail. So, it will take the second branch and wrap it in a lambda. So, that is a continuation of this expression clear yeah one more example. So, again what is the context of chart 3 and 4 first step again yeah I simplified the first step the value as well here in the first step. So, here multiple things are happening. So, we need to wrap it in a begin. So, n is 1 we know that n is 1. So, it goes to the second branch and it has to return the value of n. So, actually I have to return the value 1 there it is a typo there. So, begin so that is what happens there now you wrap the whole thing in a lambda. So, that is a continuation as far as chart 3 and 4 yes the continuation will be different in that case. So, if n is 0 what is what is the rest of the program it will take the first branch right yeah first first display it will take right. So, the continuation is different in that case continuation means rest of the program. So, rest of the program is going to be different in that case yeah yeah agree yeah yeah context of 3 and 4 is irrelevant. You can you do not have to evaluate you can actually find continuation for all possible branches. So, this actually are just for thinking about continuation what is. So, this is not how a compiler will do what a compiler will do is it will do source to source transformation before it actually. So, during compilation time CPS is one path that is it will pass the continuation at every point we will see some examples I am coming to some examples there what is the point here. So, point is that we make control flow explicit right and other control operations like loops non-local exits coroutines or generators you have the yield in python and things like that right. See you can represent all of that in using this primitive you can think of continuation as a primitive to implement rest of the control flow operation. So, that is again if you see scheme that is a that is a theme in the entire language where you have things that can be built from bottom up. It is you have small or very orthogonal primitives at the bottom and you build the rest of the things using these. So, we will see an example of a non-local exit we will not have time to go through generators and coroutines but we will see non-local exit. So, third point there is that continuation is present in every program if you see nothing but rest of the computation right but not all programming languages allow you to capture it in a variable go back to that continuation and things like that. Very few languages support it ML supports it standard ML that we saw Basker talk scheme supports it yeah. So, there are a few such languages. So, that brings us to the construct used in scheme called call CC or call with current continuation. So, call CC has a very weird API but essentially let us look at this example again because we had been thinking about this for a while. So, again come back to the same expression char 3 and 4 that is the context we are looking at. Now, let us say you want to capture the context of char 3 and 4 in a variable this is what you need to do. So, you wrap char 3 and 4 in this expression called call CC. So, call CC call with current continuation that the current continuation at that point of time is passed in a variable called K. Now, that K itself is wrapped in a lambda. So, call CC's argument is a function which takes another function K. So, it is very confusing you can there is another concept called let CC that takes just K. But essentially K is nothing but the current continuation that we had been talking about that K is nothing but the lambda expression that we have written there lambda of V star of V plus that is given the value of 3 and 4 multiplied what do we need to do next that is bound implicitly to the value the binding K. So, now we just return it we are actually not using K. So, K has a scope inside the lambda it has got the scope only within the lambda expression we are not using K there.  So, you can actually apply K to char 3 and 4.  So, what does it do it will just return 3 and 4 multiplied. Now, let us do something interesting define a global variable char K star that is a convention in the list world where globals have this earmuffs you put char on both the sides. So, now what can you do within the lambda you can capture K which is current continuation and set the star K star with that value and it returns back. Now, you can actually call let me try to why does it not show here it shows on the screen oh you have to mirror it does not show anything here yeah it is there, but it is it is not showing the screen it is not it is actually not detecting that device otherwise it is okay. Oh yeah that is a possibility and try to move it into this okay yeah I think it is okay I think I will just talk it is yeah I get this, but I do not get any other application let us say I want to show the racket I just on the star K star we have actually captured the continuation and the continuation is nothing but this function there lambda function lambda of v plus v and 5 that is the continuation. Now, you can actually apply star K to any other value you can pass say 42 into that if you pass 42 you will get 42 plus 5 instead of star 3 and 4 so it is like you have captured the rest of the computation at that point of time and you can go back to that point of time that will also be 17 now K we are not using K is not identity K is the continuation at that point of time current continuation we are not using K there it is just returning that value this expression when you are saying it will compute it it will complete it computer I am not able to show the racket ruffled control goes to the lambda control goes to the expression inside the lambda yes it just returned the last value of it just returned you have a choice to use K and do something interesting with it yeah you are exactly you are placing a marker there you actually captured the marker in a variable K that is all it is using that exactly because we are showing it we are able to come back there just a marker exactly so here there are there is no difference between this the value returned here and the value returned here why because K is the same if I had used a different so K is what K is current continuation current continuation for this expression is what is a lambda function right it has to take the value and add 5 returned result here also it is the same thing so what are we doing here we are essentially calling this lambda function lambda of v plus v and 5 with the value star of 3 and 4 yeah yeah interesting things will happen the thing is here that the continuation K is nothing but this function at the bottom we are now calling that function with star of 3 and 4 which will return the same value 17 understood now if you use another value there let us say you use another value we are actually jumping to the we are actually calling the continuation with the value star 3 and 5 yeah it will not do it will not do it is actually jumping into the continuation that we have captured in K it will not come here that is an important point so you actually you never returned from this value you have actually you have passed the control to another point of time I will show another very interesting example I expecting to spend at least 5 minutes on that we will come to that so yeah so this is actually same thing we captured the value K into star K star we apply to some other value like 20 you apply you get a different value because rest of the computation you are applying to a different value yeah so one one simple application of this let us say you want to I should have called the break as returned here you want to scheme does not have a return expression like in C right you have returned some value now let us say you want to implement return in scheme I think instead of break let us assume return but let us let us say that you are you are multiplying a bunch of numbers recursively and let us say you have if you have if you encounter a zero at some point of time you do not want to just multiply blindly you want to return immediately without doing any further computation that is what you want to do so if you just do recursively you still get the same result but you will end up even if say first value is 0 you have say 1 million numbers you will still end up multiplying the whole thing right now let us say you want to return the moment you enter you encounter a value 0 so what do you do you capture the continuation of outermost continuation you are you are using call cc right at the outside right the first thing you do inside the function is capture the current continuation in a variable break now you look at care of LS the list if it is 0 you call break so it just returns the value 0 because the current continuation that you have captured is nothing but it is just exiting out of the program else you do the usual stuff is this clear this example is a non-local exit yeah yeah it is nothing but a closure it takes one value as input it is nothing but this yeah because break what is break break has break is nothing but a function that represents the continuation at that point of time so what does it do yeah it just did a go to there yeah it returned actually so what does it return it returned yeah come to that what is break what is a break value what will it be it will be an identity function right it is an identity function it is not some lambda it is identity function because we are capturing the break right at the outermost part correct that is what we are returning break 0 returns 0 we do not want to do that that is why we did that right the moment we encounter a 0 we want the control to jump to the place where we are exiting the program we are actually calling the break we are calling the continuation with the value 0 the continuation is nothing but a closure it is a lambda yeah takes one parameter now what is that closure in this case it is an identity function right it is true yeah it is a closure no if you yeah right yes yeah break 0 returned 0 what is it used for that is nothing but the continuation at that point of time right yeah yeah it will not use the else part moment it encounters a 0 it will just return it will jump out to the value it will jump out to the end of the function because break is what break is the current continuation when we started it is the outermost part right if you had put break somewhere else if you had used called no no let us say let us say we are the first example here first example that is it does not have a 0 okay yeah so if you pass the continuation along so you are calling the product with a plus 1 of product something right it will return 121 because the continuation at the break break captures the continuation right what is the continuation given the product I need to add 1 you are not calling but it actually returns that value right so it it it is the same example as this that you are talking about right like you have some value instead of the star of 3 and 4 we are doing that product there but yeah let us say you wrap that call you see inside the product and you are adding some value 1 right so if you just return it will just return that value if you do not use break there it will that is the continuation at that point right so break has actually or k k has k has captured this continuation lambda of v what do I need to do to complete this expression that is what is the context around this expression context is nothing but you need to add some value to the result and return that value okay so nonlocal exit now this is a bit complicated example if you let us spend some time on it if we really understand this I think you can really claim that you really understand continuation now so you have a you have a let expression there is a binding x all it does is called cc lambda of k which is a current continuation k it returns that value k that is what the the x x is getting now in the body of let all you are doing is you are calling x you are invoking a function x with another function lambda ignore high that is a function now this returns high think about it for a minute do not think do not see the rest of the part try to think only at the first part of the expression please do not see the rest and try to see if you really see it so we have captured the value k which is nothing but the current continuation and that value goes into x it prints the value high so to break it down again go back to the same thing that we talked about the steps that we took what is continuation k k is the current continuation at that point right wrap it wrap the whole context of that in a lambda right there is a first step you can do so you wrap the whole let expression remove that calls you see because that is what you that is the context right k is returned context is returned to x so continuation is nothing but a lambda of v assign the value v to x invoke x now what do we do now we invoke that continuation this continuation lambda of v the whole thing now we invoke this with another function lambda ignore high at that point what happens x gets bound to v which is this argument lambda ignore high once again right x gets bound to lambda ignore high and then we invoke lambda ignore high lambda ignore high and it returns high understood this what somebody said no what what exactly you did not understand okay I will explain once again what is the continuation k to call cc or call with current continuation means you are passing the current continuation what is the rest of the computation at that point into the variable k or into the identifier k so k is bound to the current continuation now you are actually just returning k there inside the call cc so that value the current continuation of the current program that I am running gets bound to the identifier x now I am invoking x with a function lambda ignore high now at that point what happens this continuation the second expression there gets invoked with the argument lambda ignore high now what do we do there inside we are bounding the argument that we are passing to x so x gets assigned another value again and then we invoke lambda ignore high with another lambda ignore high and it just returns high understood ignore is a is a parameter right this is what x get got bound to lambda ignore high right yeah now you are just invoking that here ignore is going to be ignored yeah yeah exactly it will be lambda ignore high lambda ignore high and we are ignoring that function returning high yeah exactly yeah you do not need any other special constructs yeah exactly it is a nothing but a here so ignore gets assigned to this value it is an anonymous function right lambda ignore high now you understand okay this is the simplest thing you just apply this function to another function now this whole thing gets assigned to it but we are not using it then it would have invoked this function yeah but you can do some variance of this let us say if you put instead of lambda ignore high if you put something yeah but I hope how you reach there to the last statement I think that is the most important thing how you actually invoke last statement probably not the important thing but how you actually reach there what is the continuation what is the value of k so you can easily break it down using this technique that is you replace the area of interest with a with a identifier wrap the whole thing in a lambda that is your continuation yeah so now now let us say the hello world of functional programming factorial example that is how you write a normal factorial example right so we have 15 more minutes that is how you write a normal factorial example that is if n is 0 you return 1 else you do the example that the continue the tail called optimization talk talked about so you invoke factorial of 5 then you have a triangular like execution model that is you keep you have to store the previous value and yeah it is a normal execution now the case of tail called optimization or if all you if all your calls are tail calls then you get a very different execution state that is you can you can call this as accumulator passing style whereas where in you what you do is you you also have some identity value in an accumulator and you keep you keep adding your accumulating the result essentially folding your value in intermediate values and computing the result so this has a very flat stack or if you can the the fact acc is can be it can be just a jump because you really are not you do not have to store anything to be done after we call the fact at acc right so I think you you will start seeing some very painful so what do you do fact slash k has a continuation k as another parameter so one more parameter it takes at k when you invoke the fact is nothing but identity function you just have to return the value now what do you do now k is continuous actually this k and that k you are confusing I think I should not have used k in the invocation instead of you yeah yeah it should be I just an id it is an identity function yeah I should not have yeah yeah so k k at that point is the current continuation you can you know k always takes one parameter as input that you invoke k with one parameter you can return k k is first class right it is a it is a closure you can return pass it around do whatever you want yeah when you invoke you need to invoke with one parameter takes one parameter yeah yeah sure sure yeah I think it should not be k like I think you should call it n or whatever that is the continuation of this program no they are not continuation yeah yeah that is identity exactly exactly yeah yeah yeah that is that has nothing to do with continuous it is a wrong usage so what is happening here so we converted our previous simple factorial function here right into into a continuation passing style so what do we do is first thing as we add a new parameter k with represent continuation now if n is 0 we have to invoke the continuation and return the value 1 now take the second example so the second branch of it if n is not 1 or if n is not 0 what do you need to do given the value of factorial of n-1 we need to multiply that result with n and return the value right that is what we have in this right given factorial of n-1 multiply it with n return the value that is exactly what is done here you create a new continuation inside the second invocation the invocation of fact slash k so you are actually creating a new continuation and that continuation has to what should it do it has to given the value of fact n-1 multiply with n and return the value so that is what what is happening here right if no you should say k you should say k 1 that is where it unfolds exactly actually this program does not return it actually passes the control to k this program does not return all continuation passing cell programs never return this is clear okay some more examples we have 10 minutes I think I cannot show the interpreter program with this laptop I can try with another laptop yeah continuation no we actually use it in an assignment both of us Anand and me together in a while we wrote a python interpreter in scheme yeah in racket we actually used it to implement generators for example yield operator in python so the compiler if you have used any functional language this is a one of the first step that happens in any functional programming language compiler Haskell or scheme or any anything so you can actually implement it in scheme with a macro CPS can be source to source transformation so it is like a perfect fit for scheme macro so let us take a sum of a list another example very simple example so it takes a continuation now count and again same thing so given the so if you say the first one without continuation given the sum of the rest of the list what do I need to do to complete it so you see that the first part of the program is not in continuation passing cell and not into a tail call position whereas if you convert the program to a continuation passing cell you always get a function invocation in the tail call position that is another property it is like a side effect of converting a program into CPS side so CPS was not invented for getting tail call optimization that is like a nice side effect yeah so some more example again in lower level example like Fibonacci program okay so you have a you have a generative recursion here and again so here two invocations of Fib is happening so when you convert that into into continuation passing style the those two invocations are sequentialized or they are called in sequence so the first one the k one is the continuation of the first Fib that is given the value n what all needs to happen to compute the Fib of n given the value of Fib n minus 1 what do I need to do to compute the value Fib n so now inside that you are again we have sequentialized the whole thing now given the value so you still have to figure out Fib of n minus 2 there right so given the value of Fib n minus 2 so given these two values we just have to sum and return the result so the first one first program was not really very sequential program but whereas the second one has made it really sequential some more examples you have say given a value you need to find out whether it is odd so the first one is without continuation second one again so given the value X of odd if odd of n minus 2 if that value is given then you invoke the continuation again it is the same it is the same thing this a bit more bigger example let us say higher order function filter so again first part how you do filter without continuation passing style that is the given list is empty you return empty that is you return an empty list now you look at each value of the list if it passes the predicate test you count that value else you do not count it and keep looking at the rest of the list now how do you convert this into a continuation passing style you have multiple invocations of functions happening right so if you really want to so all the functions in your continuation passing style program should be in the CPS state except the primitive like plus and minus and the lowest level program everything else has to be CPS otherwise there is no point so we need to CPS the pred function as well here so pred also takes an extra parameter k its continuation so again we just return empty with the current continuation k or else we first have to do pred that is you look at the you look at the first value now what is the depending on the pred result you are going to take either of the branches so the continuation at that point is very clear you are going to take either of the branches given the value result of pred and it is going to take one of these branches which is also converted to given given the value pred then what do I need to do to do filter k I think this line should be called the pred slash k everything has to be in the CPS here so as we said can be done using a source to source transformation generally that is what is done in every compiler but we can also do in by hand I have the program I may not have time to show but I will post the code somewhere these are some resources that you can look at SICP 4 chapter has has a continuation passing style program but the first time the name continuation passing style was invented was in the second reference the rabbit the first compiler for scheme by guys seal so that had so he invented the term continuation so and it is another nice book the third third reference which is out of print it is one of the best reference on continuation you can find it in Amazon marketplace or somewhere it is very nice book and then programming languages applications and interpretation one and two both are extremely nice preferences and the lambda ignore high example is from the scheme programming language Ken Dewey's book and there is also a very nice Google hangout recording by Will Bird so he has a extremely nice continuation example yeah with a small parting thought this is the end of the question so yeah this is a code by Alan Perlis I guess the previous talk here is also I think it really echoes and many of the other talks here language that does not affect the way you think it is not worth knowing with that parting thought it is TCO is part of the scheme spec itself implementation is usually the CPS usually no your your your source program need not be in tail call position you can write a factorial program in it yeah right scheme itself will convert it into tail call position oh no I think I understood your question no is the test based on CPS comparison or no CPS is an implementation detail right it only looks for whether it is tail call or not tail call is you know CPS is one way of implementing I do not I do not think so yeah yeah yeah conceptually it does not I think because continuation of a program respective of evaluation order you have restored the program right you are just capturing the rest of the program in a in an identifier k yeah I do not have not done any CPS in say Haskell I guess my rain might have done yeah