How your code might get rusty,
And what you can do about this
Maëlle Salmon (rOpenSci, cynkra)
Old, really degraded abandoned boats near the sea. Picture by Jean Claude-Salmon.
Maëlle pointing at old, really degraded abandoned boats near the sea. Picture by Jean Claude-Salmon.
Nice sailboat. Picture by Jean Claude-Salmon.
Big ship at sea, looks a bit rusty on the inside. https://www.pexels.com/photo/old-cargo-ship-on-sea-20703978/
Positive affirmations
Scrabble letters spelling the word ‘lousy’ https://www.pexels.com/photo/the-word-louise-is-spelled-out-in-scrabble-letters-19835557/
No one wants to approach it. 😉
Something isn’t working anymore.
Something isn’t readable anymore.
Something doesn’t follow standards anymore.
Code that used to be ok for a different context and less complicated features.
Old phone https://www.pexels.com/photo/gray-rotary-telephone-on-brown-surface-209695/
At a small scale: patterns, code style, etc.
At a larger scale: design (classes, functions), script (and test files) organization, dependencies, docs or lack thereof, etc.
igraph, started by Gábor Csárdi
> 18 years ago.
Close Up Photography of Yellow Green Red and Brown Plastic Cones on White Lined Surface https://www.pexels.com/photo/close-up-photography-of-yellow-green-red-and-brown-plastic-cones-on-white-lined-surface-163064/
“Paying off igraph’s tech debt”
“Paying off igraph’s tech debt”
“Setting igraph for success in the next decade”
Philip Heltweg’s blog post
“Since then, I remind myself that legacy software is written by people like me. Torben had constraints I knew nothing about. He worried about deadlines long past. Torben had learned a lot since then. Development workflows had evolved, infrastructure had gotten better.”
Hadley Wickham’s toot
Periodic reminder: The only way to write good code is to write tons of shitty code first. Feeling shame about bad code stops you from getting to good code.
Marianne Bellotti’s book “Kill it with fire: Manage Aging Computer Systems (and Future Proof Modern Ones)”
Legacy technology exists only if it is successful. These old programs are perhaps less efficient than they were before, but technology that isn’t used doesn’t survive decades.
Let’s refactor a codebase!
Construction Equipment and Tools Plastic Toys https://www.pexels.com/photo/construction-equipment-and-tools-plastic-toys-4492351/
Write down your frustration in your issue tracker.
Some ideas
If no tests, add them first!
If no tests, add them first! Test inspiration:
usethis::use_github_action("test-coverage")
To get my mojo on, I find the simplest infelicity to fix, I fix it. Then I do it again.
GeePaw Hill in “Refactoring Pro-Tip: Easiest Nearest Owwie First”
A way to get going!
Increase codebase quality
Increase understanding of codebase
Opportunity to explore many scripts: fix the owwie everywhere.
Code style https://styler.r-lib.org/
Unclear, unspecific names
Use of “tmp” variables
Repeated names in tests https://masalmon.eu/2024/05/23/refactoring-tests/
Convoluted logic
lintr::lint()
lintr::lint()
Line 2 [string_boundary_linter] Use !is.na(x) & endsWith(x, string) to detect a fixed initial substring, or, if missingness is not a concern, just endsWith. Doing so is more readable and more efficient.
lintr::lint()
Line 2 [string_boundary_linter] Use !is.na(x) & endsWith(x, string) to detect a fixed initial substring, or, if missingness is not a concern, just endsWith. Doing so is more readable and more efficient.
(R 3.3.0 gem!)
🧰 Can be configured
.lintr.R
🧰 Can be run on continuous integration.
Worth it if
expect_that(x, equals(1))
to expect_equal(x, 1)
Or experiment for a bit.
Patience
Colorful puzzle pieces with scrabble tiles spelling the word ‘patience’ https://www.pexels.com/photo/colorful-puzzle-pieces-with-scrabble-tiles-9227484/
When working on a bug fix or feature…
“tech debt”-labelled issues “upkeep”-labelled issues
Refactoring pull requests / commits
Less, easier refactoring
A plastic toolbox with toy tools https://www.pexels.com/photo/plastic-carpenter-tools-in-a-toolbox-toys-4492368/
John Ousterhout’s book “A Philosophy of Software Design”
Two approaches to programming:
🐰 Tactical programming;
🐢 Strategic programming.
Word ‘dream’ on greenery https://www.pexels.com/photo/dream-text-on-green-leaves-1535907/
Training! Sharing!
Letters in felt https://www.pexels.com/photo/assorted-color-alphabet-1337385/
Add your comment here, be kind…
Pull Request reviews
👀 Tidyteam code review principles by Davis Vaughan.
👀 The Code Review Anxiety Workbook by Carol Lee and Kristen Foster-Marks.
rOpenSci software peer-review!
Easier future refactoring:
Git history
A gray room with shelves full of brown drawers https://www.pexels.com/photo/a-gray-room-with-shelves-full-of-brown-drawers-6549926/
Day 1 : script.R
Day 2 : Add statistical stuff, script2.R
…
Day 42 : Add plot, script-final-2024-06-03.R
(40th copy of the file 🤪)
Less loss of work;
Experiments in branches;
History to use (locally and on platforms like GitHub).
Julia Evans’ zines “Oh shit, Git!” and “How Git works”
Small commits with informative messages
My blog post Why you need small, informative Git commits
“Commit a bunch of files before lunch 🍝”
Showing 145 changed files with 2,624 additions and 2,209 deletions.
“fix: adapt code to tool’s 0-indexing”
Showing 2 changed files with 3 additions and 2 deletions.
Your repository’s Git history should be like your Instagram profile grid.
Another dimension to your work.
Work in branches
Pink blossoming branches https://www.pexels.com/photo/pink-blossoming-branches-20699831/
“The repeated amend”™️ : git commit --amend
“Squash and merge”: click the right GitHub/GitLab button
“Start from scratch”: git reset --soft
+ git add (--patch)
“Mix and match your commits”: git rebase -i
My post with details: Hack your way to a good Git history
Get better at Git
A laptop and a book on a beige leather sofa https://www.pexels.com/photo/a-laptop-and-a-book-on-beige-leather-sofa-6372812/
12 functions creating Git sandboxes with a small challenge to solve.
Inspired by Oh shit, Git! + my experience
Exercises to be solved however you want (command line! RStudio Git tab! GitKraken! GitHub Desktop!)
Put a change on the right branch (git cherry-pick
+ git reset
),
Rewrite history in a branch (git rebase -i
),
Split changes into several commits (git add --patch
),
…
Remove untracked, useless files (git clean
),
Find which commit introduced a bug (git bisect
),
Undo a commit (git revert
).
This was all easy
A red plastic hard hat toy and a yellow bucket on a wooden crate https://www.pexels.com/photo/a-red-plastic-hard-hat-toy-and-a-yellow-bucket-on-a-wooden-crate-4492347/
Now what if no one is there to maintain the code?
Brown bare tree on dry brown ground https://www.pexels.com/photo/photo-of-brown-bare-tree-on-brown-surface-during-daytime-60013/
Especially relevant for open-source projects.
ownership of the scope, code and community;
responsiveness to external requests;
regular housekeeping.
Blog post What Does It Mean to Maintain a Package?
pocket/wallet payment;
payment for the heart;
payment for the brain.
Yanina Bellini Saibene Three currencies of payment for our work
If the balance feels off, consider your needs. It might be time to try and recruit co-maintainers or join a community of other developers, or even to find a new maintainer or retire the package.
Blog post What Does It Mean to Maintain a Package?
Never hesitate to ask for help.
Publicity (blog, social media posts)
Technical infrastructure (R-universe) and content (dev guide, blog, Package Development Corner)
Social (Slack workspace, coworking, community call)
Succession
How to join?
Submit a package to software review “Do you expect to maintain your package for at least 2 years, or to be able to identify a new maintainer?”
Take over a package
Contribute significantly to a package
Other paths of participation
Monthly newsletter including events and Package Development Corner
help-wanted https://ropensci.org/help-wanted
publicly look for a new maintainer (team) https://ropensci.org/news
retire a package https://devguide.ropensci.org/maintenance_evolution.html#archivalguidance
Have a good codebase 😉
Foster a welcoming atmosphere for contributors. 2021 community call
Regularly assess your maintenance responsibilities. rOpenSci yearly package maintainer survey.
Be gracious with maintainers.
Provide support as relevant/possible, be it technical, social or monetary.
Conclusion
Plastic construction toys https://www.pexels.com/photo/handyman-tools-plastic-toys-4492348/
Refactors and successions are a fact of programming life as are bug fixes, but there are ways to limit damage.
Thank you and thank you to:
useR! program and organization committees.
cynkra team especially igraph project team Kirill Müller, Michael Antonov; and speaker training/practice buddies Angelica Becerra, David Granjon, Antoine Fabri, Mike Page, Christoph Sax.
rOpenSci team especially practice audience Yanina Bellini Saibene, Steffi LaZerte, Mark Padgham and abstract reviewer Jeroen Ooms.
igraph team now and then Szabolcs Horvát, Tamás Nepusz, Vincent Traag… and Gábor Csárdi! 😉
Hannah Frick, Athanasia Monika Mowinckel, Shannon Pileggi, Hugo Gruson
Old boats near sea. Picture by Jean-Claude Salmon.
Refactoring one bit at a time or in a more ambitious ways. Tests as safety nets!
Ensuring code quality through kind code reviews.
Training oneself and others.
Learn a bit more Git.
Supporting maintainers even when they need to leave, and before they leave.
Jean-Claude Salmon (title slide, second and third slides, thanks slide) ❤️
Toy construction tools by Polesie Toys on Pexels (and others by the same account)