Last week, Syed, one of my email subscribers, shared his struggles with writing online.
Here’s an edited version of Syed’s email:
I wanted to start writing about my debugging journey of the things I had been stuck with long time and then solving it finally… But I couldn’t continue as I thought my website wasn’t the best with SEO and no one may read it on my website. Then I shifted to Twitter and later, due to fewer engagements, I couldn’t continue there either. Well no I think maybe writing for some well-known forums might be the way.
For Syed and you that want to start writing as a software developer:
Don’t Create, Document
Start by sharing what you do and what you learn. That’s a good start.
Writing online is like keeping a public time capsule. If you don’t know what to add to your time capsule, follow the 20-minute rule: if something takes you more than 20 minutes to figure out, write about it.
Write about your learning and the problems you’re solving at work. Probably, the next time you’re googling something, you will find your own writing. That’s magical.
If You Want to Start Writing, Don’t Start Your Own Blog
And don’t code your own blogging engine either.
When we want to start writing, we fall back to doing what we know best — coding — and start by coding a blogging engine. That’s where writing and blogging die.
The best place to start is on “social blogs.” Platforms for long-form content with readers and a distribution mechanism. This way, you don’t have to “chase” readers with SEO tricks and you’ll have faster feedback.
If you don’t know where to start, go with dev.to or Medium. I can’t recommend dev.to enough. It’s a beginner-friendly and welcoming platform for coders.
Once you start on a social blog, keep your blog as your main hub or a portfolio of your favorite posts. That’s what I do.
We All Started With Zero Readers and Followers
At the beginning, writing can feel lonely.
I wrote my first online piece in 2018 and nobody read it. Maybe only one or two of my coworkers. I saw my blog analytics going from ~10 views per month to eventually ~1000s in a matter of years. Yes, you read that right. Years.
Focus on writing your first 10 posts and keep trying and improving.
Here’s when the Show Your Work attitude keeps us writing in the long run. And like any other infinite game, you only lose if you stop playing.
Write for yourself and for sure others people will find it useful too.
SEO Is Another Skill to Master
If you go with a social blog, the platform does the SEO part for you. You don’t have to worry about it.
Search engines keep changing their rules with algorithm updates. These days, it seems Google favors Reddit posts instead of personal blogs.
You’ll be in a dead end if you try to chase every SEO update. Write for humans because search engines like it when you do that.
Instead of trying SEO tricks, go with these rules:
Write to answer a query people might search for in a search engine.
Make your posts easy to read for humans: Don’t use big chunks of text and use subheaders.
Link back to other posts using keywords: Don’t use “click here” or “see more.”
You see? Another skill to master. Go with a social blog.
Parting Thought and Challenge
I owe my career growth to a couple of skills: apart from coding, learning English and writing online.
After blogging for more than five years, writing online has opened doors here and there. I made my first money on the internet thanks to my blog, for example.
Even if you don’t make any money writing, it will give you clear thinking.
And if you’ve made it this far, here’s my challenge: create an account on dev.to and write your first 4 posts there and see where they take you. If you accept the challenge, contact me and share your first post.
Write as if no one is reading and then keep writing because you don’t know who’s reading.
In case you don’t know Herbert Lui’s work, he’s a writer, editorial director, and book author. He wrote Creative Doing, a book with exercises and prompts for writers and creatives.
After binge-reading his blog, I learned these lessons from him.
1. Don’t Start From Scratch
Be a DJ producer of ideas instead.
Instead of trying to come up with original ideas every time, mix and build on your past and maybe forgotten ideas.
If you want to improve at something, go for quantity.
That’s the key finding of the story of the pottery class: A teacher divided his pottery class into two halves. The first half was graded on the quantity of pottery produced and the other half on the quality instead. At the end of the class, the half graded on quantity did best. Their effort was to produce something and quickly move on to the next piece, taking the feedback from past repetitions.
If you need ideas to go for quantity, do a 100-day challenge: finish something every day for 100 days. Herbert wrote for 100 days and shared his lessons.
Quality comes after quantity.
3. You Don’t Run Out of Ideas if You Know Where To Look
When you think you’re running out of ideas, go through your favorite blogs, YouTube channels, and your social feeds and write a reaction post for a piece you liked.
A post doesn’t have to be a 2,000-word masterpiece.
To remove the pressure of writing masterpieces every time, consider a blog like a garden of ideas instead of a finished and polished product. You can always expand a past idea on a new piece.
Most of Herbert’s posts only have a headline and one main idea. You’re free to break the rule of writing introductions and conclusions. That’s something I also noticed by reading Seth Godin’s blog. They write the main idea naturally after the headline without an introduction.
Finding Herbert’s blog inspired me to continue writing. Herbert doesn’t seem to have a “niche.” Maybe everything he writes falls under the umbrella of writing and creativity.
Don’t have a niche and go for quantity. You don’t need to write masterpieces, only to document you journey.
Running out of ideas is the greatest fear of new writers.
But don’t worry. You’re not running out of ideas. You have plenty of them. You need to be aware of the content you consume and have writing prompts to help you write.
Here are 3 tips to never run out of ideas to write:
1. Become a DJ of Ideas
There’s nothing new under the sun. And it has all been done before.
That’s relieving and reassuring. That removes the self-imposed pressure of coming up with new and original ideas.
Never start from scratch again. Develop your “new” ideas by remixing and expanding your past ideas or others’ ideas. Become a DJ producer of ideas.
If you think you’re running out of ideas, go through your posts, videos, or social feed and write a reaction post about one piece of content.
2. Follow the 20-Min Rule
If something takes you 20 minutes or more to figure out, write about it.
This is the prompt I’ve used to write some of my coding tutorials. Once I figure out how to do something after being stuck for a while, I write about it.
I wish I could credit the source of this rule. I remember learning about it from an old YouTube presentation about technical blogging that I can’t find anymore.
So if you have an aha moment, write about it. If you finally understood a hard subject, write about it.
By writing about your learning struggles, you will reinforce and document your learning.
3. Follow the 3-Strike Rule
If a subject or idea comes up at least three times around you, write about it.
I found this idea on Shawn Wang (swyx)’s blog in the context of technical blogging. But it can be easily extended outside the coding world too.
If another client asks you the same question, write about it. And if you give the same piece of advice to someone, guess what? Write about it.
With the 3-strike rule, you’re also saving your keystrokes. After 3 strikes, the next time the same subject comes up, just share a link to your writing.
Now, you’re not running out of ideas again. It’s impossible. Notice the content you’re consuming and write about it.
My first coding job was far from being like a Silicon Valley job at a startup.
I didn’t have ping-pong tables or slides to go between offices.
It was, by all means, a boring job at a local non-tech company. There’s nothing wrong with a boring job if that’s what you want. But it taught me valuable lessons about life, coding, and money. Here they are.
You Are Not Your Code
My first job was with a small team. One team member took care of one project, from start to end, wearing multiple hats.
Things got complicated when we had to work together and inherited the code from a coworker. It was messy code, to say the least. He put all actions and logic inside event handlers. Those were the days of WinForms applications: Drag and drop a button, double-click, and connect to the database right there.
We had to fix his issues and rewrite his code. Nobody wanted to do that. And I started to judge him because of his code. “What if he does everything else the same way he codes?”
Don’t judge someone by their code. Don’t take it personally either. You could miss professional connections or friendships by judging people for their code.
Assume everyone does their best with the resources they have at hand.
In the future, someone will inherit your code and say “What a crappy code. Who wrote this?”
There will always be different opinions and better ways of doing things. And even you will think of better ways to do your current work!
That's not me at my first job. Source: stablediffusionai.ai
Coding Is Not the Only Thing
In my first days, I only wanted to code.
I had just finished reading the Clean Code and wanted to refactor everything around me. I didn’t want to attend meetings, answer phone calls, or even reply to emails. I only wanted to code. That’s what I was paid for, right?
More than once, my boss called me to his office and I arrived minutes late because I was coding in my cubicle. I don’t know why I didn’t get in trouble for that.
Software engineering is about collaboration.
You won’t be locked in a basement coding. You must talk to clients, conduct meetings, agree on estimations, and ask for help.
I had to learn there’s more than just typing symbols in text files.
Live With Half of Your Salary
That’s the best life advice I’ve ever received for free.
My cubicle was next to the coffee machine, in a corner that had once been a bathroom.
One day, another coworker, a “veteran of many battles,” came over to have his coffee. And he said something like this:
“Hey Cesar, here’s a free piece of advice. Now that you can, imagine you only make half your salary and save the other half. Sooner than later, you can buy your own apartment.”
Years later, while reading money books, I found similar advice. And it reminded me of that conversation.
I’ve followed that advice, but not exactly. I’ve saved less than half of my salary.
Today, I’d rephrase it like this: “Imagine you make half of your salary, save, and invest the other half.”
You Don’t Have To Feel Miserable
I thought talent and good work were shortcuts to breaking the rules of the corporate world. I was soooo wrong! The Matrix is real!
Endless meetings, office politics, and a fixed schedule.
It all started to take its toll on me.
There were days when I felt I was leaving my life behind while sitting at a computer. I felt demotivated and disengaged. I was craving variety and change. I didn’t know there was a term for that: burnout.
Always have an exit plan.
Change jobs when you wake up and can’t get out of bed to work.
Find a way to motivate yourself: start a side project, learn a new tech stack, or discover a new way of doing your work. Or simply update your CV and LinkedIn profile and move on.
Parting Thoughts
It’s been more than 10 years since my first job. I’m only grateful for it. Somebody took a leap of faith with me and gave me a chance when I had 0 hours of flight time.
I took these lessons to my next job. And every time I can, I give the same money advice my coworker gave me: save and invest half of your salary.
Often what we value the most from past jobs is not the money, but the friendships and connections. From time to time, I meet with coworkers I met at this first job for coffee.
C# is getting more and more functional with every release.
I don’t mean functional in the sense of being practical or not. I mean C# is borrowing features from functional languages, like records from F#, while staying a multi-paradigm language.
Yes, C# will never be a fully functional language. And that’s by design.
But, it still misses one key feature from functional languages: Discriminated Unions.
Discriminated Unions Are a Closed Hierarchy of Classes
Think of discriminated unions like enums where each member could be an object of a different, but somehow related, type.
Let me show you an example where a discriminated union makes sense. At a past job, while working with a reservation management software, hotels wanted to charge a deposit before the guests arrived. They wanted to charge some nights, a fixed amount, or a percentage of room charges, right after getting the reservation or before the arrival date.
Here’s how to represent that requirement with a discriminated union:
publicrecordDeposit(ChargeCharge,DelayDelay);// Of course, I'm making this up...// This is invalid syntaxpublicunionrecordCharge// <--{NightCountNights;FixedAmountAmount;PercentagePercentage;}publicrecordNightCount(intCount);publicrecordFixedAmount(decimalAmount,CurrencyCodeCurrency);publicenumCurrencyCode{USD,Euro,MXN,COP}publicrecordPercentage(decimalAmount);publicrecordDelay(intDays,DelayTypeDelayType);publicenumDelayType{BeforeCheckin,AfterReservation}
Here, the Charge class would be a discriminated union. It could only hold one of three values: NightCount, FixedAmount, or Percentage.
You might be thinking it looks like a regular hierarchy of classes. And that’s right.
But, the missing piece is that discriminated unions are exhaustive. We don’t need a default case when using a discriminated union inside a switch. And, if we add a new member to the discriminated union, the compiler will warn us about where we should handle the new member.
Discriminated unions are helpful to express restrictions, constraints, and business rules when working with Domain Driven Design. In fact, using types to represent business rules is the main idea of the book Domain Modeling Made Functional.
For example, discriminated unions are a good alternative when moving I/O to the edges of our apps and just returning decisions from our domains.
I told you that C# is borrowing some new features from functional languages. Well, if you’re curious, this is how our example will look like in F# using real discriminated unions:
typeDeposit={Charge:Charge;Delay:Delay;}typeCharge=// <-- Look, ma! A discriminated union|NightCountofint|FixedAmountofdecimal*CurrencyCode|PercentageofdecimaltypeCurrencyCode=|USD|Euro|MXN|COPtypeDelay=|BeforeCheckinofint|AfterReservationofint
All credits to Phind, “an intelligent answer engine for developers,” for writing that F# example.
A Proposal for a Union Keyword
It seems the C# language team is considering fully supporting discriminated unions.
In the official C# GitHub repository, there’s a recent proposal for discriminated unions. The goal is to create a new type to “store one of a limited number of other types in the same place” and let C# do all the heavy work to handle variables of that new type, including checking for exhaustiveness.
The proposal suggests introducing a new union type for classes and structs. Our example using the union type will look like this:
publicunionCharge// ^^^^^{NightCount(intCount);FixedAmount(decimalAmount,CurrencyCodeCurrency);Percentage(decimalAmount);}// This is how to instantiate a union typeChargechargeOneNight=newNightCount(1);// <--varoneNightBeforeCheckin=newDeposit(chargeOneNight// ^^^^^newDelay(1,DelayType.BeforeCheckin));// This is how to use it inside a switchvaramountToCharge=chargeswitch{NightCountn=>DoSomethingHere(n),FixedAmounta=>DoSomethingElseHere(a),Percentagep=>DoSomethingDifferentHere(p)// No need to declare a default case here...}
The new union type will support pattern matching and deconstruction too.
Under the hood, the union type will get translated to a hierarchy of classes, with the base class annotated with a new [Closed] attribute. And, if the default union type doesn’t meet our needs, we can use that new attribute directly.
Two Alternatives While We Wait
The union type is still under discussion. We’ll have to wait.
In the meantime, we can emulate this behavior using third-party libraries like OneOf.
Here’s how to define our Charge type using OneOf:
publicclassCharge:OneOfBase<NightCount,FixedAmount,Percentage>// ^^^^^{publicCharge(OneOf<NightCount,FixedAmount,Percentage>input):base(input){}}// Or using OneOf Source Generation:////[GenerateOneOf] // <--//public partial class Charge : OneOfBase<NightCount, FixedAmount, Percentage>// ^^^^^//{//}publicrecordNightCount(intCount);// <-- No base class herepublicrecordFixedAmount(decimalAmount,CurrencyCodeCurrency);publicrecordPercentage(decimalAmount);// Here's how to instantiate a OneOf typevaroneNightBeforeCheckin=newDeposit(newCharge(newNightCount(1)),// ^^^^^newDelay(1,DelayType.BeforeCheckin));
OneOf brings methods like Match, Value, and AsT0/AsT1/AsT2 to work with and unwrap the underlying type.
Apart from third-party libraries to emulate discriminated unions, there’s an alternative approach abusing records: Discriminated Onions.
And here’s our Charge type using discriminated onions:
publicabstractrecordCharge// ^^^^^{privateCharge(){}// <--publicrecordNightCount(intCount):Charge;// <--publicrecordFixedAmount(decimalAmount,CurrencyCodeCurrency):Charge;publicrecordPercentage(decimalAmount):Charge;publicUMatch<U>(// ^^^^^Func<NightCount,U>onNightCount,Func<FixedAmount,U>onFixedAmount,Func<Percentage,U>onPercentage)=>thisswitch{NightCountr=>onNightCount(r),FixedAmountc=>onFixedAmount(c),Percentagep=>onPercentage(p),_=>thrownewArgumentOutOfRangeException()};}// Here's how to instantiate a discriminated onionvaroneNightBeforeCheckin=newDeposit(newCharge.NightCount(1),newDelay(1,DelayType.BeforeCheckin));
Voilà! That’s what discriminated unions are, and the official proposal to bring them to the C# language.
You see, C# is getting more functional on each release. While we wait to get it more funcy with discriminated unions, we have to go with libraries and workarounds. Let’s wait to see how it goes.