 Hi, everyone. I'd like to start off with a question. How many of you actually feel this way when you start learning a new language, or when you come across something new in general? Do you feel things can get confusing? You wonder how do you go about learning things? Do you have feeling that there are too many resources out there in the community and say if you're learning a new programming language, and to top that up, if you're even learning a new programming paradigm, how do you go about approaching things? Things can get overwhelming when there are too many resources out there in the community. So, do you feel confused? Can I see a show of hands? How many of you feel it can get overwhelming? Great. More than 50 percent. Right. That was basically my feeling too. So, the journey of going from not knowing something to knowing something has its own ups and downs, has its own highs and lows, and learning a new language can be thrilling. At the same time, it can get uncomfortable. It can get challenging and it can also be fun. So, this talk is basically about my journey of learning Elixir and what helped me learn Elixir better, and hopefully through this talk, I would be able to give you some takeaways that could help you learn Elixir better. So, a bit about me. I work at Money Smart, and I'm just going to talk to you about my overall journey of learning Elixir so far. So, to start with, I started learning Elixir by looking up the basic theoretical sources out there. I started off with Dave Thomas' book. He's a pretty famous guy in the community if you don't know him. He's well-known for his contribution to Ruby, and introducing Ruby in the United States. His book explains things pretty well when you want to learn individual concepts and how do you apply those concepts with respect to one or two data structures. But after a point of time, I felt my learning was lacking in terms of me being able to apply those concepts in the real world. That's when I went to the official Getting Started Guides of Elixir. So, this is basically how it looks, and it's pretty interesting that when you're having a language that you want to learn, and that's being supported by official guides. This is something which is really helpful to me when I want to learn Elixir. The good thing about these guides was that they were concise and to the point. So, it made my learning journey much more easier. After a point, I was like this user on a forum called Elixir Forum, which is a forum that is built on top of discourse. It's similar to Stack Overflow but not the same. So, this guy says that I was okay with starting off with programming Elixir, and it was very interesting theoretically, but I couldn't find the real world connect. What do I do? That's when I thought of learning by doing, and why learning by doing. It was an easier way for me to understand and grasp things. It had a closer connect to real world problems, and learning multiple concepts at one time is something what we usually do or what we usually apply in our day-to-day job, when we actually have to solve a particular requirement. The whole idea is the more I do, the more I understand, and it's more easy for me to relate back. So, learning by doing is very helpful in this way. So, when I was like learning by doing, I wanted to have certain goals with learning by doing approach. They were, I want to be more confident, what do I learn is something I should be able to use when I am actually applying them to a real world problem or a real world project. I wanted to make sure that I was approaching problem solving using the new language in the right way. I also wanted to make sure that I'm applying the right concepts to solve the given problem. Also, I want to be able to track and make progress in general. Well, as a beginner, you would want to make sure that you're heading the right direction. How do you do that is something which can be questionable or it's not easily answerable because you're starting off and you don't have any guidance, and that's something I wanted to see how I could better keep an eye off. In addition to that, I want to learn the underlying concepts with real world problems because I could establish the connect much better that way, and I want to write idiomatic elixir code, which basically means using some of the best practices and the right constructs or structures to a particular problem that I want to solve. Also, the ability to apply multiple concepts, and I want to see how I could improve with my learning along the way. So, that's where I think if I could compare my solution with somebody else's solution, I could find missing gaps and potentially areas of improvement. So, the way I went about approaching this was through collaboration in general, and I felt like if I learn things in a collaborative way, it would help me learn things much more faster and make learning even more fun. How would I do that? One of the platforms that I made use of was Exorcism. So, what's useful about Exorcism if you see what's highlighted over here is, they help you with some small problems that basically bridge the gap between a real-world problem and what you want from a book in the sense of its theoretical concepts. It gives you some small wins that can actually help you get a better grasp of these concepts that you are more confident to apply them in the real-world. In addition to that, I also made use of a couple of forums like Elixir Forum which is built on top of Discourse, and Discourse has been built by Jeff Atwood, who's a co-founder of Stack Overflow, and has pretty famous in the programming community. In addition to that, I also made use of another platform where through Slack, I could again communicate with different people in the community to get their help on a more instantaneous way. The good thing about forums like the Elixir Forum was they have a very strong focus of supporting beginners. So that was encouraging to me, and that's basically what I wanted, or I think what anybody else would want when they want to start learning a new language. So the way I went about solving things from there on was the classical introductory exercise with Elixir or with any language, which is the Hello World exercise. So if you see over here on the right-hand side, you have the way things work in Elixir system just to give introduction is you have a failing test case that you have to make pass, and you have a basic sample script on your as you can see on the left, and the idea is to write the minimum code that you need to make the failing test case pass. So this was my initial solution. So the whole problem was, given a module and a function called Hello, I need to print out Hello World. The way I approached it was by using something called as default arguments, where if I want to print Hello Alice, I can just pass Hello World.Hello, and I can add Alice as an argument to that function call, and with that, I would get Hello Alice, and if I don't pass any particular name by default, it'll take the word world, and that's basically I wanted to implement in a way which is more flexible. So that's why I went with the default arguments approach. So when I started learning this, I actually was trying to look up, how do I implement default arguments in Alexa? Things weren't very clear to me when I read the documentation. A particular aspect of the documentation made this thing a little confusing for me. So as a beginner, when I was looking at the documentation, it had an io.puts and the string Hello. I was like, when we want to use default arguments, I didn't need a default argument. Why would I need io.puts which is like a print s or a put s in other languages, which basically print something to your console? That's where I went to the Alexa website related GitHub repo, and I opened up an issue where I thought of clarifying this with the collaborators there, and I basically proposed to them that, hey, instead of using the default arguments documentation with io.puts, you can use it without that, and that's when I had a conversation with Jose Wally who's a creator of Alexa. He replied saying that the original intention of why it was added was to help you or understand the evaluation of default arguments at when exactly they get evaluated, and he realized that yes, it could be more confusing than helpful to a beginner, and that's where he said like, yeah, let's remove it, and that was my first PR as a beginner during the language with just a very simple exercise Hello World. That's how I started with my first contributions to Open Source with the Alexa language, and it was a very fun experience because I was just starting off and it just gave me some good confidence to make such make further progress with learning the language. The next exercise that I would like to talk about is exercise called Kika second. So the way this works is the problem statement for this exercise is given a particular date like if you see over here, it's 16, 30, 90, 77. If I add 10 power nine seconds to it, I need the resultant date in the same format as the initial input of 6, 13, 1977. So 10 power nine seconds is like 31.7 years, and so a bit of more background about me. I've been coding with an object oriented programming background for a number of years. So my initial approach to the solution was, okay, let me convert the date time, which is 6, 30, 1977 to seconds. Then let me add a giga second to it, which you can see is 10 power nine seconds, and then let me convert the sum back to date time, and that was my initial approach, and I was making use of saving things into vehicles. This was, it worked for me. The solution was fine. It passed all test cases for me. But then what happened was, I was comparing my solutions with other people's solutions on exorcism, and that's when I realized that in the functional world, you don't necessarily make use of variables, and instead you can use something called as pipes. What are pipes? Pipes are a way of passing data around from one line of code to another line of code through something called as transformations, and that's where I learned that when I'm learning a new language and also probably learning a new paradigm, I should learn to unlearn whatever I already know from the old paradigm, so that I can open my mind to relearning this in another way of problem solving, and that's basically when it left an impression on me that, going forward, I will be more proactive about using such things like pipe and thinking more functionally than in a more imperative way of problem solving, and that was a takeaway for me from this exercise. In addition to that, I also learned how to use a particular constant in another fashion. So instead of just directly using 10 power 9, as you can see in the code over here, you could use a math.power function, and so my overall learnings from just one exercise were, I learned how to use pipe operator, I also learned how to use the constant in different ways. One more learning that I had from this exercise was, so what happens is when you're trying to convert something or basically when you're trying to do something and if you can't find the solution for it in the Elixir documentation, that's when you can look up the documentation of Erlang. Why? Because Elixir is built on top of Erlang. So instead of directly going and getting your solutions from people's help on forums, one thing that you could do initially is start with Elixir documentation, move on with the Erlang documentation, and actually the whole day time to Gregorian seconds function is taken from the Erlang documentation, and that's what I also learned that, hey, this is what I can additionally do whenever I'm stuck, and I also learned how to use the Erlang code within Elixir code this way. Moving on, I had one more exercise that I solved. It's an exercise about a person called Bob. Bob is like a dice-cycle teenager, and his responses are basically in four ways. He responds, sure, if you ask him a question. He responds, oh, chill out if you yell at him, and he also responds, fine, be that way if you address him without actually saying anything which is like being silent, and he answers whatever if you talk to him about anything else. So when I was solving this particular problem, one of the test cases that I was dealing with was given an input. So somebody is talking to Bob in Russian, and the answer it should evaluate against is the yelling answer. So if somebody is shouting to him in Russian, if you look back at the problem statement, the answer should be, whoa, chill out, and that's when somebody is yelling at him, and how do you actually go about getting to write the code which passes this particular test case was something tricky to me because I had more of an English background, and I wasn't sure what is capital or what is not capitals in Russian, and it is a little tricky to me. So I was stuck for a while, and I was looking up for solutions, and that's where again I found Elixir Forum to be very helpful to me. Turns out another guy also had a similar question. He also asked about this particular problem that he stuck with getting the talking in capital test case to pass, and he was just wondering how do I get my way around solving this problem. So turns out the way this works is, I was able to actually find a solution to this problem using a rejects, and I was just looking up this whole question and that conversation around this question in terms of the response that he got for to where he was stuck. One thing in particular that struck me was this particular exercises approach by this user, another user who basically commented on telling him that you can solve this better was to understand if something is in capitals, what you basically can do is you can find a solution without using rejects, and how it basically is a combination of using these two particular functions and these two comparisons. So string.upcase, so if you see over here, this is the given Russian string. What I do is if I do an upcase of the string, if I get the same result, well that's one way of telling me that the given string is upcase. In addition to that, since it's Russian, I'm not very clear if everything is already upcase because I don't know Russian, and I wanted to see that, what is the result do I get if I downcase it, and the result that I got from this was actually with some characters downcased. This is when I realized that this is how downcase looks in Russian, and the downcase of the input should not be same as the original input. That will come a combination of both these conditions will actually tell me that yes, this particular thing is in upcase. That's basically a solution to the problem that really got me intrigued because it didn't make use of rejects, and it was much more clearer and easier to read. So this is basically my same experience where I was having some rejects code, and I felt my code was not that readable. So I was looking at more from a perspective of somebody else who look at my solution and see if they're able to understand it. I felt replacing the rejects with the upcase and the downcase combination, and the upcase combination comparison checks was very helpful. This came through Elixir Forum, so it was pretty helpful that I could find something similar in that platform. In addition to that, I had more learnings. When I was looking up other people's solutions because exorcism gives you that potential of finding ways how you can improve your code by seeing other people's solutions. One of the other things that I found was this whole concept of type specs. Now in Elixir, type specs are basically a way of doing some kind of static checking for your types or for your data. So if for a given function, whatever you see as something on addition to that is a given line above your function prototype, which starts with the word at spec. So why are type specs useful? It probably can help you determine what is a type that you're returning with respect to a particular function. I felt coming from an object oriented background, this is probably more code for me to maintain, and I would not really want to do that. That's when I realized I should probably explore more why do people even use type specs in Elixir. So it just got me curious to dig further, and I was just trying to find answers on Slack. So in the Elixir Lang Slack, we have a beginners channel which has more than 2,700 users. That's when I actually opened up a question about why to use type specs and what is the big deal. So one of the answers that people gave was, it's a good first thought when you're considering to change a particular function. Now, I didn't think about it that way, but the fact that you can know what a function returns at my first site without actually looking at the code was something that got me very interested, because it saves me the whole time of looking at the whole function in more detail, to understand what's happening within it, and turns out it also is helpful in terms of reading library's documentation, and that's where somebody is trying to ask for the same question like, why should I use type specs? Because it can help you understand code much more better. So the whole thing of finding other people's solutions, trying to see what made the solutions better, and also the fact that trying to understand why type specs are really useful in Elixir, made me more curious and asked people for more answers, and that's where Slack was useful, and what I ended up learning from this experience, I even wrote a blog about this, so that people who have similar questions can also get answers on why to use type specs. So that was something that was a good takeaway for me from the whole experience of learning. So many things just from another exercise of exorcism, and pretty helpful as a beginner because again, getting clarity for these things might not be obvious, because I was not even able to find these answers in the online documentation. So turns out even if you are in that situation, where you're not able to find answers for certain questions on documentation, you can try to get answers more faster through forums like Slack. So this is how my final solution looked like. It is modularized more, it's much more cleaner compared to my previous solutions, and for me to even get there, I refer to some more people's solutions and just made my code more abstract in the sense it's much more reusable if people want to use. And that's one thing I really like about exorcism is that it really stretches you to think further about how much more you can improve your code. Moving on, I had one more exercise that I solved which is a word count exercise. The whole idea of this exercise is given a phrase, I want to count the number of occurrences of a particular word within that phrase, and I want to repeat that for all the words in that phrase. So what was my initial thought process of approaching this problem was, think of it as like a hash, and where the key will be word, and the value will be the number of occurrences of that word. So I was thinking about approaching this in the form of, okay, I should be able to create a hash, and within that hash I should have words as keys, and I should be able to loop them throughout the string so that I break them as a word delimiter, and I increment the count as then when I encounter the same word again. So the question was, how do I approach this in the functional world? Because turns out when you want to do this in a normal imperative way, you want to save the previous state of the result of say calculating the occurrences of say the first word, and you want to add up to that, but in the functional world, you can't mutate the state of a variable. So how do I go about doing it in the functional world was a question to me, and that's when I realized that there's an innumerable model, for example, in the Ruby world, and I realized I should drop parallels between what I've learned in another language and apply or just even look out if I can apply that kind of thinking, like will there be an innumerable module in Elixir, and that was something I wanted to explore next in terms of I wanted to approach this with a particular problem. This was one of the test cases that basically shows you that, okay, for a given text, this is how the result should look like. So in the functional world, because you can't mutate state, and even if you're looping through a particular structure, like a map, and adding the count to it is not straightforward. That's where things can get again tricky for you because we are used to thinking and solving this in a procedural way or a way which is basically saving stuff to state, and since you can't save stuff to state in Elixir, I was not sure how to proceed, and turns out this, somebody posted about this as a question on Stack Overflow, and they wanted to again do something similar. The whole idea was they wanted to basically given a set of RSS feeds, they wanted to update the RSS feeds, and they wanted to update the RSS feeds to historic data. So how did they do that was their question, and turns out the answer was given by Jose for this question, and he suggested that people need to make use of a use function in Elixir. So the way the reduce function works is basically, so this is a particular function body, right? So the result of the previous function, so the result of this particular function is used as an accumulator, which basically means a structure that in which you can add more stuff and that accumulator will be like, say let's say this is your accumulator, this accumulator can be used when you iterate to the next item, which will be two. So that's how you basically add on and see the count with respect to each particular element of the list. So this was something which was not very obvious for me from the documentation, and the Stack Overflow answer here really helped me to understand how does reduce work better in Elixir, and as you can see, Jose has mentioned very clearly the map at the end will still be empty because we can't mutate data structures in the functional world. So that's why we have to use reduce, and this is how reduce can be helpful when dealing with similar problems. And that's where again I raised another PR, this was on the Elixir core repo, and I said that, hey, this was not very obvious about how do you, how does reduce work, and can we make it more clear? And it was expected by Jose, and so that turns out like, these are basically how I ended up finding gaps as a beginner, and how I ended up feeling that, okay, if it's not very clear, let's try to make it clear for the people who will end up using this in the future. So also in addition to this, like in Ruby world, for example, there is a particular bot, there's a particular service called Hound, which basically gives you a code review comments on your pull request. Something similar to that is a service called Abert by Platform Attack where Jose works, and he's one of the founders there, and they have a service through which they go through your pull request, and they comment to you what can be improved in your code using a style guide. So the style, the static analysis tool that is used for giving you style improvements in your code is a tool called Credo in the Elixir world, and Abert integrates with Credo to give you feedback on how you can improve your code. So as a beginner, the more resources or the more help you can get to improve your code is something that everybody looks out for, and that's where I realize that in addition to using Elixir, sorry, in addition to using Exorcism, in addition to using Elixir Forum, in addition to using Slack, I can also make use of Abert to give me feedback on how I can improve my code and write more idiomatic Elixir. So yeah, collaboration with bots, that's possible. So now I took a step back. I have made decent progress. I learned a lot from a few exercises, but turns out in Exorcism, they are 89 problems, and with 89 problems, if I go about solving each and every problem, it takes me a lot of time, and I wouldn't have so much time to actually learn all these, solve all these problems and learn the language and then end up actually applying them in my real-world projects. I want to learn faster, and that was something I was caught in curious as to how can I end up learning things faster. That's when I realized that in one discussion in the Elixir track, they have a good mapping of what particular exercise that you want to learn and what are the concepts that you can learn through each exercise. Now this was very helpful to me because I wanted to proceed. I don't want to solve the same problems which make me, again, familiar with the concepts that I already have a better understanding of. For me, the next target was, I wanted to learn pattern matching. I want to learn recursion. So I started off with taking the surplus exercise, and that's the last problem I talked to you about. This is a problem which really got me thinking about functional programming in more depth. So I chose this exercise because it would teach me two things. One was pattern matching and one was recursion, and that's why I thought of taking a deep dive into solving this. So the problem statement for this, as you can see, one and two, you have to determine if the first list is contained within the second, or the second is contained within the first, or whether both are contained within each other, or if none of these are true. That was the given problem statement. And how I approach this problem. My initial thought process for solving this was, hey, this looks like sets. Let me see if I can find a subset function in Elixir. And turns out there is a subset function in Elixir, and that is with a library function called mapset. And if I use mapset or subset, I can find whether a given list is a subset of another list. Now that worked for me pretty well, except for one test case, which was this test case. If you observe closely in this particular, so they have an interactive shell in Elixir, where I try to execute the same code as for the test case using the same list values, and turns out it returns true. But what is expected from the test case is, it should return unequal. So my code was in such a way that if it returns true, it should be returning equal, whereas if it returns false, it should return unequal. But since it was returning true, it was returning equal and what I wanted was unequal. So it made me realize that the way mapsets subset function works, it does not take into account the order of the items or it does not take into account duplicate items. So what it basically means is that if I have one, two and one, two, three, it will look for something as for the problem statement, if it has to be a sublist, I need one, two, one, two, three for it to be a sublist of the bigger list. But I have one, two, three, one, two, instead of one, two, one, two, three. So that's why unequal. So I was like, nah, subset doesn't work for me. I have to try something else. And that's when I basically went about looking at, thinking about, hey, I have two lists. I can find the difference between two lists. Even in sets, I can subtract one set from the other. And that's how I can see if I can find the difference between two lists or if one is a sublist of another through the difference operator. This didn't work for me for two particular test cases. One of them was a recurring values unequal test case. And the other one was a test case where a huge sublist was not in another huge sublist. That particular test case, when I ran it against this solution, which made use of the difference operator, was taking too long to execute. And that made me realize that I should probably stop this and just think about it, because it was not really helping me. And instead of one, now I have two test cases failing. Why the difference operator doesn't work? If you see on the right hand side, it basically shows you that it, again, the difference between one element and the difference the way it works is, is on a per element basis and not against the entire list as a whole. So one against one, it can be striked through similarly for two, but since three cannot be striked through against one, which is the smaller sublist, I'm left with three, two, three, two, one. And that's where I realized that, okay, this approach doesn't work for me. What happened next was I was stuck. I had the feeling of the imposter syndrome where I was stuck and I was not sure how do I proceed. And I was just thinking, am I not able to solve this? Am I not thinking in the right way? How do I proceed? Things weren't very clear to me and I was looking for some guidance or some direction. How did I proceed? So I submitted my solution on Exorcism and as I was exploring some other people's solutions, I was mainly reading their comments. I wasn't actually looking at the solution because for me, I didn't want to see people's solutions. I wanted to see what people were saying in their comments about solving this exercise. Turns out there's another guy on Exorcism who had the same problem with one of the test cases which I was not able to make pass, which was a huge sublist is not in a huge list. And that's basically nothing but this particular test case. So two huge sublists, you're comparing this thing like on a element by element basis and that can take a hell lot of time to determine if one. So basically I'm comparing the whole list against a length against the other sublist to see if they're actually, if one is a sublist of the other. Well, so he asked the same question in his solution. He submitted a solution which did not fully work and he got a hint from somebody. So the guy who gave the hint took a very small example. Let's take two lists, right? B and A. Now we have to check whether the list B is whether a subset of list A. So you'll compare one, two, three, four, five against a similar list which has at least five elements. Well, that's when you can find whether it's an equal list or a sublist, right? So I would compare one, two, three, four, five against two, three, four, five, six. No, if it's not a sublist, you move on. You compare one, two, three, four, five against the next set of items which is three, four, five, six, seven. Now, as soon as you compare one, two, three, four, five against four, five, six, seven, stop. You realize that you're comparing a list A which has got five elements against a list which has got four elements. That's when it was like a aha moment for me. Like as long as length B is greater than A, proceed with your comparison. As long as length B is not greater than A, stop. Because there's no point comparing two, three, four, one, two, three, four, five against five, six, seven, six, seven, and seven. Because you already know that it is not a sublist right by now. And that's where the hint was very helpful to me. And I applied the hint to my solution and I was able to get an answer without actually seeing somebody as a solution. It just gave me more confidence that, hey, it's okay if you're stuck. And I took another step back and I just had some reflections from this. I asked myself, did I try honestly? And did I try to find ways to get unstuck? Was I fast enough at getting unstuck? And did I identify missing gaps between my thought process and somebody else's thought process to solve the problem? And I also realized a bigger thing which was not very obvious to me was, it's okay to ask for hints in excessism in addition to asking for help. And you don't necessarily have to see somebody as a solution. You can still hold on to your confidence, just ask for hints. And so this again, where they talk about imposter syndrome, there was an article by a person called Alisa Lou and she basically says, what I know is definitely a small subset of the entire universe. And learning to program is hard and learning anything worthwhile is hard when you're starting out. And that's just reality. That's not imposter syndrome. How many of us actually think about it to that much depth? So it also helped me realize that there was a missing debugging chapter in the Elixir documentation. And very recently I proposed to the guys on the website or the main collaborators of the platform that, hey, we're missing a documentation chapter on the getting started guides. And I'm currently working on adding some documentation that you can get up and running with Elixir much more faster. This also made me realize one more thing, how to be a better programmer. If you see over here, this is one solution to sublist where a guy is suggesting that you have a given function called includes and you're basically trying to check if one string or like one list is included within another list. And what he was suggesting was in the string documentation of Elixir, they have a function called contains. Well, when you're trying to check if a list is within another list, you can also use the same function name contains instead of using the word includes. Why do that? Well, just think about it, right? If your function names that you write in your custom code, if that is very similar to the actual standard documentation, it makes things much more easier for you to remember and actually apply in your world world problems. Well, think about more complex custom names with respect to functions, right? They're hard to make use of and it basically involves looking back. Whereas if you're using standard, if you're using function names which are very similar to standard function names, it makes it much more easier for somebody to think about it without actually somebody looking up as to what the method can do for you and it basically ends up saving you time. So, and this is something you can apply across any programming language that your function names, if they're as good as standard function names, they're much more easier to use and to recall whenever you need to use them. So that was like a high level learning for me. And basically even comparing my solution to other people's solutions helped me learn how to write better Elixir code. And this is actually somebody else's solutions. He has done six iterations to this particular problem and if you see each of the iterations has got a lot of comments and this is something I would encourage you to check up whenever you get some free time. And that's the beauty of excessism, right? That collaboration is something that they promote and they promote you to go and share your ideas with everybody. So this is how my final solution looked like. I had five iterations to solving this problem and through each iteration, I commented whatever I learned and what was my approach. So that was pretty helpful to me. And so to wrap up, basically what I realized was the Elixir forum is very helpful when you want to post a question or just get unstuck. And they have so many categories. They have categories with respect to getting started, learning resources, libraries, even the Phoenix framework and also something specific to deployment testing, et cetera. In addition to that, since if you're a big nut to Elixir, you just see that people have asked questions like how do I proceed learning the language and how do I get better at it? So you'll really find quite a few interesting insights on how did other people approach the language. So the whole point is that they're using state of, the language is using state of the art tools like discourse to help you get started with learning a new language. And that's what really makes learning even more fun when you're able to get unstuck faster and you're able to get help. And even for the Elixir lang slack, they have so many channels where you can actually get help. They have channels for testing. They have channels for beginners. They have channels for the Phoenix framework. They have channels even for Ecto, which is a persistence layer used in Elixir. And a lot of other channels that you can basically make use of to find specific answers to specific questions. And turns out in many of these channels, there are even core contributors to those libraries who will be there to probably help you out and help you get unstuck. So something that really helped me was the beginners channel. So I would definitely encourage you to check it out. And I realized recently, as I was researching more about this, Robert Warding, who's the creator of Orlang, spoke about one thing. When he was learning Orlang, or basically when he was actually giving courses on Orlang or Elixir, he found three things that people get stuck with when they learn the language. One of them is immutable data, one of them is pattern matching, and one of them is recursion. So I'm glad I solved the subject exercise because it helped me understand recursion and pattern matching better. So the whole idea of relating the concepts you want to learn to an exercise was something that really worked well for me because I didn't really have to solve 89 problems to understand these concepts. Because at the end of the day, we all want to learn something fast enough so that we can actually be able to apply them in real-world projects because that's how we feel we are actually productive, right? That's when we really feel we get the real experience. So doing specific exercises and doing small exercises really helped me along the way. Next steps, how you can go about proceeding with learning. You can definitely use exercise as one of the ways of solving problems. But yes, please note, it's very important that you post conversations, you have conversations on the platform to really benefit from your experience of solving problems on that platform. Because without the conversations, I've seen many people end up submitting their solutions, but they don't get feedback. And it's also important for you to give feedback. So if you even start a conversation with, okay, these are the problems I encountered and this is how I solved the problem or this was my approach. If anybody can guide me on how to solve this part, people who actually even review a solution will know that you have given them enough context. I mean, think about it, right? If somebody back then did not go and comment how that person was stuck and how that person got unstuck and somebody did not see that, I would still remain stuck with learning those concepts and I would still look around for finding solutions and mentorship is something which is not easy to get. So if you can get mentorship this way, make the most of it. Other ways of learning the language, I think you can use Advent of Code, which is something that you do once a year and somebody has posted on the Advent of Code channel in Elixir Languages Act, they were able to understand streams better through solving some of the exercises there and that got this guy excited and he went about saying that, okay, I'm gonna go and solve some exercises from Advent of Code. I feel it's okay to use Advent of Code as a platform to learn the language, but if you're starting off, I think this is like the next level because the whole mapping of concepts to exercises is not very clear with Advent of Code, I think. And in addition to that, you can use Elixir Cones. Dave Soms also has another course on Elixir for programmers. It's an online course, which gives you hands-on training on how to use Elixir and somebody has even mentioned that it's a good way to learn Elixir and they've had good experience of learning things that way. So another takeaway for me was the whole idea of learning, unlearning and relearning. And that's where I realized that if you're a programmer who's coming from a different background, it's important to think about things in another way. And that's why you have to probably be more conscious and mindful about your habits in terms of problem solving. Like I did in the case of the exercise which made me realize that I don't have to use variables like in the giga second exercise. And contributing to documentation has its own value. Jose Valim encourages people to contribute to documentation. He's mentioned that over here. And I think that's basically, there's even a guy who's giving a talk at a conference of Elixir called MPEX Los Angeles in 2018. And he also highlights one point that the docs can play the gap between a beginner and an expert and providing everyone a way of getting unstuck and understanding things better. I mean, just think about it, right? If the documentation was not clear enough, even as a beginner, you don't feel like continuing with learning a language. So the fact that you're making contributions to the documentation is having a much more bigger impact than you can imagine. And yeah, the power of collaborative learning. The whole idea of even collaborating passively where I didn't have people answering questions to me at a given point of time, did not stop me from learning. If you see, this whole conversation goes back to 2014. Somebody saw this in 2014 but they made a very conscious attempt of actually commenting about their approach and what they learned along the way. That has helped me three years further down the line. And I'm thankful to them because without that, I would still be stuck with learning a few concepts in the language. So collaborating with learning a language and also the community is very approachable to beginners. Do small things, like just like how life is about small wins and celebrating them, doing the small problems, it gives you the confidence to make sure that you're progressing in the right direction. And yeah, be proactive about your conversations on the platform, make use of hints. Also believe in yourself that, yeah, you can do much more than just actually learning the language. You can even give back to open source. And yeah, well, giving back to open source is actually boosting adoption of Elixir. So you're playing a much bigger role than you can imagine, than you can think of. And yes, collaboration can be passive as well. And even collaborative learning through a passive way can give you good ways to make progress. And sum up, I would like to talk about one more thing. Through the existing platform and basically even through collaborative learning, one thing I realized was, how do I be a better problem solver? Because if you see, this guy asked one question with respect to the Bob exercise. He says that, but it's how that conclusion was reached that truly interests me. So at the end of the day, we want to be better at language, but we also want to be better problem solvers because that will even help us back in our work. And that's where collaborative learning and using platforms like Exorcism where you can compare solutions can really help you. And to sum up also, I would like to mention this one thing, always have a beginner's mindset because the potential that you have as a beginner can be sometimes much more than what you can have as an expert. Benjamin Tan, who's a local Singaporean and he's written a book about the little old, the elixir and the OTP guidebook. I found this in one of his blogs where he was again talking about the same thing. Being a beginner is precious and celebrated and it definitely can help you make a much bigger impact than you can imagine because with a beginner's mindset, you have fresh ideas and you can always explore your potential much more and imagine the possibilities are much more than what you can imagine. So yeah, that's pretty much about it. I would like to thank Anil for some feedback on the slides and that's about it. Feel free to keep in touch if you'd like to and any questions? Yes, please. Can you actually tell us why you started learning it? Yeah, sure. So I had knowledge with, so I started off with learning C back in my undergraduate degree and sorry, yeah, sorry. So I started with learning C in my undergraduate degree and I proceeded with learning a little bit of Java and I got into Ruby programming in the professional world. I was just casually exploring stuff as a programmer and trying to figure out why are people excited about languages in general or why do people, how do people keep learning new things? Because I mean, we know as just as a person in general, I realized learning is a good way to keep yourself up to speed and for me, like even people are talking about things like functional, imperative, I was like, what are all these concepts? I don't know what they are and that's where I wanted to explore further. So your question was why did I want to learn Elixir specifically? For example, specifically or whatever other languages? Sure, so I chose Elixir specifically because first of all, I had knowledge from an object oriented background. I knew how to write procedural code. I want to learn about writing things in another style. Why? Because there was one quote on Twitter where somebody was saying that if you're not thinking about how you're problem solving you're probably not learning enough to the right language and that's where I realized that maybe I should just think about learning it from the approach. I mean, just imagine, right? Whatever we apply in our daily life, if you just start thinking about things from somebody else's perspective, it opens up a mind and that's pretty much true even in the case of programming. I'm confident about writing procedural code. I'm confident about writing imperative code. I'm confident about writing object oriented code but what are the benefits of writing functional code? That was something that caught me curious. Why was there a hype around this? So what Elixir was more like? Yeah, yeah, sure. So Elixir had a Ruby-like syntax and the Ruby community is very famous for being very developer friendly and people like Jose Valim have come from the Ruby community where he has been like a core contributor and so the syntax is kind of similar and the community is very supportive. Also one more thing that I realized is in the Elixir community, Jose Valim is very closely involved in not only Elixir projects but also projects like the Phoenix web framework and that is really helpful, especially when you want to learn things just beyond Elixir and the fact that he's also ideas and proposals gives me the confidence that I'm proceeding to learn something under a person who's himself very motivated and he's very supportive and it makes me think I'm thinking about it in the sense of being in somebody's leadership who cares about giving back to the community and who's also challenging the status quo at the same time, yeah. Guys, sorry to cut you off. We'll have the questions to Monish after the talk by Nate. Matt, is it fine? Yeah, sure. Cool. Thank you very much, everyone.