We Speak Your Language S01 E04
Darius: Welcome. I am Darius, and I will be your host today, here at “We speak your language”, the podcast for programming language nerds.
When we first thought of putting together this podcast, Jan and I considered all the people who we had met over the years, which as you can imagine is quite a bunch. We thought of the people who we’ve learned to know, to appreciate, and of course, some have become friends during the process.
But I really wanted to avoid this turning into a member’s club activity of sorts. I wanted to talk to people outside our immediate circles. I wanted to reach out and hear stories from people I wouldn’t necessarily speak to every day.
So, I aimed for the most remote connection I could think of.
In that spirit, I’d like to introduce you to our guest today Leandro Melo, from Belo Horizonte, in Brazil. It all started on LinkedIn, where I came across a post by Leandro a few months back, and his profile indicated that he was dealing with programming languages in a serious way, from a very different angle than mine. Even so, I found that we shared important interests, so I sent a connection request which he was nice enough to accept.
But that’s it. That’s essentially all I know. Leandro and I have spoken just once, to prepare for this interview, this interview that I am so looking forward to, because I know close to nothing about what he’s about to tell us today.
Leandro: Hello Darius, thank you for the invitation. It’s my pleasure to be here.
Darius: Tell us about your story, where you come from? Where did you study? What’s your story?
Leandro: Let’s start by the fact that I’m Brazilian and then I was born in 1979. I’ve been working with programming languages for the last 10 years or so. My first contact with the domain of compilers was when I started working at Nokia. This was in Berlin in 2010. I received the job offer from Nokia to work on the Qt framework.
It’s that popular C++ framework and I was part of the team that developed the Qt creator IDE, so that’s where my interest for programming languages and compilers and every topic that’s beneath this larger umbrella started.
Darius: How did you get in Berlin of all places? If you come from Brazil, how did that happen?
Leandro: I went to college and when I finished my college degree I enrolled myself into a master degree. During this time, I was working part-time. I worked for two companies, one of which was a lab in the University.
But then when I finished my master I decided to leave my comfort zone and I was very interested in C++ and system-level programming. In Belo Horizonte, there are not that many opportunities in that area, so I moved to Sao Paulo because there were some positions that interested me more. I spent one year there, but after just one year I wasn’t enjoying my time there and my wife preferred for us to live back here in Belo Horizonte.
After I moved back to Belo Horizonte, I continued to work in another company, but after almost two years, I still couldn’t satisfy my desire to go into topics that interested me. At this time, I was not involved with compilers or programming languages at all. I was really involved into C++. I was engaged with the language and I was already reading part of the C++ standard, so even though I was not working with compilers, there was perhaps some sort of spark in this direction.
At some point, I saw a job opening for the Qt framework in Germany and I applied for it. I was not really expecting to get very far, but I got asked for an interview and I went to Berlin. Then we continued the process and eventually I moved to Berlin.
Darius: In the spirit of ‘We Speak Your Language’ do you speak German?
Leandro: My German is very bad.
Darius: How long did you stay in Berlin?
Leandro: I stayed in Berlin for approximately 2.5 years from the end of 2012. It was during the time when Microsoft acquired Nokia and then Nokia was in this decaying process, at least within the areas that we were involved with, namely mobile phones. We were also developing an internal candidate for a new platform in Nokia and it didn’t look good for us. We were told that our division was going to end and we were not sure whether we would all be laid off or we were going to be acquired by another company. At this time, my daughter was born and my visa/work permit in Germany was tied to Nokia, so I was insecure about what was coming.
I started looking for jobs, I received a couple of offers and in the end I decided to go to SAP. I left Berlin and I went to South Germany, in Karlsruhe. I stayed at SAP for approximately 1.5 years, after which I moved back to Brazil.
In total, I spent about 4 years in Germany, and this was a great time of my life. I learnt a lot, both from a technical perspective, also from a society, civil side of life. It was an awesome opportunity for me to move to Germany.
Darius: With the Qt part of your career, where you started to get involved in language processing in a serious way, could you elaborate on what on what you were doing there and how did that evolve into your next positions and what you’re currently doing today?
Leandro: When I began, on my first week, I was introduced to all members of the team. My manager Matthias Ettrich then told me that I would be joining the compilers team. It is the compiler-like component embedded in their IDE, with the semantic features that an IDE has to have to navigate across symbols in the program, through type hierarchies, syntax and semantic highlighting, etc.
My manager came to me and said ‘you know how compilers work, right?’ And I said ‘kind of’ but I didn’t really know compilers at all. I actually graduated as a control and automation engineer. I started turning my studies more towards computer science halfway through college. I discovered that my interest was more on the computer science side of things, and I then started moving from control and automation engineer to computer science. I never took the classic compilers or programming language courses that one would take at the University, but I studied these topics on my own. When I graduated, I did have two Java certifications and I had studied the Java specification.
When I was doing my master’s degree, as I told you, I was also reading the C++ standard because I wanted to learn every little corner of the language, but I was not ever formally educated in what compilers are or how a compiler works, so I freaked out a little in the beginning!
My first task was to develop a generic syntax highlighter for the Qt creator IDE, and I spent around four months doing that. This was pretty much a pattern-based way to identify constructs. It was not really using compiler technology itself, but it was pretty much like pattern-based rules in order to match the syntax of the program.
Leandro: I finished this task and I was working closely with 2-3 guys from the compiler’s and the editor’s team. So I was on this border between the text editor operations and the information you need from the ‘code model’ or at least that’s what we called it within our team.
And then I was also participating in a collateral way across the features that were implemented that required integration between the text editor and the compiler front end. Through this entire time, I was learning about our front end, which was based on a hand-written parser, a classic descent parser. I was learning how it would construct the AST of the program and how AST visitors work and how we would collect and produce information from these visit processes.
I worked a lot in the preprocessor. We actually wrote a C preprocessor by hand. That is how it started.
You could think of features like code completion in the IDE. You have X dot. We need to discover what comes after the dot. We would then query the symbolic table of the IDE to get symbolic information, type hierarchy, navigating through the type hierarchy of a type when you right click and say ‘show type hierarchy of this type’. These are the kind of tasks that I was implementing that required a compiler side the IDE.
Darius: What always strikes me when thinking of parsing within an IDE is that there is that trade off where you must be able to parse incomplete or locally incorrect input, did you use specific techniques for that, or was it totally ad hoc? I understand you were using a handwritten parser, but if you were to go fully naïve and use Yacc and Lex, they would not behave correctly when facing an incorrect input. How did you deal with that?
Leandro: When I joined this team, the architecture of the parser was pretty much established. They were doing the construction of this front-end. Certain decisions were already taken. In regards to incomplete code, this is of course a best effort attempt. You cannot do a lot. The parser had a lot of points where it would rewind in order to try to parse a particular construct in different ways. This is the critical factor to find a good granularity on which exact points that you want to rewind to because you don’t want to invalidate the entire editor in which the user is programming because of a minimal error. Recovery points were of course one of the strategies.
It was not a very rigorous parser, so this is another place where you could incorporate the ability to not crash or not cause any large invalidation because it could not parse. We would parse things that were not correct, both from a syntactic and a semantic perspective. If you know the grammar of C, declarators are have a very particular way of being parsed in C.
We actually did not parse the declarators very correctly. If you think of functions returning pointer to functions, and with functions, you have a spiral rule for parsing declarators. We would accept lots of things and their order, some of these by design, and some because there were bugs in the parser. And because you are in the IDE and you’re not generating code, you even get say that some of these bugs are like features!
After Qt, how did you evolve into your current role?
Leandro: After I left Nokia and I joined SAP, as I said before, but this was not for a role involving programming languages and compilers. Under the kind of pressure I was when that I took this decision, I didn’t have a lot to choose from. Of course, I would have preferred to be involved in a job with programming languages. I was very excited about this field and I started a project which is still in my GitHub repository, it is called ‘UAISO’.
The purpose of UAISO was to create a semi-universal abstract syntax tree that I could use to parse different languages to a certain extent. I was still working with Qt creator IDE because this is an open-source project, and that’s the greatness of open source, One of the challenges that we had in Qt creator was the need to implement a semantic model parser for every language that we had to support.
This bothered me a bit. You have different programming languages. They have declarations and most of them consist of a type annotation, except if it is a dynamic language, like Python, then all you have is the name. There’s some declarators information, there is a semicolon, the notion of a class that comes from type declaration. Is it so hard to build something that’s consistent across these different programming languages, and defining the abstractions at the right level of granularity?
I started this project, building an abstract tree with a lots of variety within it and during the semantic step, I would construct this very complex abstract tree and doing semantic analysis. I would allow hooks into certain spots of the processor. Let’s say, when you do an ‘import A’ in Python and you do a ‘import A’ in the go language, the syntax is exactly the same, but the semantic there is potentially different. Python could be importing a module a specific file about .py file. In go, you import the package, in python you also import the package, but the interesting thing is that even the same syntax could lead to different semantics. Of course, different syntax can also lead to the same semantics. So, the game was, how can you find the balance between all this information?
I was not working at SAP with programming languages, but I was like putting all my extra time into this project. I got to the point that I integrated it into my own fork of the Qt creator IDE, this generic semantic analyzers for Python, for go, for the D language (by Walter Bright and Andrei Alexandrescu), which is a great language! It’s a bit frustrating that has not received so much attention in the industry.
I spent almost two years at SAP. I enjoyed my work there but it was a bit rough in the beginning. I had decided to quit after a few months, but I had a good manager and we discussed other projects. He told me about a project that has just failed and they were looking for someone else to take over. It was a C++ library. Then it got more interesting.
Still, I started having some family problems. Eventually, my wife and I decided to move back to Brazil as our families are here. I’m glad that we took this decision. I’m very happy here in Brazil despite the political situation and all the problems that we need to deal with.
When I returned to Brazil, I decided it was time to go full time into my UAISO project. I did this for two months before I started to think ‘how am I going to make a living?’. I could have found a job here in Brazil but I did not want to start working on things that did not catch my interest, such as unchallenging apps that would need to go to a database to store data, fetch it afterwards, etc.
In particular, I wanted to work with programming languages and compilers. The choice of what I wanted to do was pretty clear. I wanted to go back to the University to pursue a PhD program. But the operational aspect of it was not very convincing because, of course, when you go to a PhD, then you need to think about money. I would need to get a scholarship and it was not comparable to how we were living in the recent years. But still, I had an opportunity to join so I decided to go back to the University.
I had a friend in this university which was a professor and he introduced me to another professor that I didn’t know, and who is a worldwide compiler expert. I had an opportunity to work with this group of people, so I decided to take a chance, sacrifice the financial aspect and invest. As this is where my passion is in compilers and programming languages.
So that was how I moved back to the University, first starting to work with this engineer within the two to three groups that were doing work in the inter-disciplinary areas between security and compilers.
I was not conducting research myself. I was sort of a collaborator for these three teams. Over two years I participated in several projects. But after that, I was pretty sure that I wanted to pursue a PhD program and I wanted to dig deep. At this point, I was already in contact with this professor called Fernando.
I asked whether he would be willing to be my PhD advisor because I also didn’t want to just do a PhD. I wanted to do a PhD in an area I was sure that I was interested in, with someone that I trust to mentor me and to supervise my work. He accepted, and I finally enrolled myself into the PhD program.
I spent a few years there. I was working a lot during this PhD with the C language from the more formal side, specifically in the area of type inference. This project actually used the parser from the Qt Creator IDE. I resurrected the parser because one of the its characteristics is that it had very modular stages between syntactical and semantic analysis.
If you think of C and you see X*Y, you don’t know whether that’s s multiplication or whether that’s a declaration of a pointer. If we try to parse this without the information regarding X, then it comes back to incompleteness as mentioned before.
You can’t parse that with a regular compiler. Either you request that information and if it’s not there, you break or you carry on with the ambiguity within the AST, and later disambiguate the construct in question when possible. The parser of the Qt creator IDE also used this strategy to deal with this incompleteness that emerges when you arrive within an IDE.
It also didn’t parse header files multiple times. In that sense, it is not like a real compiler. It was very fast because in C, in C++, you need to go to inside the includes, because a macro there could change completely the semantics of what you’re parsing. This was ignored by the Qt creator parser. If we were to encounter an include file more than once, it would assume that it exposed the same symbolic information that we had seen before.
So as you can see, working on the Qt creator, really was a landmark in my career.
The team was good. There were these guys Roberto Raggi, Christian Kamm, Erik Verbrugen. They taught me a lot about compilers and I’m very grateful that I had this opportunity there to learn so much.
When I was 1 year away from finishing my PhD, I received a call from the CTO of Shift Left which is the company that I work for now. He had bumped into this project that I was developing (UAISO project) Actually, he told me I had bumped into one of their problems. I thought he was talking about my PhD project for which I had been receiving relatively good feedback. But then we had a conversation and I realised he was actually talking about the other project that I was not even developing anymore due to a change in priorities. So then I started working at Shift Left and I have now been there for 4 years.
Darius: So you’ve been in this company for 4 years. Tell us more about what you’re doing there?
Leandro: We perform static analysis for the purpose of vulnerability discovery. Originally, there was an intent to go further than classic static analysis: the goal was to also perform dynamic analysis. We released a product that would combine static analysis results with dynamic analysis monitoring of the application in order to give higher priority to certain issues than to other issues, those which that were actually happening during execution of the application.
In the end due to various reasons, we shifted focus, now we are a classic static analysis tool company. We also provide SCA. When I was invited to the company the team had developed the foundations of a static analysis technique and this was done for Java, on top of Java bytecode. And the goal now – this was at the end of 2017 – was to expand this technique to other languages. When I joined I was specifically focused on .NET and the .NET universe and C# in particular. So we had discussions on how we wanted to represent C# code.
Would we use source? Would it be different from what was done for Java, which was a Java bytecode-based analysis. Would we use Microsoft immediate language? Would we use C# source? We had a number of discussions to decide whether we would require a buildable application, in the sense that all dependencies should be available at analysis time?
These were usual discussions that happen when you’re doing this kind of up enhancement to a technical technology that you have created, and I spent the first year pretty much developing this language layer that would compute an intermediate representation and the data flow tracker that we have.
So I learned about the C# language. I had programmed with C# before, but I spent some time reading the C# 6 spec. That’s not really a spec as rigorous as that of C and C++, which is also not as rigorous as that of some modern, more formalised languages, but it is a spec after all.
I worked on the core of this language layer for 1.5 years. We then started putting it into production. Then of course, it’s usual that you discover issues. Sometimes, those issues are technical, those are sometimes they could be more design-related. And then after 2.5 years, I also designed and implemented this language layer for Python. At this time I was not so involved in the data flow parts of our representation. I was focused 100% on the Python language itself. So, we designed and built a rich front end, a rich language layer for Python that is then consumed by this middleware that we have which computes data flows.
Darius: Static analysis is obviously not my domain of expertise, but the way you describe it, it seems that there’s an intrinsic difference of approach. Anything people do with C# or .NET on our side, on the compilation side, would typically rely on a bunch of tools and libraries that are available to parse, decompile, analyse, verify, and more on .NET assemblies, C# source code and the transition from one to the other one. There is a bunch of things that we would rely on almost by reflex and the way you describe it, it seems to me that you don’t. Am I right assuming that you don’t? And if I am right, is that just a question of culture or do you have very specific needs that makes it impossible for you to rely on existing components?
Leandro: You’re partially right. We do rely on the tooling that is out there. For instance, we actually use Roslyn. When I started this project, one of the considerations that we reasoned about was: are we going to analyse source code directly or are we going to analyse DLLs (Microsoft Assemblies)?
It is my personal opinion, and I’m stating this in a general sense, that for the purpose of static analysis and more specifically static analysis targeting vulnerability discovery, it is likely that you will be able to gather better and more refined, more precise information if you perform analysis on the source code.
At this time, I was not a Microsoft .NET developer, so I gathered information and it appeared to me, and I continue with this impression, that Microsoft is moving is moving toward Roslyn. If you’re doing source code analysis, and if you’re doing general static analysis, Roslyn is the way to go. Roslyn works on source code and abstract syntax trees, and then it has a semantic model. This was one that one of the reasons why we opted for Roslyn.
This said, we still consider whether to provide a DLL-based approach for static analysis, as you said by decompilation. It is not always easy to reason about this process because there are even some legal boundaries. Sometimes, I can’t even tell whether or not one can decompile, and whether the customer is actually aware of what you’re doing, that you will be decompiling one of their libraries.
In fact, even with source code, doing our first proof of concepts, it was common to see enquiries such as ‘Will you have my source code?’. Many people don’t actually know that, but if you provide a DLL to a static analysis company, ultimately if someone wishes, the DLL could be decompiled.
Darius: We have a COBOL compiler that generates MSIL and one way to understand what we did was to decompile and read the resulting C# code, whether the behaviour was what we expected it to be. So, from a compiled assembly, you can derive an amazingly understandable piece of source code.
Leandro: One of the disadvantages of working on the source code, and in particular with Roslyn, is that this internal representation that we compute is not only syntactic. In fact, this was one of the surprises that I had when I joined. Within the group, we were discussing and I had the impression from the information I was getting from the colleagues that this intermediate representation is syntactical only. In reality, it’s not. There is a lot of semantic information embedded within it which might be invisible if you don’t know where to look.
That could have been the case because the original implementation was for Java bytecode, that already contains some semantic information. We then realise that we actually need buildable C# code and this is good on one side, but it’s a disadvantage in another side because it’s not easy and Roslyn is a great tool, but even to this day, it is not being very well coupled with Microsoft MS Build and there is no good integration between Roslyn and MS Build.
There is this component MSBuildWorkspace in Roslyn that is available for the .NET Framework. But if you want to do things more general for .NET, with .NET Core or .NET 5, then this coupling is not the best. We failed sometimes to compute static analysis information because the build failed. If you’re working on MSIL, then you have the benefit that it’s all there. So there are trade-offs to these two choices.
Given that approach that we wanted to follow, which was source-based analysis, we tried to use the best tools that were available to us. We also use another component that’s open source, which is called Buildalyzer, and a lot of other companies use that as well, so these are open source tools that we try to leverage more on our platform.
Darius: How do you describe what you do when you talk to people outside the computing world? How do you describe your job?
Leandro: I have an archetype as an example which would be my dad. I think when we talk to people outside this circle of compilers there are two levels. One is the individual that is acquainted with computer science and knows, where we share a common baseline, so there’s a ground which is can be assumed for the discussion to happen.
But then when I talk to my dad and my mum, it is very difficult to explain. My dad just thinks that I do security for the cloud. Whenever he reads some news about some security tools in the world, he says this important for you because it is security in the cloud.
The general description that I use is that I write programs that inspect other programs in order to discover issues or problems or vulnerabilities. That’s how I put it for a naive individual that’s really outside of computer science, engineering or programming languages.
Darius: What would you do if you were not involved in language and compilers? Still in computing but not language and compilers? What would be your domain of choice?
Leandro: Well, I guess everyone would need to do AI, right? Actually if I restrict that to my personal interests, I think I would do something in the field of graphs and algorithms. That would be my second interest.
Darius: And what would you do if you weren’t involved in computing at all? What would be your career?
Leandro: I would be a former tennis player investing in music right now. I would try to be a musician at this point of my career. I like music. I studied the piano when I was young. I also was a competitive tennis player, exact right now that I have an injured back. If I was not working with computers, if I was told for some reason that I’m no longer eligible or no longer allowed to touch a computer, aside from family time I would try to find work in the music business or even with tennis.
Darius: How old were you when you wrote code for the first time?
Leandro: I was rather old when compared to when people learn how to code these days. I was 18 or 19. It was in college, not even my first period in college. I had not written a single piece of code until I got to college. I had colleagues that had already written programs by then.
Darius: What software project would you have loved to be part of?
Leandro: There are good candidates here. I would say Clang. I would have certainly enjoyed participating in Clang, but I would also have enjoyed participating in LLVM itself, not necessarily in the front end. I can maybe think of others, but I think there are other smaller projects that would have been very interesting for me to participate in. The reason for me choosing Clang is because I think it would have opened a lot of opportunities, a lot of people are doing Clang- and LLVM-related things in the industry. I like academia, but I’m not a full academic. I also like the industry. I like to work on the applied science layer.
Darius: What do you consider the most important quality for someone in our trade?
Leandro: I would say attention to details. When I started my PhD, I already had this practical knowledge of compilers, but I was not educated in theoretical programming languages. And if I would need to pick one of the greatest learnings that I had during my PhD time, is the ability to look very close to the meaning of a piece of syntax, of a program, a construct, and I learned this from my PhD advisor.
He says that ‘Let’s try to put everything in mathematical terms’, because once we put in mathematical terms, this actually has helped not only the field of programming languages and compilers, but the field of logical in general, not only for life but programming. When you can filter and isolate things that really are just noise, and you come to a very accurate, minimal description of a problem, then you can, most of the time, think of a very minimal solution to this problem. You then go step by step until you realise that you have actually tackled a larger amount of this problem than you thought you could in the beginning and in order do that it’s necessary to have very particular interest in details.
Darius: What do you consider your most important professional, technical, scientific quality? What is there about you that makes you good at what you do, in your own opinion?
Leandro: I would go for that characteristic that I’ve just described. I don’t consider that I’m good at it, at least not as good as I want but I really try to. We were debating how we would do analysis for C# and for Python. I would try to go into every little characteristic of the language, of the semantic representation that we need to compute in order to see how I could make things connect in a more mathematical way. I think people who have experience with functional programming develop the ability to think mathematically in terms of functions, t helps you a lot.
Darius: I’m going to reverse the question, what is the thing you do where you say ‘I could have/I could be better at this’, whether it’s technical or social or at any level.
Leandro: One that stands out for me and I’ve been actually actively working on this area right now is more personal than technical. It is related to emotional intelligence: the ability to capture what a colleague or a PhD advisor, or anyone that you’re working within a team, is trying to say. What I mean is true understanding between the lines because communicating is very difficult and it is hard to express exactly what you really want to say.
Sometimes you think that you’re expressing something, but in reality you’re actually saying something that’s not that exact thing. One needs this ability to read between the lines of another person and to put context into it. I’ve caught myself in, let’s say in a debate, and in the end, after many pints of beer, we realise that we are actually on the same side of the argument and what caused the friction was a term that was not common between individuals. I’ve been trying to be better at this because, as I said, I’ve caught myself in situations that I misinterpreted what was being said. If we had this higher level of abstraction and this ability to give a context into the discussion and to gather all the information, we’d be able to find a common ground. This would be one of these weaknesses that you mentioned that I think would characterise myself.
Darius: That’s interesting because you’re expressing both better decoding what people say and implicitly being clearer yourself when you talk to people, it goes both ways.
If you were to direct our audience to read one book, one article, one author, computing-related or not, what would that be?
Leandro: I would pick the Algorithms book from Robert Sedgewick. Algorithms are everywhere and we talked about algorithms earlier, you asked me if I was not into compilers and programming languages, I said I would like to work on algorithms. During my master, I studied this algorithm book, the C++ version because Sedgewick has this book for different languages such as C and C++ or Java.
I had a great time reading this book by Sedgewick. He writes so well and he teaches a little bit of what we were talking about, this level of details and how to look into algorithms and little choices that make a big difference. And of course, you go through indirectly underneath you go through a wide range of computing domains and algorithm domains.
Darius: What is the book that you wished you could force yourself to forget, so you can read it over and over and over again?
Leandro: I would pick the Model Compiler Implementation book by Andrew Appel. I’ve heard from some people that this book is great, while others feel very differently. I personally found this book great because it has a mix of theory and practice at a very interesting level. It does not go through the theoretical details of a particular topic, but it does show you the code of how you would implement that. If you want to see how unification works, which is an algorithm very commonly used for type inference and then if you go to that book you have a glimpse of it from the theoretical side, and then you still are provided with the code and it covers a wide range of compiler topics.
It’s not as big as the Dragon Book. When I was reading this book it was also a roller coaster for me because I didn’t understand certain concepts. I was frustrated at first, but then I got to read the code and once I got a better understanding of that concept, perhaps even from a different book, then it was joyful that I could see this mapping to code in such a beautiful way. That book sparked a variety of feelings and sensations while reading it.
Darius: You’re still young, so it’s probably not relevant right now, but what would you like to be remembered for?
Leandro: I’m 41 right now, the answer to this question is immediate in my mind, and it’s not technical. It really is a family-oriented answer. My life, my way, my strategy, my reasonings about life changed a lot when I had kids.
I have a 9 year old daughter and a 5 year old son. My life changed so much, my perception of life, on what you need to do and what you need to accomplish and what your true responsibilities are in this world. They went from one opposite to the other when I had children and I didn’t really imagine that.
When I look back to how I was living before, it changes even very little habits, even the moment of day I go to bed. I now go to bed very early compared to when I used to go to bed. It goes to very complex feelings, regarding what you actually want to leave for your children? What’s the example that you want to give them? And how do you want to do that? I want if for my daughter and my son to remember me as a great dad. That is all I want.
Darius: To some degree, you don’t care what you are remembered for, you want to make sure who remembers you.
Leandro: Yes, that is a good way to put it.
Darius: Leandro, thank you so much for this interview, it was absolutely lovely. This is it for today and have a wonderful day, thank you!
Leandro: I want to thank you, it’s been a terrific experience. I hope people enjoy and thank you Darius, and I hope we get to talk again soon.
Outro: We hope you enjoyed this episode of ‘We Speak Your Language’ Stay tuned for the next episode with Jean Claude Van Dam for more nice talks about computer languages and programming. Have a great day.
Algorithms, by Robert Sedgewick: https://algs4.cs.princeton.edu/home/
Model Compiler Implementation book by Andrew Appel: https://www.cs.princeton.edu/~appel/modern/