Side Effects

Summarized using AI

Functional programming for rubyists

Bianca Gibson • February 10, 2016 • Earth

The video titled "Functional Programming for Rubyists" presented by Bianca Gibson at RubyConf AU 2016 delves into how functional programming can address common issues in Ruby applications, particularly those related to mutable state and side effects. The talk provides insights into the core principles of functional programming and its application in Ruby, promoting clearer, maintainable, and testable code.

Key points covered in the presentation include:
- Immutability: Highlighting the importance of non-mutative programming, where instead of changing values, new ones are created. This eliminates confusion regarding value and reference passing.
- Managing Side Effects: Discussing how to handle interactions with the external world (like printing or network calls) by keeping side effects separate from core logic, making the code more testable and understandable.
- Referential Transparency: Describing how functions that always return the same output for the same input simplify code reasoning and avoid unpredictable behaviors.
- Common Pitfalls: Addressing challenges in teaching functional programming, emphasizing the importance of connecting theoretical concepts, like monads, to practical examples that developers encounter.
- Examples: Illustrating a shopping cart calculation with both mutable and immutable approaches, demonstrating the clarity added by immutability through recursive solutions and higher-order functions.

The talk also provides practical advice on how to introduce functional programming techniques in existing projects, not just new initiatives. Additionally, resources for further learning are shared, including the book "Refactoring Ruby with Monads". The overarching message emphasizes that functional programming doesn’t eliminate side effects but rather manages them for clearer intent and more predictable outcomes.

In conclusion, Bianca Gibson encourages developers to explore functional programming principles to foster greater code clarity and maintainability, allowing teams to work more effectively. She invites attendees to reach out with questions and expresses opportunities for joining her team at REA.

Functional programming for rubyists
Bianca Gibson • February 10, 2016 • Earth

RubyConf AU 2016: Rampant side effects. The shifting sands of mutable state beneath your feet. Mocks as far as the eye can see. Enter Functional Programming. Functional Programming helps you write clear, maintainable and testable code. This talk will cover the core principles of functional programming, how to apply them in ruby, the benefits they can offer, and how to introduce them to other developers.

RubyConf AU 2016

00:00:00.680 So you have rampant side effects all through your code, with mutable state everywhere. Enter functional programming to help you solve these problems.
00:00:02.679 I'm a developer at REA, and while there, I've worked on some functional projects in Scala as well as Ruby. I've encountered quite a few problems in our Ruby applications that can be addressed by adopting techniques we use in our functional applications.
00:00:10.160 From this talk, you should gain insight into the core principles of functional programming, parts you can apply even when you're not working in a functional language, and how to use these concepts in projects you're already working on—not just in shiny new greenfield projects. It's not as hard or complicated as it may seem, and while advanced concepts are welcome, they are not required.
00:00:39.719 We'll discuss immutability, how to manage side effects, referential transparency, and some common pitfalls people encounter when explaining these concepts. I'll also share resources where you can learn more. At its core, functional programming aims to prevent unexpected changes in your code, making it easier to reason about and understand.
00:01:12.920 We will start with immutability, which means you do not change any values; instead, you create new ones. You rely on constants, utilizing recursion and accumulators rather than loops and mutations. This way, any confusion about whether you're passing by value or by reference is eliminated.
00:01:25.479 If you've ever had the dilemma of whether to use a bang method when reversing a list, you were likely considering the implications of mutation, which can be extremely confusing. For instance, I once worked on the build of an older Java application where we added a new build task in Gradle. We filtered our dependencies to make changes and ran our contract tests which passed, but when we executed a full build, it failed because of unexpected dependency issues.
00:01:43.799 We realized, during debugging, that the 'filter' operation in Groovy actually mutates the list, resulting in the removal of all other build dependencies from that context. Our attempt to manage a shopping cart example can illustrate both a mutable and an immutable approach to calculating totals.
00:02:04.960 Consider a straightforward mutable solution where you iterate through all items in the list, adding their costs to the total. In contrast, a recursive immutable solution is more verbose and explicit, involving a base case where recursion stops and a recursive case where the function calls itself with a new argument each time.
00:02:56.240 In this example, we take a list and separate it into a head and tail using the splat operator, commonly used in recursive functions. Our base case returns the cost of the item when the tail is empty, while the recursive case accumulates the costs of the rest of the list.
00:03:29.039 Although this method is more verbose than its mutable counterpart, we can streamline our approach using higher-order functions, which take other functions as arguments. Using the inject method, we can apply an accumulator that starts at zero and adds each item's cost as we traverse the list. This approach replicates the functionality of the previous method but in a cleaner manner.
00:05:02.360 Moving onto side effects: these occur whenever our code interacts with the external world, such as printing to the console or making network calls. In functional programming, we strive to make these side effects explicit and separate them from the core logic. This means our core functions can operate smoothly, while the outer edges handle side effects.
00:06:00.400 For example, to add a feature to print the total from our shopping cart example, a straightforward approach might involve directly printing in the main function, which mixes logic with side effects. A functional solution, however, would separate these concerns, leaving the core logic intact while adding an outer function that handles the printing of results. This separation not only clarifies our intentions but also makes testing significantly easier by allowing us to test the pure function without the complications of side effects.
00:08:03.680 When combining immutability and lack of side effects, we achieve referential transparency, meaning that calling a function multiple times with the same input will always yield the same output. This property simplifies reasoning about code, allowing us to treat function outputs as values that can be substituted freely. For instance, printing the reverse of a list should yield consistent results unless we opt to mutate the list, which introduces unpredictability.
00:09:23.760 However, when mutation is involved, the same operation on the same line can yield different results, leading to confusion in larger systems where tracking the state of a variable involves remembering all previous mutations.
00:10:11.760 Common pitfalls when teaching functional programming include overly formal mathematical explanations, which may alienate learners. It’s vital to connect functional concepts to real-world examples. For instance, many have used monads unknowingly; explaining their practical use without initially labeling them can foster understanding.
00:10:49.800 With functional programming's academic reputation, emphasizing practical applications can combat misconceptions. Although one might think functional programming prohibits side effects, it merely isolates them for clarity.
00:11:14.360 While I couldn't find extensive resources for functional programming in Ruby, there are useful online courses and a book recommendation: "Refactoring Ruby with Monads." Additional resources include functional training in Scala.
00:11:59.120 As we wrap up, feel free to reach out to me via email or chat if you have questions. We are also hiring at REA, so if you're interested, please get in touch. Overall, functional programming is about avoiding changes behind your back, aiming to deliver clearer, more maintainable code that produces predictable outcomes.
Explore all talks recorded at RubyConf AU 2016
+15