2023 X was a better Twitter (for me)
I wouldn't have expected to say this, but X (Twitter) worked well for me in 2023. I got good things out of it. In the previous years, I had a tormentedrelationship with the platform, so, what happened? First, Mastodon happened. Elon Musk's acquisition of Twitter provoked a stampede of the most politically radicalized folks to Mastodon....
When everyone has a say
I don't think creative processes benefit from democracy — quite the opposite. After presenting the new Turbo 8 stuff in Rails World, some people opined that Rails needed to improve collaboration in the frontend space. I got a variant of this question in a couple of podcasts, which also happened when we released Active Record Encryption...
Demo of how page refreshes with morphing work
This article was originally published in the 37signals dev blog. We published a demo showing how Page Refreshes with morphing work in Turbo 8. Comparing code helps a lot in software discussions, so I thought it would be valuable to show how the new feature compares to Turbo stream actions for performing partial updates and broadcasts. ...
The radiating programmer
This article was originally published in the 37signals dev blog. You are an individual contributor at heart. You like writing code and solving technical problems. You dislike meetings and ceremony. Here’s what you can do to maximize what you like and minimize what you don’t: radiate information. The daily standup meetings that Scrum po...
Towards smoother page updates in Turbo
I recently published two articles in the 37signals dev blog related to how we will improve page updates in Turbo 8. • A happier happy path in Turbo with morphing. What we will do. • Exploring server-side diffing in Turbo. An investigation of an alternative approach to fulfill the same vision. I hope you like them!
Navigating personal information with care
This article was originally published in the 37signals dev blog. Accessing personal information from customers is a serious matter. With the launch of HEY in 2020, we developed some technology and processes to support a very simple principle: employees shouldn’t have access — intentionally or unintentionally — to personal information f...
Minding the small stuff in pull request reviews
This article was originally published in the 37signals dev blog. Nitpicking in pull requests reviews means offering insight that looks excessive, pedantic, and unimportant. It’s a pejorative term. I don’t question there are cases where the term applies, but many folks assimilate it to paying attention to the small stuff. By projecting ...
Difficult and complex
There is complex and there is difficult, they are not the same. Being able to run a marathon is very difficult. But what you have to do to prepare is simple. A small sheet of paper is enough to describe the steps. You will need tremendous effort and discipline - so it’s hard - but it is simple. Software development is different: it is ...
Globals, callbacks and other sacrileges
This article was originally published in the 37signals dev blog. Sacrificing purity for convenience is one of the Rails pillars. This principle informs several Rails features that some recommend avoiding but that we happily use in our apps. In this post, I’ll discuss how we use three of those in Basecamp. I’ll show some examples involv...
Let people be
• Have side-projects / don’t have them. • Do open source / don’t do it. • Have tech-related hobbies / have completely unrelated ones. • Have children / don’t have them. • Work long hours / never put in an extra hour. • Small and risky / large and secure. • Work for others / work for yourself. • Work out of passion / work to pay the bil...
Social media evilness (II)
Back in the day, I wrote some notes on the puzzling question of why so many people act so maliciously toward others on social media. A book introduced me to the concept of moral outrage, which brought some answers for my questions. A recent tweet by Dr. Jonathan Shedler referred an article that suggests a pretty different angle: the pr...
Remote struggles
I've worked fully remotely for the last ten years. I find the discussion about remote work fascinating. Is remote better or a lesser evil? Is a decision full of tradeoffs? Something that works in some circumstances, but that is not a good default? As with every complex subject, people – me included – love to reduce it to a dichotomy. A...
Erase and rewind
Imagine a problem you can't understand without solving it first. The first time I saw software development described as a wicked problem was in Code Complete by Steve McConnell, and I haven't seen anything but a constant validation of this proposition throughout my career. And it's a paradoxical one with several counterintuitive coroll...
Energy
Internal energy is tricky. On the one hand, energy is more reliable than happiness. I liked this reflection by Jocko Willink in the Huberman podacast. Everyone experiences joy and sadness as part of their daily lives: keeping a certain energy level is more feasible than a certain level of happiness. On the other hand, as with anything ...
Pending tests
I recently started working on a new thing at 37signals. We have a blank slate in front of us, and nothing is set in stone, which means we are moving fast. I find myself creating meaty pull requests every day. This is how every single pull request I open ends: This is just a reflection of how, most of the time, I write tests at the end....
Sensations
I’m fascinated by the sensations that the things we use induce in us. Not their usefulness, suitability, ergonomics, or aesthetics, but sensations. I don’t have a better term to capture something as substantial as difficult to describe, but I can illustrate with some very personal sensation-driven opinions: • Zelda Breath of the Wild’s...
Writing is thinking
You don’t need an audience to put writing work for yourself: • Writing can let you access things you know but can’t access deliberately. This is a powerful and utterly counter-intuitive insight. • When it comes to modeling software, compared to plain English, every other notation usage is marginal in practice. • Writing down assorted i...
The best presenter ever
I learned about Benjamin Zander in 2011. I was reading Resonate by Nancy Duarte, and she used his Ted Talk from 2008 as a case study in one of the chapters, to illustrate several concepts on how to deliver presentations. Nancy Duarte knows one thing or two about presenting, so her description of him as a "master communicator" caught my...
The augmented programmer
If you are a programmer and have tried ChatGPT, you have probably realized it’s a landscape-changing technology. The history of programming is a history of raising the abstraction level, and with all the cautions and disclaimers you want, the jump that ChatGTP represents is monumental. Right after college, I got a research grant to exp...
Learning with ChatGPT
I’m learning Python these days. The reason is that there are two domains I want to explore and play with — finance and artificial intelligence — and everything I want to use is built in Python. Being Ruby my go-to language, a recurring problem I’ve suffered for years is building my own infrastructure for most things I wanted to do in t...
2022
Some assorted reflections on my 2022: • I wrote a lot, more than ever. This was my favorite piece. This was my biggest hit. And I’m proud of this series, into which I put quite a bit of effort. I had many interesting conversations with people with shared interests, which I enjoyed a lot. I intend to continue writing for myself in 2023....
Stuck
I have referenced this article by Kent Beck in my last twopieces. Here goes the last one. When discussing whether coupling was good or bad, Beck says: “This is where I got stuck for a long time (years).” I can’t think of a more influential author than Kent Beck. His contributions have defined what modern software development is. This s...
Code I like (V): Active Record, nice and blended
This article was originally published in the 37signals dev blog. Persisting objects in relational databases is an intricate problem. Two decades ago, it looked like the ultimate orthogonal problem to solve: abstract persistence out so that programmers don’t have to care about it. Many years later, we can affirm that… it’s not that simp...
Compared to what?
This article was originally published in the 37signals dev blog. I loved this article by Kent Beck on cohesion. At some point, when discussing how cohesion and coupling are opposing forces, it says: “Wait!? Isn’t coupling bad? But cohesion is good? But cohesion is coupling of subelements? Isn’t that bad? And good? This is where I got s...
My curse with plain code editors
I think the first IDE I used was Borland Delphi in 1999. I remember being marveled by its code insight features, where the editor would suggest what properties and methods were available for a given symbol. I remember being puzzled about the programming sorcery powering that — pretty much the same feeling I have today when I play a mod...
What defamation looks like
Last Sunday a friend shared with me this Twitter thread by Kasper Timm Hansen: He confirmed later in the thread he was referring to me as the author of the Vanilla Rails article I recently published in the 37signals dev blog. Kasper starts by presenting a story of friction during PR reviews between him and me, where he was careful with...
Code I like (IV): Vanilla Rails is Plenty
This article was originally in the new 37signals dev blog. I recommend you to read it there, it looks much better! I have often heard this: vanilla Rails can only get you so far. At some point, apps become unmaintainable, and you need a different approach that brings the missing pieces, because Rails encourages a poor separation of con...
Online discussions, the good parts
Some recent positive experiences made me think about the source of my distaste for online discussions. The blame is on me: I assimilated online to social media or online comments in the wild. I can’t imagine a worse discussion platform than Twitter. Any meaningful discussion requires nuance, which Twitter eliminates by design. Making p...
Code I like (III): Good concerns
Rails concerns have received much criticism over the years. Are they the solution to all the problems or something to avoid at all costs? I think a problem with concerns is that you can use them however you want, so no surprise you can shoot yourself in the foot when doing it. After all, concerns are just Ruby mixins with some syntax s...
Aging programmer
Back in college, they told me that I would start my career writing code, but eventually, I would move to a position where I would ask others to code my designs. To celebrate that this turned out to be completely false, here are some assorted reflections as a 40-year-old programmer that looks back: • Compared to my younger versions, I f...
Code I like (II): Fractal journeys
Fractal is about similar patterns recurring at progressively smaller scales. To me, good code is a fractal: you observe the same qualities repeated at different levels of abstraction. This is not surprising. Good code is the one that is easy to understand, and the best mechanism we have to deal with complexity is building abstractions....
Utility-first CSS
Recently I've found myself with the need to use a CSS toolkit a couple of times. The motivation was building from scratch some internal admin tools. I had heard great things about Tailwind, and David had bootstrapped a Rails integration for it, so we decided to go with it for building a new version of our internal Basecamp admin panel....
Code I like (I): Domain-driven boldness
One of the first things I did when I started working at 37signals almost three years ago was cloning the git repo for Basecamp. I poked around and ended up at this method: module Person::Tombstonable ... def decease case when deceasable? erect_tombstone remove_administratorships remove_accesses_later self when deceased? nil else raise ...
What do we want people to feel?
Since I started using HEY World last year, I have written 28 posts. Those are more than what I wrote in my six previous years of blogging. Publishing an article in HEY World is as easy as sending an email, which I am sure is a life-changing feature for many people, but not for me. I am a programmer nerd, and publishing on my personal s...
Enterprisey expectations
As a customer, I can't think of something I value more than how a company handles the problems I have with them. I have recently been evaluating Datadog for Basecamp. It's a fantastic product, and we are in the final testing stage. We recently tried the new version of its official Ruby/Rails gem, finding a severe memory leak problem. I...
Priceless adversity
It's hard to appreciate the good without having experienced the bad. My first job made me professionally very unhappy. It lasted a few years, and it deeply impacted me. I swear there hasn't been a week since I quit, almost ten years ago, where I didn't reflect on my good luck compared to my starting point. Don't get me wrong: if I coul...
Performance in context
When it comes to analyzing code performance, context matters a lot. For example, say we have this code that adds two numbers: a = 1 + 2 And now we need to add a subtraction: a = 1 + 2 a = a - 3 So what's the cost of this change? We can benchmark: require "benchmark/ips" Benchmark.ips do |x| x.report("only add") { a = 1 + 2 } x.report("...
Rails attributes: an essential API you can probably ignore
A few years ago, Rails 5 introduced an API for declaring Active Record attributes. It lets you define typed attributes at the model level, to formally capture the list of attributes a model has and control how to cast values assigned to them. Active Record internally uses this API profusely. When using an Active Record model, it automa...
Ceremony
Ceremony at work is those self-imposed rituals people follow to get things done. Too much, and it becomes a burden. Too little, and it's chaos. Ceremony serves two purposes: assessment and communication. Assessment is about making sure you are working on the right problems at any given moment; communication is about getting everyone on...
What did you work on today?
Everyone at Basecamp answers this question at least twice per week: "what did you work on today?". We use Basecamp check-ins, of course. It's a simple practice with profound implications and something I would recommend to any company working remotely. These answers are in written form, and anyone in the company can see them and make co...
Writing for yourself
This question applies to most people, and it certainly applies to me: does it make sense to write without an audience? It does. One of my favorite books is Pragmatic thinking and learning by Andy Hunt. It's a book about how our brains work, which is a subject I find fascinating. A core concept it develops is how our brains operate in t...
Not a designer
I love design (as in product design). It's a discipline I have tried to educate myself at, and it's what I appreciate the most in any product I use. And yet, I'm terrible at it. I have empirical evidence that it's not my thing. But I can't help having strong opinions on how things should be designed. A contradiction, you see, HELP! I g...
Critical code path changes with scientist
I recently worked on improving the inbound email analysis system in HEY. This system analyzes every email that hits HEY to decide whether it should flag it as spam, bounce it, or warn the user about specific problems such as having a forged sender or containing a virus. In its current form, the system was making it difficult to add som...
Changing critical code paths with scientist
Social media evilness
Why are so many people so awful towards other people on Twitter? How can there be this massive gap between how people conduct themselves on Twitter and in real life? I've always found fascinating how our brains work, and I was sure there would be good answers out there. I've read a few books and articles on social media issues lately, ...
No silver buckets
The suggestion that mixing buckets is the root of all your software quality problems is common in our industry. In Rails, it's a recurring theme from his critics. Augment Ruby core classes with monkey-patching? Wrong! Those buckets are meant to remain separate. Invoke models logic from controllers? Wrong again! Those actions deserve th...
Balance
Balance is hard. We love extremes: they are simple and effective. Take learning and the Shu-Ha-Ri model. When learning something new, you first look for strict recipes: sharp boundaries that guide you through every step. At some point, you forget about recipes and start acting without thinking much. Those initial boundaries become fuzz...
My MacOS essentials
Just because the world is short of lists of favorite apps, here is mine: Task Paper for todos I used to have a thing for todo apps. I have tried them all and even tried to build my own. I switched to Task Paper years ago and have stuck to it since then. The truth is that my relationship with todos has changed significantly over the yea...
Of bugs and giants
In October of last year, we started to receive reports about chats that stopped working in Basecamp. They were all iOS/Safari users. Campfires wouldn’t work, as if there was no internet connection, and the only solution was completely restarting Safari. The bug was elusive and happened very intermittently. We tried several things witho...
Silence
I quit Twitter for the first time nine years ago. Two years ago, when I started at Basecamp, I felt like giving it a new try. Long story short: it didn’t work. I had identified noise as my biggest problem with Twitter back in the day. The signal was very low. I naively thought I could improve that by carefully selecting who to follow a...
A system to encrypt data in bulk for Rails
We just released mass_encryption, a library to encrypt large sets of data using Active Record Encryption. If you have been following along, Rails 7 was recently released and, among many goodies, it supports at-work encryption with Active Record. This new gem answers a problem many apps will face: perform the initial encryption in exist...
Don't block yourself: a remote-worker super-power
When working remotely, this is a great habit: make decisions and communicate them, but try to avoid getting blocked waiting on others. Imagine this typical example: you are not sure about how to do something. Your first idea might be to jump into a chat and ask someone for help. I won’t say I never ever do this, but it’s not a great ap...
MacBook Pro M1
Two weeks ago, I got a MacBook Pro 16-inch. I got the base model (M1 pro, 16GB). My previous machine was a loaded-up MBP 15-inch from 2019. Bottom line: it's been the most noticeable performance jump I've experienced since SSD disks. Performance The improvement is abismal. My previous MBP felt slow, and it often struggled to dispatch m...
Couple of weeks with a MacBook Pro M1
Two weeks ago, I got a MacBook Pro 16-inch. I got the base model (M1 pro, 16GB). My previous machine was a loaded-up MBP 15-inch from 2019. Bottom line: it's been the most noticeable performance jump I've ever experienced with an upgrade since SSD disks. Performance The improvement is ridiculous. My previous MBP felt slow, and it often...
Career advice
A software engineering student asked me via Linkedin about career advice. Not sure I would take advice from myself because I made many mistakes, but here are a few things I wish someone had told me right after college: • Technical stuff is a fantastic career path, really. If someone tells you that true engineers don’t code, or that you...
Timeboxing away
Deadlines in software have bad press, for a reason. Say “we need to release this version at this date”, and you are stressing everyone out. Now, say “we need a version of this at this date”, and you are actually helping to ship. I learned about this idea of fixed deadlines and negotiable scopes from Basecamp many years ago, way before ...
Privacy-aware Rails consoles with console1984 and audits1984
We just released console1984 and audits1984. The first gem extends Rails consoles to make them auditable and to protect sensitive accesses. The second one is a simple auditing tool. This constitutes the other essential part of the technology we developed at Basecamp to raise the privacy bar in Rails applications, and I am thrilled to f...
Making Rails run just a few tests faster
Some time ago, I learned that Rails parallel testing had a significant overhead due to database setup and fixture loading. Essentially, each process will set up its own database and load all the fixtures, and this is not free for non trivial datasets. Fixtures are a factor here. At Basecamp, we use fixtures heavily and, when running si...
A story of Rails encryption
This story starts in October of 2019. I was in the Basecamp meetup in Chicago two weeks after joining the company. During an internal presentation, David talked about the need to raise the bar when it came to privacy for the new product the company was working on, codenamed Haystack, now HEY. We all were busy with all kinds of projects...
Complexity-inducing narratives
I recently gave a talk on software complexity, Single Page Applications and Hotwire (slides). Due to time constraints, I ended up cutting off a whole section on narratives that are often Trojan horses for unjustified complexity and decided to write it down instead. These narratives are: • It doesn’t scale • Tech giant uses it • In the ...
Farewell Evernote
I've been using Evernote since September of 2010. I started as a passionate user, and it quickly became an indispensable part of my workflow. Then, the product started to go south, slowly but steadily. The clients became more complex, heavier, and uglier. They added a ton of features nobody asked for. And they didn't improve the one th...
A Basecamp email: before and after
As a longtime fan of Basecamp copy, I always enjoy asking for help with user-facing texts I need. This time we had to send an email to some users that were impacted by a bug. I went to Jim Mackenzie. Here's the before and after. Before: “Hi <name>, We recently discovered a bug in HEY where it could fail to move emails to the designated...
Extracting, not inventing
Documenting the pull request to add encryption to Active Record brought me memories about the origin of each feature: • Support for unencrypted data: HEY was already used by staff and some beta users when we added encryption. • Option to downcase: emails are not case-sensitive. • Option to ignore case: labels are case-insensitive when ...
Smelling Rails smells
Shopify recently published Upgrow: A sustainable architecture for Ruby on Rails. It describes a set of architectural principles to build Rails applications and announces a companion future gem. I was surprised by seeing Shopify endorse this approach. The proposed patterns aren't new. Many people have advocated for them since Rails is R...
Subscribe and get the latest posts in your email
Daily digest, no spam, unsubscribe any time
Or simply get the latest posts RSS.
https://world.hey.com/jorge
Posts: 64
New post: Monthly
Search using free-text and press