Software Development

What I Learned to Love About Ruby When I Switched to Python

What I Learned to Love About Ruby When I Switched to Python

by Lauren Ellsworth

In her talk titled "What I Learned to Love About Ruby When I Switched to Python," Lauren Ellsworth discusses her transition from working exclusively with Ruby to a focus on Python at Flatiron Health, an oncology data company. She highlights both the challenges and joys of adapting to Python, drawing several parallels between Ruby and Python.

Key Points:

- The Principle of Least Surprise: She appreciates Ruby's intuitive design, where commands behave as expected, contrasting this with Python, where commands can be less straightforward, such as requiring parentheses for exit commands.

- Whitespace Sensitivity: Lauren notes the frustrations she encountered with Python's reliance on whitespace for code structure, stating that even a single space can lead to errors.

- Version Management: She discusses the contrasting version management practices between Ruby and Python, especially emphasizing Ruby's regular upgrades versus Python's prolonged life cycles for versions, particularly Python 2 and 3.

- Package Management: Ellsworth praises Ruby for its version managers like RVM, which help manage dependencies transparently, as opposed to the limitations found in Python's pip packages and version control.

- Defaults and Their Consequences: Through examples using Rails and Django, she illustrates how defaults in Ruby provide clear guidance for new developers, while Django may present initial obstacles through security requirements and less informative console outputs.

- Cultural Philosophies: The talk touches upon the cultural underpinnings of both languages, where Ruby embraces flexibility and joy in coding, in contrast to Python's emphasis on structure and guidelines.

- Personal Reflection: Despite her newfound appreciation for Python, Lauren expresses her affection for Ruby, indicating that both languages serve specific needs effectively.

In conclusion, Lauren Ellsworth's presentation underscores the nuanced differences between Ruby and Python, particularly in terms of usability, version management, and the developer experience. She advocates for recognizing Ruby's strengths while also acknowledging the value that Python brings to data-intensive work. The talk encourages developers to appreciate each language's unique offerings while maintaining a fondness for Ruby.

00:00:17 Hello, this thing works. We're good.
00:00:22 So, hi! This is what I learned to love about Ruby when I switched to Python.
00:00:28 I tried it out on some Ruby coworkers, and I did not massively offend anyone.
00:00:34 So I feel that it's safe.
00:00:42 This is a little bit about me: I'm a senior software engineer at Flatiron Health.
00:00:54 Flatiron Health is an oncology data company; we use cancer data to accelerate research and improve patient outcomes.
00:01:01 I occasionally write things at thefourthparty.com and also at Flatiron Engineering.
00:01:06 Prior to coming to Flatiron Health, I worked exclusively with Ruby stacks, and Python was my first foray into a Python company.
00:01:14 I tried to find some photos to paint the picture for you; I found a photo of a happy hour, a photo of puppy day, and a photo of my current coworker and I with a Yeti.
00:01:22 I learned that I don't take photos of my office, so we'll jump right into the languages.
00:01:29 How many people here have worked with multiple stacks in your day jobs professionally? A ton of people? Awesome!
00:01:35 And how many of you have tried to learn a second language that wasn't your native language—like a spoken language? Also, a bunch of people? Awesome!
00:01:42 I know that coding languages and spoken languages are obviously different, but I'd like to draw a comparison here.
00:01:50 I'll start by talking a little bit about language in general.
00:01:59 This is a quote from a researcher at the University of California, San Diego, Lara Boroditsky.
00:02:06 The premise is that language contains a way of perceiving, categorizing, and making meaning in the world.
00:02:12 Languages give us a habit of thought; they provide a framework to understand our world.
00:02:20 There was a theory about 70 years ago that a language could limit the way we understood our world.
00:02:28 If I never learned the word 'happy', could I never experience happiness?
00:02:34 That theory has been widely debunked by common sense and research.
00:02:41 This new philosophy posits that language doesn't limit the way you think or your capacity, but rather gives you habits.
00:02:50 These tendencies shape how you interact with your world.
00:02:57 So, there are four topics I'd like to discuss in this context: the principle of least surprise, version management, defaults, and their consequences—all within the Ruby context.
00:03:03 First, I learned to love and dearly miss the principle of least surprise.
00:03:12 Let's talk about what this is.
00:03:17 David Hansson has a great excerpt on this from the Rails Doctrine.
00:03:27 The basic premise is that Ruby should behave the way you expect it to.
00:03:36 There's a big caveat, however: if you are brand new to coding, nothing behaves the way you expect it to.
00:03:44 But if you have some degree of experience and you're in an interactive Ruby console, when you type 'exit', it exits.
00:03:52 And if you type 'quit', it quits.
00:03:59 If you are in a Python console and you type 'exit', it says, 'Did you mean exit()?' or 'Control+D to exit'.
00:04:06 I find this extremely surprising! Obviously, it knows what I'm going for.
00:04:11 Yet, I am not allowed to exit the program without knowing the exact syntax.
00:04:18 Every time I write out the parentheses and try this again, I get the same confusing result.
00:04:26 The caveat here, as Matt himself acknowledges, is that the principle of least surprise is based on familiarity.
00:04:35 As you gain experience with a language, you find that there are fewer surprises, and it feels like the program is designed to do what you expect it to.
00:04:42 I think this is really lovely.
00:04:49 This experience sharply contrasts with my Python scripts and Python consoles, which often fail due to whitespace errors.
00:04:56 Fifteen spaces or sixteen spaces can create a crisis that crashes the whole script.
00:05:01 This issue arises especially during web development; as I code a web app, I accidentally misplace a space.
00:05:11 When I flip back to my browser and refresh, my page is dead.
00:05:17 This wasn't a trivial change; it came with a lot of work.
00:05:25 Matt quoted DHH, who stated, 'To smile at and flatter its human co-conspirator.'
00:05:32 I like the idea of a language working together with me.
00:05:40 I appreciate a language responding to my needs and complimenting my effort.
00:05:47 Here's an example: in Ruby, when we have an array, we can use the collect method to multiply it by two.
00:05:54 Using collect with an exclamation point affects the original object.
00:06:00 The method without the exclamation point does not, which I find really intuitive.
00:06:08 While I struggle to remember most documentation, this distinction is important.
00:06:17 Another strength of Ruby is the use of synonyms.
00:06:22 Python is famously known for having one way to do things; synonyms are anathema to the Python philosophy.
00:06:30 Ruby has many synonyms; for example, 'collect' and 'map' are interchangeable.
00:06:37 The word that comes to you first is the one you should use.
00:06:44 Companies often have style guides recommending one synonym over another based on personal preference.
00:06:51 But with Ruby, you have the freedom to choose what you like.
00:06:57 This flexibility is evident in the documentation for methods like 'find' and 'detect', which are found in the same code block.
00:07:04 Searching online revealed lovely gems that I enjoy, but not much about Ruby synonyms.
00:07:10 There's one more thing to note about Ruby's usability.
00:07:16 The question mark in a method name indicates a yes or no, true or false.
00:07:23 This can make my code less surprising for those who read it in the future.
00:07:29 Ruby allows me to imply significance in my code, enhancing clarity for future developers.
00:07:38 That's the principle of least surprise.
00:07:43 Now lets talk about version management, which I learned to appreciate a lot.
00:07:49 Let’s look at a timeline of Ruby and Python over the last few years.
00:07:56 Ruby 2.0.0 was released in February 2013, while Ruby 2.2.0 came out in December 2014.
00:08:06 In April of this year, Ruby entered security maintenance mode.
00:08:16 A version of Ruby has three modes: normal mode with full support, security mode with security patches, and end of life where it will no longer be patched.
00:08:26 2.2.0 remains in normal mode for two and a half years, followed by one year of security mode, ending in about three and a half years.
00:08:34 Now, let’s take a look at Python.
00:08:41 I triple-checked these dates because I was shocked that Python 3 predated the last major release of Python 2.7.
00:08:52 Python 3 was released in December 2008, while Python 2.7 was released in July 2010.
00:09:02 Python 2.7 will reach end of life in April 2020—that's a ten-year cycle from start to finish.
00:09:09 Transitioning from Python 2 to 3 is a breaking change; organizations must refactor their code.
00:09:15 When Python 3 was introduced, complications arose; all packages and libraries split between the two versions.
00:09:24 When faced with this split, developers had to choose a side.
00:09:32 Flatiron Health was founded after the release of Python 3.0, so we have two and a half years before transitioning becomes necessary.
00:09:40 I think this is impactful on the cadence of development in a community.
00:09:46 I've worked with roughly half a dozen Ruby stacks and have never seen one that wasn’t upgraded at some point.
00:09:55 Conversely, I’ve never worked with a Python stack that I’ve seen upgraded.
00:10:03 This stark difference impacts the community significantly.
00:10:10 How will we get new features? How will we obtain speed improvements?
00:10:17 These challenges have downstream effects on everyone using the language.
00:10:25 I miss saying, 'Hey, there's a new version out with some really cool stuff!'
00:10:34 In this space of version management, I want to discuss packages.
00:10:42 Some of you may be familiar with Ruby Version Manager, or RVM.
00:10:49 How many of you are RVM users?
00:10:56 Great, and how many of you are RBN users?
00:11:02 That's a fairly big split.
00:11:08 I've witnessed some heated discussions about which one should prevail.
00:11:15 Polarizing or not, these tools are fantastic compared to common practices in the Python community.
00:11:23 What's great about RVM and RBM is that they bundle Ruby with gems.
00:11:29 Practicing this talk, I realized I've never said 'pythons' before.
00:11:38 However, with Ruby, I can switch environments effectively.
00:11:43 I have the tools needed to navigate through the language's development.
00:11:50 In contrast, there isn't widespread adoption of multiple Python versions.
00:11:57 This limitation raises concerns about switching from Python 2.7 to 2.11 or worse, transitioning from 2.x to 3.x.
00:12:06 Two tools relatively common in the Python community are Anaconda and Python Virtualenv.
00:12:13 Anaconda is primarily targeted at data scientists and bundles Python with numerous packages.
00:12:21 Out of the box, Anaconda contains over a hundred packages.
00:12:30 If I want to develop a lightweight web application, it isn't the best fit.
00:12:37 Though Anaconda offers the bundling that RVM and RBM provide, it can feel cumbersome.
00:12:44 On the other hand, Virtualenv can bundle my packages but doesn't merge Python with it.
00:12:51 So switching from one Python version to another can be difficulty.
00:12:58 Some kind soul has ported RVM for Python, but it's not commonly used.
00:13:02 You can see how RVM is utilized for managing multiple Ruby versions on a single machine.
00:13:10 This can be helpful for using Anaconda as well.
00:13:16 I can have both Python 2.7 and Python 3.6 on the same machine and switch as needed.
00:13:23 However, if it is not commonly adopted, it will not improve the cadence for the community.
00:13:30 Lastly, let's talk about gems.
00:13:36 This is a sample of a gem file from installing a Rails gem.
00:13:43 When I install Rails, I get a gem file that includes several gems with version numbers.
00:13:50 If I run 'bundle install', I get a 'Gemfile.lock' that outlines all versions.
00:13:56 This transparency in Ruby is beautiful; I know every version and my constraints.
00:14:02 In contrast, my Python alternative lacks that level of clarity.
00:14:10 For example, a Django tutorial does not create a requirements.txt file upon running.
00:14:17 When I run 'pip freeze', I only see top-level versions, lacking insight into dependencies.
00:14:26 Especially with the potential complications of Python 2 and 3, there can be significant trouble.
00:14:35 That covers version management—lots of Rubies and their dependencies living side by side.
00:14:43 Next, let's discuss defaults and their consequences.
00:14:49 My argument, or rather someone else's, is that defaults make a difference.
00:14:56 This is illustrated in the last line of a paper called 'Do Defaults Save Lives?' by Goldstein.
00:15:04 The paper is about organ donation.
00:15:12 You’ll see a huge difference between opt-in and opt-out systems for organ donations.
00:15:20 The left shows opt-in rates while the blue depicts opt-out rates.
00:15:28 One reason for the disparity may stem from institutional barriers to opting out.
00:15:35 The difference caused by mere checkboxes indicates presumed versus explicit consent.
00:15:42 This highlights how defaults impact behavior.
00:15:50 Let’s discuss our frameworks by looking at Rails and Django.
00:15:58 When new developers start with Rails, they find the Rails guides accessible.
00:16:04 Following its tutorial allows the creation of a web server with around fourteen commands.
00:16:11 Those commands include setting up controllers, generating models, and running migrations.
00:16:18 As a result, the application launches smoothly.
00:16:26 In summary, Rails provides developers robust defaults for settings.
00:16:34 These defaults guide how developers interact with the database, ensuring clarity in terms of expected outcomes.
00:16:40 In contrast, in Django, the first message you often receive is a security error.
00:16:46 You'll need to adjust allowed hosts to avoid access issues.
00:16:54 Furthermore, the Django tutorial introduces creating a super user up front.
00:17:01 This focus on administrative tasks contrasts sharply with Rails.
00:17:09 Django’s console output is far less verbose than Rails.
00:17:17 For instance, while Rails provides details about database interactions, Django does not.
00:17:24 This difference leaves new developers unaware of crucial context.
00:17:31 In the Django configurations, the first several lines focus heavily on security.
00:17:38 Despite that, a note states: 'These settings are unsuitable for production.'
00:17:45 There’s a debate on where the emphasis lies for new engineers.
00:17:53 Rails highlights database timing, while Django underscores security.
00:17:59 Ultimately, this leads to different learning paths.
00:18:06 The level of detail in Rails shines a light on what's essential in web development.
00:18:14 Conversely, developers often face hurdles in understanding the Django console.
00:18:20 The irony in this, given Ruby and Rails’ reputation as so-called 'magic languages,' is notable.
00:18:27 It's ironic that while many assume Ruby is magical, Django has hidden complexities.
00:18:35 Transparency in logging matters, and I miss that in Python.
00:18:42 Every policy has a 'no-action' default—a fact that we must remain aware of.
00:18:49 Defaults have an implicit direction based on how we perceive them.
00:18:56 I miss the sensitivity built into Rails, which I didn't appreciate until now.
00:19:02 That sums up the topic of defaults and their consequences.
00:19:09 Now, let's delve into the philosophy of Ruby.
00:19:15 I learned to appreciate it more as I transitioned.
00:19:22 Language, after all, provides a lens into cultural dispositions and priorities.
00:19:30 It's interesting to observe how we converse about Ruby and Python.
00:19:37 Our language founders each have unique, recognizable personas.
00:19:44 Yukihiro Matsumoto, known affectionately as Mats, embodies a friendly, nice approach.
00:19:52 In contrast, Guido van Rossum is often referred to as the 'benevolent dictator for life' of Python.
00:20:00 The difference in rhetoric reflects differing cultural underpinnings.
00:20:07 Ruby promotes a sense of goodness and collaboration.
00:20:14 In Python, however, the emphasis is on adherence to structure and guidelines.
00:20:22 We often talk about the 'joy of Ruby' and the 'Zen of Python.'
00:20:31 The joy of Ruby highlights developer ergonomics and playful rhetoric.
00:20:38 In contrast, the Zen of Python emphasizes consistency and clarity.
00:20:45 Years ago, I presented to Python developers.
00:20:51 They raised the concern that Ruby is harder to collaborate on--too many ways to approach tasks.
00:20:59 Despite the concerns, I believe that flexibility in approach has its strengths.
00:21:08 How we talk about these languages and their concepts matters.
00:21:15 Ultimately, it impacts how we collaborate and use the tools.
00:21:22 Liz Bailey mentioned 'Why the Lucky Stiff’s Poignant Guide to Ruby,' which I applaud.
00:21:28 Published in 2005, the guide resonates with an aura of fun and playfulness.
00:21:34 It welcomes everyone to learn Ruby with joy and enthusiasm.
00:21:41 For Python too, there's simplicity for newcomers.
00:21:49 One example is the anti-gravity module that returns random XKCD comics.
00:21:55 Python author Randall Munroe is a significant fan, making it accessible.
00:22:03 With that said, let's reflect on where we are.
00:22:09 Python is notably a multi-master language.
00:22:15 In comparison, Ruby is often paired with Rails, tightly coupling those tools.
00:22:22 Hence, you'll find discussions conflating elements of Ruby and Rails, complicating comparisons.
00:22:29 Python boasts major niches: systems administration, web development, and data processing.
00:22:35 This versatility is admirable.
00:22:43 The transition from Python 2 to Python 3 presented significant challenges across communities.
00:22:51 For Flatiron Health, Python serves us incredibly well in handling massive amounts of data.
00:22:58 Our quantitative scientists and systems administrators need to work with data in an integrated manner.
00:23:05 That said, I proudly maintain my Ruby fan status.
00:23:12 I am proud to be a member of the vibrant Ruby community. Thank you for having me.