Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

    React vs. Vue vs. Angular: which JavaScript framework is best?

    Sooner or later in your front-end development career you’ll find yourself at a common crossroads: should I use a JavaScript framework for my project, and if so, which one? It’s a familiar scenario to a lot of front-end devs out there, and each developer you talk to will likely give you a different answer. The truth is, there are many JavaScript libraries, frameworks, tools, projects, and platforms that help developers to build user interfaces, solve front end problems, and ship excellent products faster. When it comes to building user interfaces, the most popular libraries are Angular, Vue JS, and React JS. All three are concerned with empowering developers to build complex user interfaces in a modular way. They encourage breaking down of complex user interfaces into components or modules and reusing these building blocks to construct different areas of the app or website as needed. Let’s take a look at a Google trends search that covers the past three years from late 2017 through to the middle of 2020. Looking at the search data from Google Trends, you can see that Vue has been slowly, but steadily, gaining interest over the past few years. React has increased dramatically, whilst Angular has declined slightly over the same time frame. A lot of enterprise development houses trust their application development to Angular because of its robust credentials and holistic approach to wiring up different parts of modern application development β€” things like app navigation, two-way data binding, data handling with APIs, and more. Vue is becoming more popular as time goes on, yet interest in React remains consistently strong with new students rushing to learn Facebook’s slick UI library. Indeed I’m a big React fan myself and have even written a beginners course on React that covers everything you need to get started building realistic apps. It’s also worth noting that jobs requiring React and React Native (React’s mobile-focused offering) are plentiful and this, in part, is responsible for fuelling the huge rise in React’s popularity. But which one really is the best JavaScript framework? And if you’re interested in learning a framework, exactly which one should you invest in? Let’s explore each framework’s background and walk through the pros and cons to help us decide. Vue JS came onto the scene around 2014 and was developed by a former Google employee Evan Yu. Vue is a progressive JavaScript framework, similar to React, and has a rich ecosystem of additional libraries and plug-ins to enable additional functionality. Angular (formerly Angular JS, which is a very different beast), is a fully-fledged framework released back in 2009. It boasts a very mature framework that handles everything you need to build rich, data-driven user interfaces right out of the box. It offers an MVVM (Model, View, View Modal) approach to development structure that separates the working parts into their respective areas of responsibility. React is a declarative, efficient, and flexible JavaScript library for building user interfaces. React was developed by Facebook and released to the open-source community in May of 2013 ). React allows us to break down our complex user interfaces into smaller, bite-sized pieces of functionality that operate on their own managing their own 'state', given some sort of input data, you'll see referred to as 'props'. This is a duplicitous question as it pits each framework against one another and it really boils down to opinions and preference. There are many solid reasons to choose any of these three frameworks, or indeed, none at all. Remember, that any library, framework, platform, language, design, pattern, whatever, are all just tools . In the same way that you wouldn’t use a hammer to unscrew a bolt, sometimes it’s about finding the right tool for the job. When you have a choice of hammers, then it can be a simple as β€˜I prefer this one over that one’. And it’s just as easy to write bad code in a good library. That said, React is a popular choice for a reason and is a great option for those beginners looking to get their feet wet with their first big library or framework.

    Thumbnail Image of Tutorial React vs. Vue vs. Angular: which JavaScript framework is best?

      Clojure - A "Learn once, run anywhere" candidate you probably didn't know about

      Clojure is a functional LISP dialect written by Rich Hickey. It is recommended by Paul Graham and Uncle Bob Martin as the go-to modern LISP. It is used by hundreds of companies , and often reaches the first page of Hacker News (for example, here , here , and here ). Clojure is a usable, yet purist, language. It is not as strict as Haskell or Ocaml, nor as forgiving as JavaScript or Python. It stays true to the functional aspect and stresses the importance of building simple systems. It doesn't run on a VM itself but is hosted on the VMs of existing languages. There are three official ports of Clojure: In addition to the official ports, there are many community-led efforts to run Clojure on top of Go, Rust, Bash, C++, and Erlang. This hosted nature lets developers tap into existing ecosystems and extend existing codebases written in one of the host languages using Clojure. Clojure also makes mixing host code and Clojure code trivial. You can easily cross the Clojure bridge and write code in the host language. Although Clojure comes with its own compilers and developer tools, it is essentially a meta-language hosted on mature VMs. This property puts Clojure in a different realm compared to other LISPs. LISPs have never been "mainstream" and one of the reasons behind this is the lack of community. If nobody uses LISP, there will be no packages for LISP, which makes it hard to attract new developers. Clojure bypasses the community problem by tapping into existing communities. I don't mean to say that the Clojure community is not strong - it's quite the opposite. The Clojure community is rich and welcoming, and the ability to tap into other eco-systems is just a bonus. LISPs are syntax-free. Compared to C-style languages, there are fewer constructs to remember, and the rich standard library makes data manipulation easy. Most code written in Clojure is almost always more expressive than its C-style counterparts. Clojure is a homo-iconic language. This means that the code is written using data structures. This leads to a terse and concise expression. Image from Jacek Schae 's article on Medium Clojure, like all LISPs, comes with a super-powerful REPL. The REPL is a bridge between source code and runtime. It provides multiple features like code-completion and inline eval. The REPL leads to lightning-fast feedback which ultimately leads to greater productivity. This aspect of Clojure is so unique that I wrote an entire post about it. Read More: Reaching flow state with Clojure's REPL Clojure runs on top of other languages and lets you talk to the host directly . You can install and use host packages using popular package managers like Maven and NPM. You can also bypass Clojure and write code close to the metal using the host language's features, such as Promises in JavaScript or Classes in Java. Clojure makes sure to not hide the host. It doesn't pretend that the host doesn't exist - it's actually common to write Clojure code at the host level for performance gains. Clojure implements the CSP model of concurrency management which is similar to that of Go and Erlang. Clojure's creator Rich gave a talk about how this implementation came to be. It's a must-watch if you'd like to understand the benefits of CSP over Promises (ie. the actor model). Instead of callbacks, where process-A calls process-B on completion, the CSP model introduces queues. In this way, process-A becomes independent of process-B and just puts its results in a queue. Then process-B can dequeue and proceed without interacting with process-A. All Clojure data-structures are immutable and lazy. This might be hard to understand at first, especially if you have a background in JS. But once you get used to the idea, your code will become local and you will be forced to push side-effects to the edges of the system. This might not make sense until you experience it for yourself. Since the language has next to no syntax, the backward-compatibility is gold. It's fairly common to see heavily relied on libraries that are not updated for years. Okay, years might be an exaggeration, but definitely months. This doesn't mean that the project is abandoned. In most cases, it means that the project has reached equilibrium and can be relied on safely. Technologies like Datomic and Integrant are so advanced, it's as if they are from the future. The Slack and Reddit groups are active and helpful. Every coin has two sides, you just need to pick the side that serves your purpose. Clojure also has some "down" sides. This is perhaps the most debated aspect of Clojure, to the extent that there is a famous open-source initiative called Typedclojure , that brings static analysis to Clojure. The community and the language authors acknowledge the value of types, but also believe that Haskell-like typing is not the best way. A famous library called core.spec has been in development for many years now. It implements typing in a different way and can be used optionally. You can check out this talk by Rich to gain more insights into why spec is a better option. However, this might be a deal-breaker, especially when companies like Microsoft are pouring $$$$ into marketing Typescript as the language we need. Clojure development aims to provide fast feedback, but this means tighter integration with the editor. Historically, Emacs has been the choice for most LISPers, but this is changing with packages like Calva for VS Code , Cursive for IntelliJ , and Conjure for Vim . Despite the packages available, knowledge regarding how to use the tools efficiently is not widespread. When you see LISP code for the first time, chances are that your brain rejects it. You might wonder why parentheses are in the wrong place and why is everything so cluttered. This problem goes away over time, to the extent that you start seeing code as a tree data structure. It's commonly heard among LISP programmers that brackets become invisible. But until then, you need to live with them and the worse part is you need to include them while writing code, ensuring that you didn't miss a closing bracket. While it seems like a big deal, handling brackets and parentheses in practice is a non-issue. Packages like Paredit and Rainbow Params make it really easy to manage LISP code. The downside is that you need to devote time to learn how these packages work. Clojure is a functional language, and in this sense, all functional languages are hard to pick up. Trivial tasks like defining a variable might seem hard, especially if you come from a C-style language. This is not a downside if you are already familiar with functional techniques. Compared to JS and Python, far fewer companies use Clojure. This is a fact, however, things are changing and job opportunities with Clojure are increasing. However, they still fall short of opportunities with other languages. Many Clojurists tend to introduce Clojure to their companies, or sometimes work with other languages full-time. Writing a functional language changes how you approach problems and the concepts can be transported to other languages too. If you have even the slightest interest in learning Clojure, you should hear the following reasoning from Rich Hickey directly: but if you want my half-baked, less accurate description, then read the next paragraph. Simple and easy are used interchangeably, but signify two very different concepts. Simple means not layered, or braided like a knot, the opposite of complex. Whereas easy signifies nearness, something in reach, the opposite of hard. npm install complexity is easy. You can just issue a command and solve a complex use case. But this is not simple. You don't necessarily know the dark magic your libraries do in the background. Relying on easy solutions can lead to complexity in the future. Relying on simple solutions addresses the complexity that will arrive in the future. Clojure tries to make simple easy. But this is not as competitive as easy. You need to put in more work upfront to reap the benefits later. This is in sharp contrast with other popular models, where you can get everything working almost immediately, without considering the complexity introduced. The problem with this approach is that when things get out of hand, the whole system has to be re-written using Typescript. Again. Clojure will help you grow as a developer. Your style of writing JS, Python, etc will change. It will help you reason for and question your choices. And will probably lead to better decision making. You'll love and hate Rich Hickey, the Clojure BDFL (Benevolent Dictator for Life). But his talks will change you and help you grow. That being said, if you are looking for an answer to "Is Clojure for me" in an article on the internet, then Clojure probably isn't for you. If you are happy and comfortable writing in your current language there is no point switching, but if you do feel limited and restricted, you might want to give it a go. I started working with Clojure in 2016, after almost 8 years of Python and JavaScript (PHP, Ruby, Java, etc). I was lucky to find a job at a company that worked exclusively with Clojure and learned from the best. There were many obstacles in the way, many tools that I had to learn, and many concepts that had to be re-learned. I have compiled my learnings from this journey into a course on Clojure for React developers. This course is the distilled version of my experience where we will walk through building a complete frontend application (Clojure semantics, tooling, UI, Auth, Routing, State Management, and API integration) from scratch. If you liked this article, you can check out our course the newline Guide to Clojure for React Developers.

      Thumbnail Image of Tutorial Clojure - A "Learn once, run anywhere" candidate you probably didn't know about

      I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

      This has been a really good investment!

      Advance your career with newline Pro.

      Only $30 per month for unlimited access to over 60+ books, guides and courses!

      Learn More

      Reaching flow state with Clojure's REPL

      Did you know that you sleep in multiple phases? At first, you lie down and close your eyes, but it's still easy to be woken up. As sleep progresses it becomes deeper, to the point where you lose your sense of time and start dreaming. This stage is called deep sleep or REM sleep and it's essential for learning, memory, and wellbeing. The catch is - you cannot progress to the REM stage until you have finished the earlier, non-REM stages. Flow state is akin to deep sleep. When you reach your desk, you are not immediately productive. You read your emails, check Reddit or Hacker News, and then slowly ease into the flow state (at which point you get disturbed by being called for a meeting, of course!). The point is, to work efficiently, we need to progress in stages until we reach flow state. Any external hindrance breaks the flow and forces us to start again. External distractions can be due to the surrounding environment (kids, meetings, food breaks, angry neighbors) or your tooling (compile time, documentation lookups, unrelated bugs, etc). Library and language developers cannot fix your issues with your angry neighbor, but a lot of effort has been made to improve the tools. In this post, you will learn how REPL driven development can provide fast feedback and get you into the flow state sooner. Working with an interpreted language like Python is faster than a compiled language like C++, in part because of the feedback cycle. In the same amount of time, you can test more changes in Python code than C++ code, because you don't need to compile. Eliminating the need to compile is equivalent to eliminating external distractions. You can experiment with more ideas without hurdles, and progress more quickly towards reaching flow state. But this comes at the cost of performance. Compiled languages have a slow feedback cycle. This leads to efficient performance, but a compromised developer experience. Languages like Go focus on fast compilation, making the feedback loop short without compromising runtime performance. Frontend JavaScript has tools like Browserify's Live Reload, React HMR, and Fast Refresh, which compile your program and execute it so you can reach or maintain your flow state. If it takes a long time to compile every change, you'll probably never reach flow state. For compiled or transpiled languages, the code we write and the code that's run is inherently different. For example, you might be writing Typescript, which is converted to ES6 before being executed in the browser. The problem is that the entire representation of the codebase is flushed down each time you make a change. The transpiler is efficient and makes sure to recompile only the files that were changed and depend on the change. But it is still hard to cherrypick the exact function or variable that changed and update just that piece in the runtime. There is no one-to-one mapping of all functions in the source to compiled code, so we resort to the next best strategy - recompilation (ie. compile the entire module). The lack of direct mapping leads to a significant loss of power. These mappings exist to an extent in source maps, but source maps treat code as text. Lines are indexed and recorded. A source map can tell that lines 1 to 4 of source code produced lines 14 to 28 of compiled code, but it cannot tell the position or semantics of the function defined on line 4 in the source code. This lack of mapping is mainly because C-style languages are written like a natural language. Computers are not good at parsing natural languages. Computers are good at parsing data-structures and discrete forms. What do we gain if we can somehow get this one-to-one mapping of source and compiled code? An easier path to flow state? Imagine a language that is not written like English prose, but expressed in terms of data structures. Imagine if we could somehow connect the source code to the runtime (compiled code), to the extent that we could pinpoint and execute a function f defined in source code right from the editor. This is what it would look like: Figure 1: Executing functions in the REPL In the GIF above, we have ClojureScript source code in a text editor, connected to a runtime (browser). We can execute functions as we write them. No refresh, no recompilation, no interpreter. Just one function, picked up, compiled, and executed right inside your editor. And the best part is, this system has been stable and in production since 2015 (perhaps even earlier than that). To understand the REPL and REPL driven development, we must first introduce Clojure. Clojure is a dialect of LISP (short for List Processing). LISP code is written in the form of trees, unlike C-style code which is written like natural English language. Consider a function that takes a Hash Map like {:a "b" :c "d"} and returns a query string like "a=b&c=d" : This code can be represented in the form of a tree as follows: Figure 2 : Tree representation of LISP code Because of the discrete data structure form, the compiler can easily create a one-to-one mapping of functions in source (CLJS) code to output in compiled (JS) code, and can also execute a selected part of the source in runtime. Like in Figure 1 above, the code (+ 3 4) is written in ClojureScript, compiled to JavaScript, and executed, and the results are returned to the editor. The REPL is the hidden agent that facilitates this source to runtime bridge. It takes source code, executes instructions in runtime, and brings the results right back to the point of definition, ie. the editor: Figure 3: Scope of the REPL 1. Your source code lives in your editor 2. The Shadow (compiler) converts this code to browser ready JavaScript 3. The REPL then sends execution instructions to the compiled code 4. This is then executed in the runtime (Node or Browser) and the result is returned to the editor REPL driven development leads to lightning-fast feedback. You just write pure functions and execute them as you are typing them. No need to leave the editor, no need to hot reload, no need to interact with the UI. In this talk at JSFOO Bangalore, I showcased REPL driven development (Start at [4:39] to get to the juice): This talk explains how the REPL fits in with common frontend tasks, like building forms and handling state. According to the official Clojure docs, the REPL is a user interface to your program . Think of it as a way to execute parts of your code with immediate feedback. This makes it a powerful development tool. You already saw how functions can be executed in the REPL in Figure 1. Since the REPL can execute any source code, you can use it to check the methods a third party library exposes. Figure 4: Inspecting methods exposed in the React package A large part of UI development involves interacting with state. The REPL can be used to read the data structure storing your state. Figure 5: Inspecting app state in real-time Form states are generally saved using one-way binding(like in React) or two-way binding (like in Vue). Since the object that stores the state is defined somewhere in the code, you can use the REPL to fill forms by changing interactions with the object. If you are building a multi-step process like checkout or signup, filling the initial steps might become tedious as your flow grows. You can define the steps in your source code, and execute it in the REPL. The UI will respond respectively. Figure 6: Simulating UI events on a React Native app In the GIF above, we have a Status App (A free, libre, open-source | GitHub.com/status-im/status-react) messenger running on an Android device, and a REPL connected to it. We can simulate events in the REPL, essentially letting us develop complex flows, without even touching the device. If you are a mobile developer, imagine the time saved if you never needed to take your hands off the keyboard to interact with the app. And the feedback is fire πŸ”₯. Flows like this can be saved as a comment alongside your source code and committed to git. This acts like documentation of what the developer was thinking while they developed this flow. Clojure is a hosted language that can compile to JavaScript, Java, and .NET. JavaScript can be used to build mobile apps with React Native and Desktop apps with Electron. This means that you can run the REPL on every imaginable platform. Clojure is the closest we are to the "Learn once, run anywhere" philosophy. Once you get used to developing in the REPL, reaching flow state becomes more achievable. The entire act of transpilation, seeing the UI, clicking buttons, checking console changes, and executing functions all happens in the REPL. This method brings you close to the runtime and lets you inspect the internals of your application with ease. The Shell (like the Python or Node shell) is a rudimentary version of the REPL. It's different in the sense that it cannot reload pieces of code like Clojure's REPL. This is partly because of how Clojure and LISP-like languages are written. It is also different because no stable tooling exists to connect the Shell to the editor. I would go as far as saying that Clojure is the only stable language with a fully-featured REPL plugin for all major editors. I first learned about the REPL after 8 years of building full-stack applications. My mind was blown and I wondered why this wasn't the norm. Why didn't more people talk about it? Why was I not able to find it? Clojure is not as well-known as JavaScript. On top of that, when you get started, all you see is ugly syntax, with brackets in the wrong place. The concepts that this article showcases might be a bit overwhelming at first. I was lucky to get a job working with experienced Clojure developers at mission-critical systems. I bundled my experience into Tinycanva - A frontend ClojureScript course for React developers. In this course, we'll set up Clojure from scratch, learn about the eco-system and developer tools, and build a Canva clone with a Firebase backend. If you like the idea of fast feedback and flow state, check out our course the newline Guide to Clojure for React Developers.

      Thumbnail Image of Tutorial Reaching flow state with Clojure's REPL

      React Dropdown Tutorial for Beginners: Create a Dropdown Menu from Scratch

      In this hands-on tutorial, I’ll show you how to build a React dropdown menu from scratch, without any library. We’ll cover:Β how to get the selected value from the dropdown, and how to create the dropdown with both functional and class components.React comes with a lot of component libraries for virtually everything you need, from forms and autocomplete search boxes to sliders and navbars. Although these UI libraries can speed up your work and are pretty convenient to use, they can make your project more complex and add to the bundle size. So unless you need to use a library for a specific project, it's preferable to write your own components and keep them as simple as possible. In this article, we'll create a basic React dropdown menu, first as a functional component, then as a class component. We won't use any library; instead, we'll define the elements of the dropdown using styled-components. By the end of this post, you will know how to create a basic React dropdown menu using functional and class components. Although this is a beginner tutorial, I won't cover the basics of React, so in order to get the most out of this article you should know: Before we start, let’s initiate a new code sandbox with React and install styled-components as a dependency. We’ll remove the styles.css file, as we won’t use it, and we’ll create a new styles.js Β file instead, in the src folder, where we’ll build our styled-components.Β  Also, let’s create the Dropdown.js file where we’ll develop the component. Your project structure should look like this:Β  Before we dive into the actual component, here's what we’ll cover: You can find the final project here: React dropdown - exercise .Β  To create the dropdown, we’ll use the HTML <select> element. This has the following structure:Β  So we have the dropdown element itself (the <select> tag), and the dropdown values (the <option> tags). Next to these, we also want to display a heading on top of the dropdown, to tell the users what this list is for. So we’ll need to add a <label> tag.Β  Finally, if we want to send the selected options to an API endpoint, we need to wrap this entire component in a <form> tag and to add a button, using the <input type=”submit”> element.Β  So let’s create these components as styled-components first, in the styles.js file. First, we'll create the wrapper, which is an HTML form. Next, we style the <select> tag and its children. Finally, we style the button. Next, let's import the components and create the dropdown component skeleton in the Dropdown.js file. We have our dropdown component, so let's include it in the App.js file: Right now, your app should look like this. If you select one of the options in the dropdown menu, nothing happens yet. To be able to get the value of the selected option and send it to an API endpoint, we need to add a hook. In the App.js file, adjust the code as follows: Here's what we did. First, we declare a new state variable, which is called optionValue . We want this to be equal to the value selected from the list, so we'll add a function called setOptionValue , which will update the state variable to our selected value. To make this work, we need to add an onChange event handler to the Dropdown component, and to define the function that will be called. So now whenever the value of the dropdown changes, the handleSelect function will be called, and the state value will be updated to the one selected from the list. To test if this works correctly, I've added a <p> tag right after the dropdown, where we'll print the state value. All looks good, so now the only thing that we still need to adjust is the endpoint where we send the selected value. I'll add a fake API endpoint, just to test if the form is submitted correctly. In the Dropdown component, add this path to the action : That's all! Now let's create the same dropdown list using a class component. We'll create a separate project for this, to keep things organized. You can find the code for the dropdown class component here . We'll reuse the same styles, so let's first add styled-components as a dependency. Then, let's create a styles.js file, and copy-paste the previous styles. Next, delete the styles.css file, as we won't use it, and add a Dropdown.js file, for our class component. Copy-paste the code from the functional component - we'll start with that and refactor as needed. Here's the starting code: We'll do the same for the App.js file. Here's the starting code: Let's remove the useState hook as we won't use it. Instead, we'll initiate the state in a constructor, as follows: Now we need to add a render() to the component, to output our dropdown menu. The rest of the component is the same as before, but we've added this to the onChange handler as well as to the selected value. Now we need to refactor the handleSelect function as well, and to add it to the constructor. We've also added an export at the end, so now if we reload the app, we should see exactly the same form as before: As you can see, creating your own React dropdown menu, selecting a value from the list, and sending it to a backend API endpoint is pretty straight-forward, regardless of which type of component you choose: functional or class component. If you'd like to learn more, check out these React tutorials:

      Thumbnail Image of Tutorial React Dropdown Tutorial for Beginners: Create a Dropdown Menu from Scratch

      Rust Iterators: A Guide

      By the time you walk out of here, you should understand what iterators are good for, how they work internally, and how to create your own!Iterators are a fairly central concept to Rust. If you're looping over something, you're very likely already using an iterator. If you're transforming collections, you probably should be using them. If your function returns a lazily evaluated sequence of things, you should consider returning an iterator - especially if that sequence could be lazily evaluated. We'll take a look at how iterators are implemented, how to iterate over a collection, what sorts of iterators exist in the standard library, usage and common patterns for transforming data, and finally a few examples of useful crates that provide their functionality via powerful iterators. Skill-wise, you'll ideally have an understanding of I highly recommend having some sort of environment to run snippets of code in. The simplest thing to use is the Rust Playground . If you'd like a local environment, refer to The Book for guidance on setting that up. Essentially, an iterator is a thing that allows you to traverse some sort of a sequence. Note that since Rust's iterators are lazy, this sequence could be generated on the fly - you could just as well traverse an existing array of finite length or create an iterator that keeps spewing out random numbers infinitely. In Rust, iterators are typically implemented using the Iterator trait. All we need to implement that trait for our custom type is provide an associated type Item (this is the type of the elements of the sequence, returned by the iterator) and the next method. Let's try and implement an iterator over numbers from 1 to 10. The next method is expected to yield the next element of the sequence. It takes a mutable reference to self in case we need to keep track of some state between next calls, which is normally the case. We'll soon find it useful. The return type of next is Option<Self::Item> . If an iterator is finite, it needs to return None to indicate it has no more elements to return. Right now, this iterator will immediately finish, not yielding any items. Let's fix this. This should be pretty self-explanatory. Every call to next increments self.current and yields it until it grows beyond 10. So we have an iterator. Let's use it. The most basic thing we can do is simply loop over all of its elements: There's actually an Iterator implementation for the Range type in Rust! A Range is what you get when you type something like 1..5 . Instead of writing the above custom iterator, we could have simply done this: Sometimes you'll want to provide the user of your code the ability to iterate over your type, but without that type itself being an iterator. This will be the case with collections. If you implement your own vector type, you probably don't want that type to needlessly hold an extra iteration variable just in case someone wants to iterate over it. What we want is a way to create an iterator out of the collection. There are three mechanisms you'll typically see. If we want to iterate over a vector of chars, we could do something like this: If we leave out the into_iter() call, Rust will call that method implicitly anyway. This implicit call is important to keep in mind. Since into_iter() consumes the data, we cannot use the original vector later. One solution would be to explicitly call v.iter() so that the iterator is borrowing instead. Another is to provide a reference to v rather than the owned value. This way, the compiler can no longer implicitly call into_iter() since it doesn't get an owned value. It gets an immutable reference, so the best it can do is implicitly call iter() on it - and that's what we want. Then there's mutability. Following the same pattern, here Rust will implicitly call iter_mut() and give us an iterator that is mutably borrowing. If all you could do with iterators was loop over them with the for keyword, they wouldn't be all that useful. But there is a plethora of adapters that transform an iterator into another kind of iterator, altering its behavior. Most adapters you'll work with are in the standard library and exist as methods provided for the implementers of the Iterator trait . There are some crates out there (such as itertools ) that provide extra adapters via extensions. We're going to go through a few useful adapters, but I highly recommend taking a look at the full list in Rust documentation . We can construct an infinite iterator using std::iter::repeat . It would be a bad idea to iterate over it directly. If we wanted to print only a few 1s, however, we can use the take adapter for that. What take does under a hood is wrap the Repeat iterator in a Take wrapper. Take is also an iterator, but this one finishes after returning a set number of elements. A very typical feature of functional programming is the ability to map , that is to apply a function to every element of a sequence. If we wanted to find only elements that fulfill a certain criterion, we can use the filter adapter. We know how to turn a collection into an iterator. How do we turn an iterator into a collection? Enter the collect method, provided by the Iterator trait. We could try to convert from a vector to an iterator and back. This, however, produces an error. What Rust is telling us here is that it doesn't know what we're trying to collect into. collect has a generic return type and could give you a number of things: a vector, a linked list, a string, etc. You could even create a custom type that can be collected into. To let Rust know what concrete type we want collect to return, we can use the turbofish syntax. We can make this slightly shorter. The compiler should be able to figure out that we want a vector of chars, specifically, and not a vector of integers. When filling out type parameters, we can use an underscore to tell Rust, "Figure this part out yourself!" In a case like this, you might find it tidier to add a type annotation to the variable declaration instead. The whole thing will then look like this: Using collect , we can convert an array of chars into a string. We could also collect an iterator of tuples (where the first element needs to be hashable) into a HashMap : Things that can be collected into implement the FromIterator trait. That means this behavior is extendable! Check out the trait's docs to see which types can be collected into and how to implement new ones. We now have some idea of how iterators work and some operations we can perform on them. Let's put it together and see some typical use cases. Let's say we store customer data in Customer structs, which include a customer's name, e-mail address, and how much they owe us. Then let's say we have a list of such customers. We're tasked with producing a vector of all debtor e-mails so we can send them a generic reminder. How do we do it? The nice, idiomatic way is to get an iterator over customers , apply some adapters that will filter and transform the data, and then collect that back into a vector. Given the same Customer struct as above, and the same vector of customers, we can search the customer data for a specific person. There's no useful method defined directly on the Vec<T> type, but there is a find method defined on the Iterator type. What if we'd like to get the position of an element in the vector? Things get a little trickier, but create an iterator. We then have to enumerate it to keep track of positions. enumerate will wrap every element in a tuple of formthe the (position, element) . Then we have to change our find closure a little to account for the items now being tuples. Finally, once we unwrap the Option<(usize, Customer)>, we still have to extract the position component of the tuple, which is the 0th one. The str type comes with a split method that yields an iterator over chunks of that string. All you have to provide is a pattern to split by - commonly a char , a &str or a String . For example, you could get all the words of a phrase this way: And then you could transform them and collect them into a new String : These are some examples of third-party libraries providing some functionality via iterators. This just about exhausts the core concepts and basic usage. Hopefully, you should now be able to not only effectively transform collections, but (with some practice) also identify where providing iterators would make sense in your code. One thing to do now would be to simply read the module-level documentation for std::iter , and take a look at the provided methods of the Iterator trait . There are some useful tools to discover there that we didn't cover here!