Talks

Functional Programming in Plain Terms

Functional Programming in Plain Terms

by Eric Weinstein

In the video "Functional Programming in Plain Terms" presented by Eric Weinstein at RailsConf 2022, the speaker demystifies complex concepts of functional programming (FP) using Ruby and Rails as a reference point. The talk aims to simplify the jargon associated with FP, making it accessible to software developers who may feel intimidated by the terminology. The speaker outlines the agenda, which focuses on context, intuition, and the vocabulary of FP, covering subjects such as pure functions, algebraic data types, functors, monoids, and monads.

Key points discussed include:
- Pure Functions: Functions without side effects, meaning their output is entirely dependent on their inputs. This concept aids in reasoning about programs and reduces unexpected behaviors.
- Algebraic Data Types (ADTs): These are types constructed from other types, allowing more expressive type systems, useful for modeling complex data structures and managing states.
- Functors: These are abstractions allowing functions to be applied to values contained within a context (e.g., lists). Functors support a map operation, facilitating transformations.
- Monoids: These are types that define an associative binary operation and an identity element, providing a basis for accumulation. An example provided is reducing a list to sum its elements.
- Monads: Described humorously as "smart pipes", which manage side effects in a fluent manner while preserving the composability of functions. The speaker describes their use in organizing code that requires context management without compromising the pure functional paradigm.

Throughout the video, Weinstein emphasizes the usefulness of these concepts in Ruby, arguing that while Ruby is not a purely functional language, it can certainly borrow and utilize these FP principles effectively. He encourages developers to learn more about good type systems and how they empower safer and more intuitive coding practices. The talk concludes with a recommendation to explore functional programming further, pointing to resources like Haskell and Elm to gain a deeper understanding of these concepts.

00:00:00.900 Welcome to my talk. I hope the audio is working well.
00:00:15.120 This is Functional Programming in Plain Terms. I tried to think of a joke title for this talk, but I realized that might defeat the purpose. Then I saw Aaron's closing keynote and thought about calling it something like FPPT. However, I ended up saying FFTP, so I'm sticking with the theme of simplicity.
00:00:35.160 Before we start, I tend to speak really fast, especially when I'm excited, which is certainly the case because I get to talk to all of you about topics like monads that are inherently exciting. This is my first opportunity to speak in person at RailsConf in three years. I'm also quite nervous since it's my first talk in that time. If I start speeding up or if you feel I’m going too fast, please feel free to wave or create a commotion to get my attention so I can slow down.
00:00:51.300 Thank you all so much for being here. I know you have many other places you could be, and I genuinely appreciate your decision to spend your time with me. A big thank you also goes to our amazing sponsors, the RailsConf organizers, and the city of Portland.
00:01:31.439 A bit about myself: I work at a company called HashiCorp. Some of you may be familiar with HashiCorp, and I won’t go into too much detail, but my role is on the Terraform Cloud side with a new team called Infrastructure Lifecycle Management (ILM). I like to pretend that ILM stands for Industrial Light and Magic, but it truly is focused on managing the lifecycle of terraformed objects.
00:01:53.820 We have some exciting developments coming up, which will be announced at HashiConf EU. We are also hiring, so if you’re interested, please feel free to reach out to me. You can find my GitHub and Twitter as Eric Q Weinstein; I jokingly say the 'Q' stands for 'queue', but it actually stands for Quinn.
00:02:26.640 There’s this book, Ruby Wizardry, that I wrote about seven and a half years ago. Typically, there’s a discount code I might provide, but this time I didn’t, as I don’t want to urge you to buy a book that’s somewhat out of date. I plan to discuss a possible update with my publisher, potentially for Ruby 3.1.
00:02:33.960 If any of this is interesting to you or if you want to discuss the book or grab a copy, please come see me after the talk. This event is not a long talk, but I thought it might help to provide an agenda.
00:02:44.760 Today, we’ll discuss context and develop intuition while peeling away the forbidding language surrounding functional programming. I’ll explain what it is and how it works, along with the real vocabulary so you can actually Google terms, focusing on concepts like pure functions, algebraic data types, functors, monoids, and monads. We'll also connect these concepts with some Ruby examples.
00:03:04.019 This talk is meant to be refreshing or perhaps an antidote to previous frustrations. If you felt close to grasping these concepts but found them elusive, this could be what you need. I’ll also provide motivation for why concepts like pure functions are valuable, aiming to develop your intuition and give you translations from functional programming to Ruby to facilitate conversations with functional programmers.
00:05:01.979 Ultimately, my goal is to show how these concepts can be applied to Ruby and Rails without suggesting you must transition to languages like Pascal, Elixir, or Clojure. You can borrow these ideas and participate in those communities; all these concepts are available to you in Ruby, which I find really exciting.
00:06:30.900 The essence of functional programming is not to be arcane. Functional programmers are not inherently smarter; they merely use a different set of abstractions and ways of thinking. I strongly encourage you to focus on understanding the purpose of these abstractions. What does it do for you? Asking 'What is this for?' yields better answers than asking 'What does this do?'
00:07:49.060 Before we dive into the technical details, let’s talk about Haskell—everything there revolves around pure functions where everything is either an input to or output from a function. One way to think about this is to imagine an imaginary C programmer at your elbow while coding in Ruby, questioning how you're not managing memory yourself.
00:08:38.720 Let’s talk about pure functions. Pure functions are functions that can be memoized, meaning you can replace the function call across your program with the value it returns without changing the program’s behavior. For instance, I/O activities, state mutations, and external calls cannot be memoized because they exhibit side effects.
00:09:12.780 This isn’t to say that side effects are inherently bad; they are indeed critical because without them, your program wouldn't perform any actions. You must utilize pure functions to streamline reasoning about your programs, allowing for predictable changes and yielding properties like idempotence, ensuring repeated executions yield consistent outcomes.
00:10:12.760 Now let’s delve into Algebraic Data Types (ADTs). In Haskell, types are minimalistic, which can be confusing. Let's look at the type signature of an 'add' function: it takes two integers and returns an integer. Notably, in Haskell, all functions are curried by default. This signature shows the input arguments followed by the return type.
00:11:12.600 In this definition, we have a function called 'add' that takes two parameters, x and y, and returns their sum. Understanding how to read type signatures can be invaluable; even in Ruby, considering types can lead to better design choices.
00:12:01.140 To further explain ADTs, we can look at a function called 'head' in Haskell, which retrieves the first element of a list. If the list is empty, it would normally throw an error. Haskell requires you to handle this case, distinguishing between 'nothing' (no value) and an actual value.
00:13:05.700 Both the 'Maybe' type and an algebraic data structure give shape to these definitions; an ADT is a type made from other types, which can help catch mistakes in a more meaningful way than just using strings to identify types.
00:14:00.300 Monoids, which are accumulators and a generalization of accumulation, will follow a similar theme: how to build shared structures without reinventing the wheel. In Ruby, you can use the reduce method to sum numeric arrays or concatenate strings. By modeling our state and operations properly, we can efficiently manage accumulation.
00:14:45.480 Now let’s move to the pièce de résistance: monads. Think of them as smart pipes or function composers with a bit of extra magic. If we take a look at the pipeline analogy using Unix commands, where everything is an input or an output from a process, it becomes clearer how monads function.
00:15:49.860 When you need to compose functions while managing side effects, monads can step in to help. For instance, consider logging dynamically during execution without breaking the functional paradigm. This abstraction allows you to work with functionally pure code while still capturing essential side information.
00:17:48.780 The writer monad helps with logging, allowing us to easily log values during execution without flattening out our call stack. We’ll explore how to implement such algorithms in both Haskell and Ruby, keeping in mind that functional programming need not be burdensome but rather an enjoyable challenge instead.
00:19:00.050 So far, we’ve explored how pure functions and immutability lead to safe composition, and how we can leverage functors, monoids, and monads to structure our code effectively. A good type system, like ones in Haskell or Elm, provides the opportunity to think in more abstract analogies and makes exploring complex functions much simpler.
00:19:55.380 In conclusion, I encourage you to venture deeper into functional programming. It's filled with useful abstractions that can enhance the way you write code in Ruby while also providing an alternative way to think about data and operations.
00:20:27.020 Thank you everyone for your time during this talk. I hope it has inspired you to delve into functional programming and take some of these concepts back to your projects. I look forward to your questions!