GoRuCo 2017

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

When I switched from a Ruby based company to a Python based company, things I had taken for granted in my Ruby life were suddenly sorely missed, and the transition to a language with only one way to do the same thing created quite a few bumps in the road. This talks draws parallels between Ruby and Python, spotlighting which brought the most developer happiness, what I miss and love about Ruby, and what Ruby can learn from Python.

GoRuCo 2017

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.