Haskell Weekly


Profunctor Optics

Listen on Apple Podcasts
Listen on Google Podcasts

You can also follow our feed. Listen to more episodes in the archives.

Cameron Gera and Andres Schmois talk about practical uses for profunctor lenses and optics.

Episode 19 was published on 2019-08-20.



Hello and welcome to the Haskell Weekly Podcast. As you might have guessed this show is about Haskell, which is a purely functional programming language. I'm your host Cameron Gera and I'm an engineer here at itproTV.

>> And I'm Andres Schmois. I'm also an engineering in ItPro TV too, excited to have you on the show today man. How you doing?

>> Doing good. I've been here a few times now and it's pretty good to be here. Yes, it's pretty fun. Get to hang out talk about Haskel be nerds. It's always a good time.

>> Yeah.

>> Well guys today we're actually going to be talking about a article called practical Profunctor lenses and Optics in pure script. And yes, we know this is pure script, but we just thought the topic was good. And this article is also written by Thomas Honeyman and it can be found in Issue 172 of Haskell weekly. So if you want go check that out cuz it's a pretty good article. All right, I'm just well, we're talking about lenses and optics. In your experience, what is that? So, been here for about three months now and that's pretty much how long I've been doing Haskell and my question is exactly what do we use lenses for? And why do we need them?

>> Yeah, so that's a that's a great question and my personal experience which isn't much more than yours. Maybe, one of the year. So the experience I've had with it is getting into nested objects and seeing really what nested data structures have in store and then actually being able to mutate them which in my most experienced being in JavaScript. I have this fear of mutation is evil but Haskell has lenses which allow mutation in the other Optics as well, which is prisms traversals and isos, which they're all kind of cool. And I definitely think this article through talks a lot about all of them, but I definitely I want us to stick to lenses. So we've used lenses a lot here at itPro for XML mostly. [LAUGH] There's another library use that helps us with our AWS integration called Amazon could that also uses lenses? But yeah, we use that because the data structures can be pretty hairy things are pretty hard to get into the nested objects of XML. So what's your experience with dealing with XML and other languages?

>> So coming from an imperative background in JavaScript and Java and specifically Android XML is something that is it's a red herring things that every single programming language is have tried to solve and it seems like for every single implementation that I've seen of parsing does it is super complicated. Especially so on languages like Android Wear when I first started didn't have it at all and the the internal implementations for XML were not allowed to be used in the Android Library. So it became this thing that would be really difficult to use. So it was very interesting to come to Haskell and start to see how we handled XML especially as a back-end server side language for Haskell. And it seems like it's complicated but it's also seems like it's doable. It's not a thing that is almost impossible or you'll have to write your own parsing and have to deal with everything that comes with parsing. So with to me lenses have been interesting because it's a complicated solution to a complicated problem.

>> Yeah, and it does add another level of mental complexity to learning Haskell, it's not the syntax. It's not it's another level of this is a possibility Haskell. The other thing is it is possible to parse XML and things like that without lenses and we've done it here in ItPro TV. It's needless to say rough, trying to filter out exactly what you need out of every element and all the nodes and children elements the kind of things. Whereas XML or sorry, excuse me, using lenses in parse the XML allows us to get out specific values without having to know what else is in the XML which is helpful because we will have to filter out things we don't need or filter things we do need. So lenses has allowed us to get, the deeper nested objects, which is great. Without all the boilerplate have you kind of experience anywhere where you're dealing with nested objects that you felt when's this could have maybe helped with producing boilerplate?

>> So that's actually the point that we were discussing way before we even came into this article, which was why even use lenses. We all of these solutions available to us why use lenses? So coming back to the the parsing of JSON one thing that came to mind was we use the JSON library to parse JSON just because that's what I was told to use. And it seems it was it is a very good way to parse JSON. There is one and only one downside that I've seen so far and it's been sort of nagging at me and that is the fact that it's got a lot of boilerplate to be able to parse all of this JSON that is coming into your server. And one of the worst offenders of it are very nested objects. To be able to use JSON in a manner that isn't required to do any kind of fancy parsing, you'll need to set up a data structure with an instance for every single level of your JSON object. Not a 100%t sure, but I think with lenses if you didn't care for this structure that was already there. So let's say that you're hitting a third-party library and you just cared about one thing and inside a nested object. I could see lenses being useful in removing a lot of that boilerplate code. My question is is it worth it? Is the complexity trade-off versus the boilerplate trade-off worth it? And with Haskell from what I've seen so far Haskell is very concise. It's the language that allows you to write things in a very concise manner, lenses is just another extension of this right. All right, so a little little more complex, but it's yes definitely the question of when to use lenses first with not to first for the complexity aspect. And I think something we talked about earlier was like you said, we don't use lenses for JSON but we do for XML. And I think with JSON there's there's a little more types there, right? There's a little inherently it's a little easier to understand you could take a JSON file and look at it and understand what is what. Where you do sometimes we pull out an XML file and you're wait a second what's going on here? And so I think the reason that complexity lives for XML is because it is a confusing data structure as it is. It's great. It's effective, but it's confusing and hard to read from a visual perspective and the kind of reflects in the code, right? That's kind of crazy?

>> Definitely and if you think about it XML specifically doesn't have any kind of data structure things that people are normally used to seeing in code because of the fact that it in it and of itself is a sort of dom language. So it's got a document and it's got a whole bunch of different tags and values and they don't necessarily need to mean anything. They just there and HTML is XML. It's just a different. It's a different subset of it. So if you into XML, XML isn't a data structure that is easily possible by anything. With JSON from what I've discovered it is a replacement for XML to be more towards transferring information simpler. And I think that's why going back to the whole complexity issue, we have a complicated problem, very complicated, I'm sorry. We have a complicated solution for a complicated problem. And that is my experience with this.

>> Right, and and we were talking to more about some of the fundamental aspects of lenses, right? And we touched on it a lot earlier about the mutability. And with XML, we wanna be able to reach into an object and if we're gonna change, it not have to parse everything else around it, but just change that one aspect, right, because it could get complicated. With Jave, JSON, sorry, we're gonna be wanting to we could just make a whole new object and deal with it cuz it's easy to kind of just create. And I think Haskell, I think most programming languages are much more friendly to JSON than they ever would be in XML. So doggone complicated problem. Luckily, we have the complicated solution. But I wanted to kinda talk a little bit about lenses and get back more to the focus not the JSON vs XML thing because this is kind of our context in which we view it and we understand lenses can be using many aspects and we're just kinda speaking from personal experience here. There's three functions that are pretty critical to lenses and are really the only ones that can be used our view set and over. So view is a get function right? Let's get it, set is the the function that's able to mutate it which is setting the value and we also have over which is kind of like a map. So it's saying, we're gonna modify this value and this lens with a function and here's the function that takes you'll get takes that value, it gives you back the same value modified which is helpful that lenses as I built in which you would think it definitely should consider we're in Haskell one. And so that was something that was interesting for me to see and understand get a comprehension on is what are the accessor functions? What do I do with lenses? How do I make a lens that even the constructors? I don't super haven't spent a ton of time dealing with because the libraries we have have easy ways to construct a new lens or whatever. And so yeah I just thought that these functions at the core or pretty easy to understand. But I think people can also get a little bit confused about how they're operating right because we're operating within this optic this lens which I think for some people a little more confusing right? JavaScript, you're just yeah hey, here's this value, I found it I have access to it, okay? Just change it to this Haskell still kind of says, hey, hold on, we're gonna make it a little more difficult for you. You taste something but here's what you can do, which I think is, it's nice because Haskell says, okay and obviously this article reading is in pure script. So I'm just pulling it over to Haskell because we're talking mule this Haskell podcast. So like I think it's very much it's a yeah it is. It's just a necessary means to solve this really deep nested object issue.

>> I totally agree with the whole lens aspect of these things. This is just an optic, this is not a mutation. Now, what I mean by that Haskell entire paradigm is please don't mutate my things. So lenses give you an option to go in there and mutate it in such a way that makes sense to Haskell. Which when you start thinking about what a mutation as it makes sense that really Haskell is mutating and it's probably mutating a lot of stuff in the background. I don't know much like I said just started three months ago, but I'm assuming that Haskell's functional paradigm is a frontside but it obviously will have to have some kind of state in the background and lenses will give you a view into this mutations. I'm not entirely sure that's where the name comes from, probably not but that's how I see it. And leading into this I have the question that has been a little nagging and lenses aren't just for these types of data structures that come from like JSON or XML or any kind of server thing. Lenses are used for a raise for list for maps any kind of data structure that you can think of can be used through a lens. In my question to you is would you use lenses in that scenario?

>> Yeah, that's a great question. And I think it would boil down to do I wanna, if I'm gonna modify something is it worth it to make a new one or just modify that single value. And most the time, we choose make a new one, right? Brand-new. Yeah, the old one good, Bye, see you later. But if we have a huge data structure that we don't wanna continually load into memory or be passing around maybe it is easier to say. Hey, let's just use a lens and modify those values along the way and keep the same thing. So I definitely say the community of Haskell, also, we lean a lot more towards make a new one rather than modify a value. But yet lenses give you that option.

>> And I think that goes online to what my thought process was, which is if you don't think you need it or even if you think you might need it don't use lenses until you're sure that lens has become a necessity, right?

>> Like I would definitely not lean towards. Yeah, if you want to go go ahead and make your whole architecture using lenses cuz, it will work and it would be fine but it's just gonna add a lot of complexity in areas. You may not always need that complexity.

>> I agree.

>> Yeah, and one thing to note here just a little side note as I was just looking at this one little thing we had highlighted here. A key difference with the lens specific optic is the value has to be known to exist, I should say, whereas prisms or traversals or isos that's not true. Prisms are can kind of can think of it as maybe your the either monads and dealing with the may be in either monads and traversals thinking more like lists and arrays and maps things like that. And so that's something to be to note you wanna make sure you're gonna use a lens. These are values you wanna make sure they're if not, you probably want to look more into a prism and say hey does this thing exist before I try to go get it and that would prisms allow have something called preview which is hey go see if this is there if not, let's bail. So that that's another thing to think about if you're using lenses,, the value has to be there and exist or else you could probably get them some gnarly runtime errors.

>> Yep, and I think might take away from this talk is lenses are complicated. I will probably only reach for them for problems that are complicated not for simple problems. And that is something that in the last three months, that's exactly what I've seen so far is the only time we've ever used lenses in our environment is to solve a complicated problem more specifically toward XML and that is my take away from this. I am open to finding out that lenses are a lot more powerful and a lot more structured way of doing something, it's just I haven't come across it yet.

>> Yeah, and that's totally fair and, if you're beginning Haskell, I would definitely up there over the head say, hey slow down on lenses. They're not a core component necessarily, you'll run into libraries you use that may have lenses, for us we have Amazon Co which is our AWS library and then we have text.XML.enses is also a big thing. So core components do have lenses and you can use and solve problems with lenses, but I would definitely say that's not. Just because that added complexity could just kind of demotivate you hum from solving the problem because Haskel, that's what one thing I love about Haskell's there's a ton of ways to solve a problem. Yet the more complicated problems. There's less options for beginners out there. Don't be don't be afraid of lenses, but I wouldn't go chasing them. Don't go chasing waterfalls stick to the rivers and lakes that you're used to. Yeah, we've got record syntax. We've got instances. We have type classes things like that can kind of bypass the whole need for a lenses. So definitely feel better about that. So on just you have anything else you wanna kind of touch on in regards to specifically lenses?

>> No, I think you've covered everything, I enjoyed our little talk about lenses.

>> Yeah, I think it was good. And I think there's definitely more out there. So definitely check out the article because of it was pretty informative cuz I hadn't really spent time looking at lenses in depth or prisms or traversals isos. So it's definitely pretty informative to me. I definitely encourage our readers to go out there and check it out. But thanks for being on the show with me today Andres.

>> Thank you for having me Cam. And thank you for listening the Haskell Weekly Podcast. If you like what you heard find out more on our website haskellweekly.news. Also, please rate us and review us on iTunes it helps a lot. Haskell weekly is brought to you by itproTV, the tech skills development platform for IT professionals.

>> And also our employers.

>> Yeah that too us you address and network admins www.itpro.tv for all your training needs.

>> And then they can tell you what they think of the people who develop it.

>> Yeah thanks again for being on the show. We'll see you again next week. See you. Bye.