Learning Elixir
By Ballou Kenny
()
About this ebook
About This Book
- Explore the functional paradigms of programming with Elixir through use of helpful examples
- Concise step-by-step instructions to teach you difficult technical concepts
- Bridge the gap between functional programming and Elixir
Who This Book Is For
This book targets developers new to Elixir, as well as Erlang, in order to make them feel comfortable in functional programming with Elixir, thus enabling them to develop more scalable and fault-tolerant applications.
Although no knowledge of Elixir is assumed, some programming experience with mainstream Object-Oriented programming languages such a Ruby, Python, Java, C# would be beneficial.
What You Will Learn
- Explore Elixir to create resilient, scalable applications
- Create fault-tolerant applications
- Become better acquainted with Elixir code and see how it is structured to build and develop functional programs
- Learn the basics of functional programming
- Gain an understanding of effective OTP principles
- Design program-distributed applications and systems
- Write and create branching statements in Elixir
- Learn to do more with less using Elixir's metaprogramming
- Be familiar with the facilities Elixir provides for metaprogramming, macros, and extending the Elixir language
In Detail
Elixir, based on Erlang’s virtual machine and ecosystem, makes it easier to achieve scalability, concurrency, fault tolerance, and high availability goals that are pursued by developers using any programming language or programming paradigm. Elixir is a modern programming language that utilizes the benefits offered by Erlang VM without really incorporating the complex syntaxes of Erlang.
Learning to program using Elixir will teach many things that are very beneficial to programming as a craft, even if at the end of the day, the programmer isn't using Elixir. This book will teach you concepts and principles important to any complex, scalable, and resilient application. Mostly, applications are historically difficult to reason about, but using the concepts in this book, they will become easy and enjoyable. It will teach you the functional programing ropes, to enable them to create better and more scalable applications, and you will explore how Elixir can help you achieve new programming heights. You will also glean a firm understanding of basics of OTP and the available generic, provided functionality for creating resilient complex systems. Furthermore, you will learn the basics of metaprogramming: modifying and extending Elixir to suite your needs.
Style and approach
An exploration of functional programming and Elixir with easy to follow examples using Elixir and the functional style. All the topics, concepts, and principles covered are clearly and concisely explained with either code examples or in depth discussions, or both!
Related to Learning Elixir
Related ebooks
Clojure Data Structures and Algorithms Cookbook Rating: 0 out of 5 stars0 ratingsTypeScript Essentials Rating: 4 out of 5 stars4/5Backbone.js Patterns and Best Practices Rating: 0 out of 5 stars0 ratingsAkka Cookbook Rating: 2 out of 5 stars2/5Parallel Programming with Python Rating: 0 out of 5 stars0 ratingsLearning Flask Framework Rating: 4 out of 5 stars4/5Building Web Applications with Flask Rating: 0 out of 5 stars0 ratingsSwift Functional Programming - Second Edition Rating: 3 out of 5 stars3/5Test-Driven JavaScript Development Rating: 0 out of 5 stars0 ratingsThe Little Elixir & OTP Guidebook Rating: 0 out of 5 stars0 ratingsElixir Cookbook Rating: 0 out of 5 stars0 ratingsPhoenix in Action Rating: 0 out of 5 stars0 ratingsInstant MinGW Starter Rating: 0 out of 5 stars0 ratingsErlang and OTP in Action Rating: 0 out of 5 stars0 ratingsNode.js in Practice Rating: 0 out of 5 stars0 ratingsClojure in Action Rating: 0 out of 5 stars0 ratingsGetting MEAN with Mongo, Express, Angular, and Node Rating: 5 out of 5 stars5/5Clojure for Java Developers Rating: 0 out of 5 stars0 ratingsGo in Practice Rating: 5 out of 5 stars5/5Introduction to JVM Languages Rating: 0 out of 5 stars0 ratingsLearning Concurrent Programming in Scala Rating: 0 out of 5 stars0 ratingsGit in Practice Rating: 4 out of 5 stars4/5Full Stack Python Security: Cryptography, TLS, and attack resistance Rating: 0 out of 5 stars0 ratingsGo Cookbook Rating: 5 out of 5 stars5/5Classic Computer Science Problems in Java Rating: 0 out of 5 stars0 ratingsEvent Processing in Action Rating: 0 out of 5 stars0 ratingsWebAssembly in Action: With examples using C++ and Emscripten Rating: 0 out of 5 stars0 ratingsPractical Rust Projects: Building Game, Physical Computing, and Machine Learning Applications Rating: 3 out of 5 stars3/5Functional Programming in Scala Rating: 4 out of 5 stars4/5Elixir in Action Rating: 0 out of 5 stars0 ratings
Programming For You
Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5SQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Learn PowerShell in a Month of Lunches, Fourth Edition: Covers Windows, Linux, and macOS Rating: 0 out of 5 stars0 ratingsPython QuickStart Guide: The Simplified Beginner's Guide to Python Programming Using Hands-On Projects and Real-World Applications Rating: 0 out of 5 stars0 ratingsGrokking Algorithms: An illustrated guide for programmers and other curious people Rating: 4 out of 5 stars4/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5Hacking: Ultimate Beginner's Guide for Computer Hacking in 2018 and Beyond: Hacking in 2018, #1 Rating: 4 out of 5 stars4/5Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5HTML & CSS: Learn the Fundaments in 7 Days Rating: 4 out of 5 stars4/5Mastering Windows PowerShell Scripting Rating: 4 out of 5 stars4/5PYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5SQL: For Beginners: Your Guide To Easily Learn SQL Programming in 7 Days Rating: 5 out of 5 stars5/5Python Machine Learning By Example Rating: 4 out of 5 stars4/5The Absolute Beginner's Guide to Binary, Hex, Bits, and Bytes! How to Master Your Computer's Love Language Rating: 5 out of 5 stars5/5Python: For Beginners A Crash Course Guide To Learn Python in 1 Week Rating: 4 out of 5 stars4/5Programming Arduino: Getting Started with Sketches Rating: 4 out of 5 stars4/5Modern C++ for Absolute Beginners: A Friendly Introduction to C++ Programming Language and C++11 to C++20 Standards Rating: 0 out of 5 stars0 ratingsLinux Command Line and Shell Scripting Bible Rating: 3 out of 5 stars3/5Photoshop For Beginners: Learn Adobe Photoshop cs5 Basics With Tutorials Rating: 0 out of 5 stars0 ratingsSQL All-in-One For Dummies Rating: 3 out of 5 stars3/5Python Essentials Rating: 5 out of 5 stars5/5
Reviews for Learning Elixir
0 ratings0 reviews
Book preview
Learning Elixir - Ballou Kenny
Table of Contents
Learning Elixir
Credits
About the Author
About the Reviewers
www.PacktPub.com
Support files, eBooks, discount offers, and more
Why subscribe?
Free access for Packt account holders
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
1. Introducing Elixir – Thinking Functionally
Why functional?
Installing Elixir
GNU/Linux
Apple Mac OS X
Windows
Manual installation – binary
Manual installation – source
Hello, World!
Using the IO.puts/2 function
Using the inspect/2 function
Exercises
Summary
2. Elixir Basics – Foundational Steps toward Functional Programming
Everything is an expression
A short introduction to types
Numerical types
Memory usage
Binary, hexadecimal, and octal numbers
Atoms
Atom memory usage
Booleans
Strings
(Linked) Lists
A little more about strings
Ranges
Tuples
Tuples or lists
Binaries
Even more about Strings
Some more built-in types
Functions
Process IDs
Invariable variables and pattern matching
Using the underscore
More pattern matching
IEEE-754
Elixir structure
Elixir files
Exercises
Summary
3. Modules and Functions – Creating Functional Building Blocks
Modules
Anonymous functions
Pattern matching
Named functions
Private functions
Calling functions
When to use .
Grabbing functions
When patterns aren't enough for matching
Functional algorithms for everyday problems
Iteration versus recursion
Performance considerations
Reverse
Sorting
Mix – the ladle of Elixir
Structure of Elixir projects
mix.exs
.gitignore
config
README.md
lib
test
Compiling a project
Testing a project
Running interactively
Files
Mix and beyond
Building functional projects
Flatten
A small introduction to testing
More to do about modules
Testing with comments
Exercises
Summary
4. Collections and Stream Processing
Keywords, maps, and dictionaries
Keywords
Maps
Dictionaries
More pattern matching
Modifying dictionaries
Performance considerations
Structures and Hash dicts
Yet another dictionary type
Flow-based programming
Stream processing and Elixir
Processing with the Enum module
Processing with the Stream module
Greedy versus lazy
Stream examples
Koolaid
Graphs
A small introduction to graphs
Node ancestors
Exercises
Summary
5. Control Flow – Occasionally You Need to Branch
Branching with Elixir
if and unless
The new else if
Elixir case expressions
Examples using branching
FizzBuzz
Mergesort
Writing tests
Implementing the sort
Exception handling
Raising exceptions
Error, exit, and throw
Handling exceptions
The try-rescue blocks
The try-catch blocks
Using exceptions
Opening files
Exceptions recap
Determinism
References
Exercises
Summary
6. Concurrent Programming – Using Processes to Conquer Concurrency
Parallel computation and concurrent computation
Erlang processes and OS processes
Parallel map
Basics of Elixir process
Self
Sending messages
Receiving messages
Spawn
Process links
Spawning with links
Process monitor
Storing state inside processes
Naming processes
Process module
Applications
Ping pong
Work pool
Summary
7. OTP – A Poor Name for a Rich Framework
Applications
Gen(eric) behaviours
Gen(eric) servers
Asynchronous messaging
Gen(eric) events
Special OTP processes
Variable scope in the Gen* processes
Back-pressure and load shedding
Supervisors
Fail fast(er)
Designing with supervisors
Assumptions of the OTP process initialization
Exercises
Summary
8. Distributed Elixir – Taking Concurrency to the Next Node
Obligatory discussion about distributed computing
Fallacies of distributed computing
The network is reliable
There is no latency
Bandwidth is infinite
The network is secure
Topology doesn't change
There is only one administrator
Transport cost is zero
The network is homogeneous
Fighting dragons blindfolded, equipped with a butter knife
CAP – choose two, and one will be partition tolerance
Why you must choose partition tolerance
Relaxing definitions
Another short discussion about networks
Topologies
Distributed computing with Elixir
OTP nodes
Node names
Connecting nodes
Cookies and node security
Node ping pong
Group leader
Globally registered names
Summary
9. Metaprogramming – Doing More with Less
Behaviours and protocols
Behaviours
Defining behaviours
A short introduction to typespecs
Using – implementing – behaviours
Protocols
Built-in protocols
Abstract syntax trees
Our first macros
Context and macro hygiene
Unhygienic macros – overriding context
Macro examples
Debugging and tracing
Static data to functions
Testing macros
Domain-specific languages
Creating a DSL
State of the macro
With great power...
Exercises
Summary
Going forward
Index
Learning Elixir
Learning Elixir
Copyright © 2015 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: December 2015
Production reference: 1211215
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham B3 2PB, UK.
ISBN 978-1-78588-174-9
www.packtpub.com
Credits
Author
Kenny Ballou
Reviewers
Ahmed El-Sharkasy
Paulo A. Pereira
Commissioning Editor
Kartikey Pandey
Acquisition Editor
Vinay Argekar
Content Development Editor
Anish Dhurat
Technical Editor
Rahul C. Shah
Copy Editor
Swati Priya
Project Coordinator
Bijal Patel
Proofreader
Safis Editing
Indexer
Hemangini Bari
Graphics
Disha Haria
Production Coordinator
Nilesh Mohite
Cover Work
Nilesh Mohite
About the Author
Kenny Ballou is a life-long learner, developer, mathematician, and overall thinker. He enjoys solving problems, learning about technologies, and discussing new and different ideas.
He graduated from the Boise State University, majoring in applied mathematics, and minoring in computer science. He has been programming professionally for nearly a decade, and is currently working as a software developer for an analytics company in the Boise, Idaho area.
Apart from developing professionally, he is active in the open source community, contributing where he can.
When he is not developing, he enjoys reading, learning, and shredding the local mountains.
You can read more from him on his blog at https://kennyballou.com, check out his code on GitHub at https://github.com/kennyballou/, and follow him on Twitter at @kennyballou.
I stand on the shoulders of those before me. I could not be where I am today without the many that have contributed to my success. Thank you.
I would like to specifically thank Sam Schrader for teaching me to teach myself, Dan Feldhusen, and Dillon Woods for affording me the opportunities to learn more, my parents for encouraging me to always strive for more than even I myself think is achievable, and my closest friends for supporting me through to the end.
I would also like to thank my reviewers and Packt Publishing for the guidance and assistance to shape and improve this book. I'm certain this book would not have been of the great quality it is now without their help.
About the Reviewers
Ahmed El-Sharkasy is a senior software engineer at Onfido (https://onfido.com/). Over the course of his life, he joined different start-ups. He worked as a team leader at Byteis (http://web.byteis.com/), lead developer at Bkam (https://eg.bkam.com), and software engineer at eSpace (http://espace.com.eg/) and Shaqa (https://www.shaqa.com/). He loves building products that can improve people's lives, and is specifically interested in the knowledge and education sectors. He is the cofounder and CEO of Fretsi (https://fretsi.com/), having a mission to deliver knowledge to humanity for free and rewarding people based on their knowledge levels. He has also published a research paper named TRUPI: Twitter Recommendation based on Users' Personal Interests.
Paulo A. Pereira is a senior software engineer. He fell in love with Elixir, and has a passion for exploring new technologies and keeping himself up to date with the industry's developments.
He previously worked as a consultant and lead developer for Mediadigital, implementing Grails and Rails solutions. He is currently working at Onfido Background Checks, a London-based tech start-up that is proving to be a key player in the background checking industry.
www.PacktPub.com
Support files, eBooks, discount offers, and more
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www2.packtpub.com/books/subscription/packtlib
Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can search, access, and read Packt's entire library of books.
Why subscribe?
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Free access for Packt account holders
If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view 9 entirely free books. Simply use your login credentials for immediate access.
Preface
This is an introduction to Elixir, a relatively new programming language. We will go through the basics of the language and teach functional programming and other paradigms as we progress. We will study the basics of concurrent and distributed programming through the lens of Elixir and OTP. We will also examine one of the more exciting features of Elixir: metaprogramming, or writing code that writes code.
This book doesn't teach the basics or programming in your first language, but it does teach the basics of Elixir under the assumption that this is a new language.
This book will also discuss a fair amount of Erlang, the predecessor language Elixir derives from, and the runtime Elixir compiles to, which is prevalent to the understanding of Elixir.
What this book covers
Chapter 1, Introducing Elixir – Thinking Functionally, introduces Elixir and functional programming, and provides some of the history and justification of Elixir. It also walks you through installing Elixir.
Chapter 2, Elixir Basics – Foundational Steps toward Functional Programming, introduces the basics of Elixir and its types, syntax, and semantics. This chapter lets you start reading and writing Elixir code.
Chapter 3, Modules and Functions – Creating Functional Building Blocks, lets us extend and expand on the previous chapter by introducing the basics of Elixir code organization into modules and functions. It makes us start our lengthy discussion on pattern matching, one of the coolest features of Elixir.
Chapter 4, Collections and Stream Processing, lets us examine collections and explains how to solve common problems using recursive algorithms. This chapter also lets us introduce Elixir's pipe operator and the basis of collection processing.
Chapter 5, Control Flow – Occasionally You Need to Branch, discusses how to do more traditional code branching, conditional statements using Elixir.
Chapter 6, Concurrent Programming – Using Processes to Conquer Concurrency, explains how to write concurrent code using Elixir. It introduces Elixir processes and the basics of message passing.
Chapter 7, OTP – A Poor Name for a Rich Framework, continues the discussion of concurrent programming with Elixir, more specifically in the context of OTP, which is the framework introduced in Erlang for building robust distributed applications.
Chapter 8, Distributed Elixir – Taking Concurrency to the Next Node, examines how to write Elixir that executes on multiple nodes, distributing the processing over possibly many computers.
Chapter 9, Metaprogramming – Doing More with Less, introduces Elixir behaviours, protocols, typespecs, and macros. Using Elixir macros, we examine how we can accomplish more with less code.
What you need for this book
This book was written against the 1.0.4 version of Elixir, but the code should be compatible with the latest version of Elixir, 1.1.1 (as of this writing).
There are, otherwise, no special requirements, even for the distributed chapter. All the code can be executed on a single computer with Elixir installed.
Who this book is for
This book targets the developers who are new to Elixir as well as Erlang to make them feel comfortable in functional programming with Elixir, thereby enabling them to develop more scalable and fault-tolerant applications.
Although no knowledge of Elixir is assumed, some programming experience with the mainstream object-oriented programming languages, such as Ruby, Python, Java, and C#, would be beneficial.
Conventions
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: If you want an integer type back, you can use the div and rem functions.
A block of code is set as follows:
defmodule MyMap do
def map([], _) do
[]
end
def map([h|t], f) do
[f.(h) | map(t, f)]
end
end
square = fn x -> x * x end
MyMap.map(Enum.to_list(1..5), square)
Any command-line input or output is written as follows:
iex(1)> IO.puts(Hello, World!
) Hello, World! :ok iex(2)>
New terms and important words are shown in bold. Words that you see on the screen, for example, in menus or dialog boxes, appear in the text like this: This is the basis of what functional languages call pattern matching and is really one of the fundamental things that makes functional programming so different and so exciting.
Note
Warnings or important notes appear in a box like this.
Tip
Tips and tricks appear like this.
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of.
To send us general feedback, simply e-mail <feedback@packtpub.com>, and mention the book's title in the subject of your message.
If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code
You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title.
To view the previously submitted errata, go to https://www.packtpub.com/books/content/support and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.
Please contact us at <copyright@packtpub.com> with a link to the suspected pirated material.
We appreciate your help in protecting our authors and our ability to bring you valuable content.
Questions
If you have a problem with any aspect of this book, you can contact us at <questions@packtpub.com>, and we will do our best to address the problem.
Chapter 1. Introducing Elixir – Thinking Functionally
Let's embark on a journey, let's leave behind the world we know and head to something new and different. We quest to learn a new programming language, Elixir, and new paradigm of programming, functional. We set out leaving behind most of what we know, and attempt to think differently.
Elixir is a functional, dynamic language built on top of Erlang and the Erlang VM (BEAM). Erlang is a language that was originally written in 1986 by Ericsson to help solve telephony problems, including distribution, fault-tolerance, and concurrency, among others. Elixir, written by José Valim, extends Erlang and provides a friendlier syntax into the Erlang VM while maintaining interoperability with Erlang and Elixir without imposing performance costs.
Elixir's roots in Erlang provide some really indispensable functionality for developing distributed and fault-tolerant applications. Developing in Elixir, we can have all that and then some.
That is, Elixir provides and exposes to us the means and tools to create applications that can truly run with nine nines of reliability. Those are a fail-fast by default design of the runtime with the concept of process supervision, which enables strong fault-tolerance, the inherent concurrency of message passing, and a functional language that also enables distribution. We will discuss all of these topics and concepts by the conclusion of this book.
But before we get into these excellent features of Elixir and Erlang, let's take a dive into functional programming and why it's useful in creating a system that has these features.
I assume you're familiar with imperative languages such as Perl and Java. Furthermore, you're likely familiar with the concept of static typing and dynamic typing, as in Python. But what is functional programming? Moreover, why should we care about it?
Why functional?
Functional programming is a paradigm of programming, a means of structuring and reasoning about code. It is, in essence, about composing functions that transform data. That is, when writing functionally, we write simple functions that transform data in a particular manner. Then we later write some other functions that use our previous functions as building blocks for more complicated transformations. This may not sound all too foreign.
In the object-oriented world, programming is about maintaining state in some controlled fashion. We create object hierarchies to define the world and we operate on some methods of those objects to manipulate the world around us. That is, we compose objects to model and, if we're lucky, we solve problems.
These are both methods of and for abstraction. We write simple components and compose. When a simple component is defined, we can forget its details and begin thinking about bigger components that result from the combination of those smaller ones.
However, there are several problems that creep up on us in the object-oriented and imperative worlds. They are subtle and they rarely, if ever, show themselves directly. These are the problems that are hard to find, hard to debug, and hard to fix. Although, we can see their symptoms.
We notice the symptoms when we attempt to conceptualize or interpret our own code using an ideal or imaginary interpreter. We notice the symptoms when we attempt to test large components. We notice the symptoms when we attempt to split execution paths. Something, somewhere, inevitably fails.
Objects and imperative code are usually, relatively easy to understand on paper. So why is this understanding only on the surface and so easily shattered when we dig further?
Imperative code is certainly testable. We can certainly get to correct solutions. But why is it so difficult to write good, testable code? Why are the correct answers so hidden from view?
Clearly imperative code is composable; yet, why is it often difficult to compose objects and existing functions? What is hindering our ability to do this well?
We can also write concurrent, imperative code. Why, then, is it seemingly so daunting and nearly impossible to get correct?
The lurking monster hiding behind our questions is usually the one thing that makes programming actually useful: side-effects or state. Functions in the imperative world usually encapsulate implicit changes to variables, objects, files, and, in other words, changes to state. These changes usually cost nothing to program and may, in fact, be pinnacle to the function they originate from. How useful would printing text to the console be if you were unable to write a stream of bytes to the character device, that is, your terminal?
It is these hidden, out-of-mind side-effects that can make programming so dangerous to understanding, correctness, and composability, not to mention, concurrency. To overcome this, we can't forget the side-effects