Talks

Super Ain't Super: From OOP To FP and Beyond!

wroc_love.rb 2018

00:00:31.540 I'm sorry, I'm not Aaron Patterson. I'm not good at pants, but I thought this was so funny that I had to include it in my presentation. I'm not going to start the presentation, as I usually do, with drunk photos.
00:00:42.950 Instead, I'm going to start with this beautiful backdrop that I created using [___] on Linux, not on macOS. As you can see, I'm quite talented now with fonts and design; it looks pretty cool!
00:01:02.000 I'm not going to show Aaron in underpants or anyone drunk from last night. Instead, I want to share my experience of learning how to eat Tartare in Poland. Basically, you mix two of the most dangerous things in the world: raw meat and raw egg, add some seasoning, and it turns out to be delicious! It takes an extremely talented Polish person to know just how to season it with salt and pepper, and today I had this, and it was fantastic.
00:01:26.330 I want to draw your attention again to my beautiful backdrop because I'm really proud of my work! It took me about ten minutes to get the scaling and everything right. A lot of people were laughing earlier, saying things like, 'Ha ha ha! He's coming; he doesn't have a talk title. He's probably going to talk about trails.' It's surprising that people talk about their projects when invited to conferences.
00:01:38.990 I’m not going to talk about Ruby on Rails. This slide is to remind you that I have stickers and lanyards for Trailblazers. So, if you love or hate Rails, just come and grab a sticker. I don’t mind if you burn it on camera or something!
00:02:15.530 Today is a beautiful Saturday. I’m planning to walk you through my journey from basically day one of my programming career to today, explaining how my programming style has evolved. We will also discuss some concepts like event sourcing and components, which were touched upon in earlier panels.
00:02:37.120 When people ask me when I started programming, I always say I was eight because it sounds cool. The truth is, I don't remember exactly when I started, but I do have this old photo of myself and my friends at that age. My first programming book was "Tricks of the Mac Game Programming Gurus." Back then, I thought it was pronounced "gurus" because I didn’t speak English. I wanted to program games and was using a Mac before it was cool. The book taught programming on the Mac, and I remember that I learned C++ from another book. I struggled to understand why, in functions, parameters could be named differently than the variables used when the function was called.
00:04:00.319 I talked to my dad about it, and he explained that you could think of a function as a component you invoke with arguments for processing. What happened outside the function doesn't matter—it's encapsulated. This realization was traumatic yet positive, as I saw how I could encapsulate behaviors.
00:04:53.210 This concept of functions stuck with me as I moved on to Perl, then Ruby, where I became dissatisfied with how functions and encapsulation were handled in Rails. Despite Ruby having good support for functions and methods, Rails felt monolithic, where one big thing handled everything. I started writing my first gem, Cells, to create reusable components and logic, allowing for a clearer separation of concerns.
00:05:34.460 Cells allowed for rendering components with complete isolation: you could pass dependencies and receive HTML strings back without worrying about other components' internal states. This idea struck a chord in the community; however, I hit a wall again when it came to managing forms. I wondered why model concerns had to be handled within models rather than allowing new classes to be defined specifically for forms. By creating a new class specifically to manage form data and validations, I could once again isolate concerns and simplify testing without running HTTP requests.
00:06:44.360 I realized that even though I had introduced encapsulation and objects into my code, I was still struggling with how to customize these objects effectively. Inheritance and mixins felt too low-level, as they often led to messy dependencies that complicated customization. At one point, refinements were introduced into Ruby, but they were confusing and rarely used. I concluded that maybe Ruby didn't provide the right tools out of the box to achieve the flexibility I desired.
00:08:10.310 Therefore, I started working on my own framework to simplify this problem. My goal was to make controllers great again by introducing constant operations, which simply delegated responsibilities to specific objects instead of accumulating all logic within one monolithic controller. This approach would allow for better structure and isolation.
00:09:19.860 Trailblazer's operations allowed developers to test in isolation, meaning you could run your tests without needing to deal with an entire stack. This reminded me of how we typically treat Rails development, where often, we took a monolithic approach to simplify architecture but at the cost of flexibility.
00:10:23.700 As I developed operations into the system, it became clear that something was missing. The initial versions required reporting everything from the operations being run to the steps being invoked, but it introduced complexity. I wanted a method to manage and control operations without needing to know the exact flow.
00:11:57.810 Thus, I began to shift toward functional approaches—where you define plain functions, passing in arguments to yield some output without caring about internal workings. The challenge arose with ensuring that operations remained easily understandable while allowing for flexibility.
00:13:03.220 In Trailblazer 2.0, instead of users defining their methods in a chaotic order, we provided a domain-specific language (DSL) to structure and visualize workflows, which resonated positively with users. They could now create logical flows without needing excessively intricate Ruby coding, where every operation could be treated as a self-contained step with clear inputs and outputs.
00:14:23.040 Moreover, they could compose operations and abstract them further to create reusable components, making processes much more manageable. Users started utilizing this composition feature heavily, building out flows that were both modular and flexible.
00:15:35.230 Again, I found much of my inspiration from structured workflow definitions similar to BPMN. This not only introduced clarity into complex workflows but also allowed for clear steps and progress tracking. The event sourcing model fit beautifully with this concept, and we could develop intricate systems that worked seamlessly.
00:16:49.040 The outcome of these changes was a toolset that incorporated not only functional concepts but also proper workflow management. It was fulfilling to develop these abstractions, transforming how we approached programming in the Ruby environment and addressing complaints about the language's rigidity.
00:18:55.570 I encountered resistance over various changes, especially regarding how we approach API design across major versions. Many preferred to stay within their familiar paradigms, often opposing innovation because of fear of change. Still, despite critiques, we pushed forward with ideas that resonated within the community, evolving Ruby projects into functional programming with a focus on clearer definitions and logical flow.
00:20:34.590 The last couple of years have focused on refining this philosophy into structured workflows representing real-world applications. I realized building small, effective components was essential, ensuring each part could efficiently communicate with others through defined inputs and outputs.
00:22:28.340 Throughout these developments, I’ve harnessed the power of structured workflows, which have enabled clearer paths for users. Seeing how these changes can lead to real, tangible advantages for teams solidified my enthusiasm for this direction, highlighting how programming can adapt to functionality as well as discovery.
00:25:32.440 I’m not very active on Twitter, but you can find me there. I'm 15 minutes over time now.
00:25:40.400 Before we wrap up, I want to address a question that came up about alternative tools. While I considered functional languages, I find that the Ruby community, despite its quirks, allows a level of community interaction that languages like Haskell or Elixir don't provide.
00:26:29.570 The richness of Ruby’s community means that even as we confront inherent limitations, we can adapt and innovate. Through focusing on clear functional principles, I believe we can leverage Ruby’s flexibility to create powerful solutions.
00:27:46.840 It's been amazing sharing my journey with you all, and I appreciate your engagement and questions. Let's gather more informally to discuss all this further and explore ways to innovate our projects!