 Today I want to introduce a crucial zipper. How many of you have used a zipper? OK. So anyone use the zipper from Haskell? No. Haskell. Haskell, actually the zipper is from the functional part. Then someone, I think, first introducing from Haskell, as I know. OK. The zipper is an idiom that use the ideal context to do the means of manipulation locations in a data structure. Actually, it takes me quite some time to understand what is a zipper, how to use it. From my experience, actually, I think to understand the zipper, you need to know the shape of the data, how it's shaped with the zipper. So today I want to demo this. So first, I want to talk about the vector zip. Actually, it's introduced by call. When you see it first time, actually, it's quite weird. How you imagine these kind of vectors can have some relationship with the zipper. It took me weeks to understand what it looks like. Then I find somebody actually to generate the graph with this. So you can see the vector data structure. Actually, if we graphed it, it's like a tree structure. So the top vector, you can see actually is the root of the child. So you can see the top one is the full vector. Then the first element is its first child, then its siblings. Because these siblings is a vector, so it has its own child. It itself is a second level root. Then it has child A and B. So it also has siblings 2, 3, and also another vector 40, 50, 60, has their own children. So after we use the graphic, we can more understand what this zipper means. Actually, the zipper is, from my understanding, the zipper is a tool to help you to manipulate the trees. The good thing, it's compared to the work. Actually, you can get the, that's what you can see from this definition. It's context. It has context. For example, for the root, you can directly know its children. From its children, actually, you can know who is its parent, who is their left siblings, right siblings, all these ways. So then it comes to make sense. It's like a zip can be zipped together. OK? The zip itself provides us also some functions to handle, to traverse it. For example, this is a root function. If you see the root of this zip, you can see actually it's the vector itself. Then we can see some of its children. So for example, I go down one level, then go right, then show the node. It's the A, B. So I go down one level. Actually, the go down gets to the leftist child. Then I get to the right. Actually, it's the sibling's A, B vector. So you can see here. If I do more, I go to the right again. You can see it's go to the two. I do twice. It gets to the 40. I go twice means I move there till the 40, 50, 60. Then go down one level. It gets to the leftist child, which is 40. So that is about the vector zip. Any questions so far? OK. So we come to a more complex one. It's a map zip. Actually, there's no core function for that. For a map, actually, it can be much complex. So you need to define its shapes. For example, for this kind of map, we can see when you define a zip, it needs three kind of information. Once a branch tells whether this node has children, then it needs a children method, which actually to retrieve the children from the node. Then it has make node. This one is more useful when you manipulate or edit the node. Then it will use this function to regenerate the node for you. So for this map, we can see we say if it's a map, then it will have a children. It will have more branch. If it's value, you can see the n6, 1, its value is a map. Then it will have the children. Then its children is the map itself or its value. So we can see the picture. So you can see this is a zipper structure visualized. So the map will be the root. Then its first child, it will be a3. Then the second is b. Then since b's value is also a map, so it also will be a node with a child, which will be branched. So it's the same. So we can see its root. You can see if we say it's with your root, it will show the full map and its children. We say we go down one level, then we go right. It's the key with the b map. So far, any questions? No? OK. So next I want to show something that's used in the real world, just as an example. First thing I use the zipper actually is for the XML processing. It's very convenient to collect the information from the XMLs. At that time, I have an application which actually calls the Singapore government's APIs, which downloads the XML, then travels it to get all the information. So below is a very simple example. For example, there's a DIV which contains two links. Then we can pass it. Then we can make it a XML zip. So you can see the structure. So it actually will be passed with all the maps, like what is the tag, what's the attribute, what is the content. So to get all the, if you want to retrieve all the URLs from this, you can do this. Actually, the zipper also has some children. I will say I get all the children of the root, which is all the anchor tags. Then I get all the attributes and the URLs. So you can see I get a list of URLs from this DOM element. So that's one useful thing. So if you know the structure of the XML, then you can do these things. You can get all the children's or left siblings or every nodes. Then you can easily retrieve the information from the XML. Any questions? Or OK, I move. So the next thing is actually, the zipper can be used to manipulate some DSLs. In some book called Closure Recipients, actually they use the, because the datomic, they use it to manipulate the datomic schema definition. Because the datomic schema definition is very robust, all the vectors. So and also you need to repeat so many, actually is default things. So some people make some DSL. It's just to give some top level definition, then give it to the child. Then use the zipper to traverse it. Then to make some default definitions of the schema inside to can be cascading down. Actually, recently we also started some work to make some DSLs ourselves. It's some simple example. For example, you want to define some job control language. So for example, you decide it will be like a tree structure. You will define some root jobs doing some initialization. Then it will have some children jobs. But the children can be run parallel. They can have some child jobs. So from this DSL, for example, you want to collect all the jobs included in this DSL. Sometimes you also have some kinds of jobs like you get all the siblings so you can parallelize them. So you can use the zipper to do the similar jobs. So for this simple language, for example, you can tell it anything has a control children will be a root node. Then its children includes all the jobs. This includes all the children's then how to make. This is a simple make of the node. So we can have some helper functions. It can iterate the whole structure, use the next, which do the depth first traverse. Then you take tier the end flag, then to return all the nodes. So in this, so here I call this function. So you can see it will return all the jobs we defined. From the root, then it's part one. It's part one's child, part two. You even can do the children of the DSL. For example, it's a children. So you can get all its children, which can be parallel run. So you can assign the task, for example, to some scheduler or something. So that's all I want to share. So any questions or? Deep with lenses. Actually lens for me is a structure which you used to get something. You retrieve the internal things. Or you set the deep structure. But zipper is more for the tree structure. You traverse. Traverse. Well, I'm using zipper. I wanted to show you how it was like when I'm in the middle of a tree. I would like to only traverse this subtree. Yes. Because if I use something like iterate a zipper next, it will go into the next subtree after finishing this. But even you do this normally, you need to get to the point. Even you want to traverse the subtree, you need to get to the point. So you go to the root. You can do the same. Means you can go to the child, find its child, then make it another deep. That's the most brutal method. You go there, then you make it another deep. From there, you do your things. Zip actually gives you the location context. So you can go down, go right. If you know your structure very clear, then that's very convenient to use. Yes, Zip has the edit. So you traverse there, you edit. Then when you come back, you return the new. It will retain the new nodes. Actually, the make nodes is a function like that. So when you edit something, it's use your new children to make the new node for you.