<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel><title>Thoughts | Hugo Ferreira</title>
    <link>https://hugo.ferreira.cc/thoughts/</link>
    <description>Recent content in Thoughts by Hugo Ferreira</description>
    <image>
      <title>Thoughts | Hugo Ferreira</title>
      <url>https://hugo.ferreira.cc/hf-bw.jpg</url>
      <link>https://hugo.ferreira.cc/thoughts/</link>
    </image>
    <generator>Hugo -- 0.124.1</generator>
    <language>en</language>
    <copyright>2000–2024 by Hugo Ferreira · CC BY 4.0</copyright>
    <lastBuildDate>Mon, 18 Dec 2023 20:45:10 +0000</lastBuildDate>
    <atom:link href="https://hugo.ferreira.cc/thoughts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>💭 Providing a sense of independence in caregiving</title>
      <link>https://hugo.ferreira.cc/caregiving/</link>
      <pubDate>Mon, 18 Dec 2023 20:45:10 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/caregiving/</guid>
      <description>Say you&amp;rsquo;re supporting and providing for someone with reduced mobility1. If you want them to maintain their sense of independence, thn focus on your response times. Make it a priority to respond to their request for help immediately (or as fast as you can).
When they have autonomy, people experience a short time from thought to action. This is crucial to give them the sense of independence:
thought ➔ action</description>
      <content:encoded><![CDATA[<p>Say you&rsquo;re supporting and providing for someone with reduced mobility<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. If you want them to maintain their sense of independence, thn focus on your response times. Make it a priority to respond to their request for help immediately (or as fast as you can).</p>
<p>When they have autonomy, people experience a short time from thought to action. This is crucial to give them the sense of independence:<br>
<strong>thought ➔ action</strong></p>
<p>Having to rely on someone else for basic stuff means that there’s now a delay on that:<br>
<strong>thought ➔ [help] ➔ action</strong></p>
<p>As a caregiver, the shorter you can make that time, the more sense of autonomy and independence you give them.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Written from the point of view of a sudden strained ankle that makes me have to hop around like a <a href="https://en.wikipedia.org/wiki/Saci_(Brazilian_folklore)">Saci</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Diversity and Inclusion: Reflections on Empathy, Hiring, and Transformation</title>
      <link>https://hugo.ferreira.cc/dei-reflections/</link>
      <pubDate>Mon, 06 Nov 2023 20:40:11 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/dei-reflections/</guid>
      <description>Thoughts about 3 aspects of promoting diversity and inclusion in the workplace: the need to understand each other, for companies to reveal themselves, and getting a seat at the table.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/dei-reflections/mural-lima-peru.jpg" length="2349672" type="image/jpeg" />
      <content:encoded><![CDATA[<p>A few days ago, I had the privilege of participating in a group discussion about diversity and inclusion in the workplace. This insightful conversation was quite enriching and eye opening. It left me with a few things to ponder.</p>
<p>Here are 3 thoughts that emerged from my reflection on the conversation:</p>
<ul>
<li>Empathy is essential, as we may not grasp each others&rsquo; experiences</li>
<li>Recruitment needs companies to reveal themselves to overcome reluctance to change jobs</li>
<li>Meaningful change requires decision-makers with diverse perspectives, by becoming one</li>
</ul>
<hr>
<h2 id="about-empathy-you-dont-know-what-you-dont-know">About empathy: &ldquo;You don&rsquo;t know what you don&rsquo;t know&rdquo;</h2>
<p>Empathy is fundamental to understand the experiences of others and overcome misunderstandings.</p>
<p>Let me illustrate this with a simple yet revealing story.</p>
<p>I have spent many years doing pair programming, where two people work together on the code implementation.</p>
<p>During a session with a female colleague, we encountered one of those tiresome captchas. The task was to &ldquo;pick the dresses&rdquo; from a list of images. My colleague selected two images, and as she was about to submit, I called out a bit too late &ldquo;wait, you missed one!&rdquo;</p>
<p>Sure enough, the captcha failed and we had to respond to a new question…</p>
<p>She rolled here eyes 🙄 and sighed with disappointment “oh, this was made by men, for sure. That one was not a dress, it was a blouse.” 🫤</p>
<p>Me calling out the “mistake” was in good faith, with intention to help a joint task. But it could be easy to perceive me as arrogant, trying to correct a minority who knows much more than me about the subject.</p>
<p>But we cannot know what we don’t know. We cannot see what we’re blind to. This scenario highlights the potential for misunderstandings and unintentional insensitivity. Had we not been working together for a long time and built a trusting relationship, I’m sure that would have been the case.</p>
<p>Only sharing our different mutual realities, with <a href="/receiving-feedback">patience and understanding</a>, can we recognise our limitations.</p>
<hr>
<h2 id="about-recruitment-better-the-devil-you-know-than-the-devil-you-dont">About recruitment: &ldquo;Better the devil you know than the devil you don&rsquo;t&rdquo;</h2>
<p>Recruiting candidates from underrepresented groups can be an uphill battle.</p>
<p>It’s very common for companies to offer “referral bonus” for bringing colleagues into the recruitment pipeline.</p>
<p>In my experience, it takes me 10 times more effort to convince a female former colleague to apply for a new job opportunity than a male one. And with much less success in getting them to do so.</p>
<p>This highlights the reluctance to change that many individuals, particularly minorities, often feel.</p>
<p>Especially for employees from underrepresented groups, the switch to a new company can be daunting. In their current company, they’ve already established themselves at great cost. They feel comfortable navigating the existing challenges, and understand where the &ldquo;dragons&rdquo; lie.</p>
<p>The idea of having to start over that struggle and the possibility of having even more pronounced challenges, can be intimidating. This fear makes the idea of staying in a familiar, albeit imperfect, environment more appealing than venturing into the unknown.</p>
<p>To overcome that, companies must reveal what it’s like to work there, for real. This involves getting representative people to share what it is like for them to work in the company. To share both the positives and the areas that need improvement. To be straightforward about the reality of the work environment they foster.</p>
<p>This way, companies can make a stronger case for why it’s worth taking a leap into the unknown. By making it less “unknown”. By making the “devil you <em>don’t</em> know” seem less intimidating.</p>
<hr>
<h2 id="about-transformation-a-seat-at-the-table">About transformation: &ldquo;A seat at the table&rdquo;</h2>
<p>Real change in diversity and inclusion requires more than well-intentioned advice. It needs decision-making power.</p>
<p>For many years I have worked as a consultant. Among other things, we would do digital transformation for clients in software development. One of my former colleagues, now serving as a director of engineering in a product company, shared a valuable insight…</p>
<p>When he was in a consultant’s role, he could only offer guidance and suggestions and lacked the authority to enforce changes. Transformation was slow and full of mishaps, especially when leadership got misaligned.</p>
<p>In contrast, as a director of engineering, he could influence the teams’ incentives and structures in a direct manner. It led to quicker and more effective transformations than when we was not as empowered.</p>
<p>This same principle applies to diversity and inclusion efforts. We need people with diverse mindsets and perspectives sitting at the decision-making table. Otherwise, attempting to drive change from the sidelines will be much more frustrating and less effective.</p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/feed/update/urn:li:share:7128074657089400832/">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/111376168405027516">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/diversity-and-inclusion-reflections-on-empathy-hiring-and-transformation-1685ff8c1196">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1722309576865829222">Twitter</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Navigating people: The antisocial guide to survive social gatherings</title>
      <link>https://hugo.ferreira.cc/antisocial/</link>
      <pubDate>Mon, 10 Jul 2023 22:16:07 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/antisocial/</guid>
      <description>Guide to being invisible in a crowded party. The subtle art of staying present and mingling with people, at the same time absent without engaging, all without raising suspicion.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/antisocial/office-party.png" length="2631025" type="image/png" />
      <content:encoded><![CDATA[<p>Parties and social gatherings with many people can be interesting… or a complete nightmare. Either for work or for family, there are times where we’re not up to it and yet, because we couldn’t get away, we must do attend.</p>
<p>Doesn’t matter what the reasons you have to lack enthusiasm on a particular social gathering. You can be a shy person. Or an introvert<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> that is needing alone time to recharge your batteries. Or even an extrovert<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> that isn’t keen on being with a particular group of people.</p>
<p>These tips can help you survive such situations…</p>
<hr>
<p>First things to remember are the following guiding principles:</p>
<ul>
<li>Look busy</li>
<li>Avoid eye contact</li>
<li>Move around</li>
<li>Everyone cares about themselves</li>
</ul>
<p><em><strong>Look busy</strong></em></p>
<p>Most encounters in social gatherings happen when someone sees you idle. People don’t like to interrupt. So don’t be idle. Read a pamphlet, scribble notes somewhere, pretend to send a text. Your phone is an excellent tool to look busy and avoid people approaching you.</p>
<p><em><strong>Avoid eye contact</strong></em></p>
<p>At all costs! For real. This is the main invitation signal for people to approach you, even if not immediately. Allowing eye contact, nodding, and other common social rituals, are an open invitation. Close those doors.</p>
<p><em><strong>Move around</strong></em></p>
<p>A moving target is hard to hit, so always be moving. Be slow, pause for a bit but don’t stay for long in the same place. If you stay put, you’re creating opportunities for other to approach and engage. It’s harder to talk to someone who is going somewhere. People don’t like to interrupt and you can always say you’ll be right back.</p>
<p><em><strong>Everyone cares about themselves</strong></em></p>
<p>Since everyone’s focused on their own experience, no one cares what you are doing.  People remember the interactions they’ve had, not the ones they didn’t. Who they talked to, not who they didn’t. This opens ample opportunities to survive a party by “walking between the raindrops”.</p>
<hr>
<p>These guiding principles apply is many ways and to many situations. Here are some examples…</p>
<p><em>— In a walking around cocktail-style event —</em></p>
<p>If you see someone approaching, don’t try to identify who it is. Curiosity killed the cat and you’ll end up creating eye contact by accident. Turn away in a slow page, as if you didn’t notice and go look for something else to do, like choosing what to eat from some tray.</p>
<p>Never join an area of the table with lots of people on it. You might end up eating the less popular food but you need to prioritise avoiding people. That’s what’s more important!</p>
<p>Going to pick up some food but someone anticipates you and gets there first? Pretend something distracted you (a painting on the wall, a flower on a vase, your shoelaces) and buy time. Approach it again only after the person has left. Nothing opens the door to conversation like deciding who gets the last croquette.</p>
<p>Always have food with you. If someone is entering the danger zone looking to chat, start eating, look away and walk out. People tend to not interrupt if your eyes are on your plate and no one expects an answer from someone chewing.</p>
<p>Another option is having a drink with you. Doesn&rsquo;t work so well (taking a sip is too fast compared to chewing a bite) but can be better than nothing.</p>
<p>Are you seeing movements for social games like “musical chairs” or, god forbid, a “conga line”? Great timing to step outside for a smoke, go look for the bathroom or answer some “urgent” messages on your phone.</p>
<p>If someone catches you on the way out and insists you join the “fun”, answer with “yes, I’ll be there right after”. Saying “no” will only make it worse. You become a challenge and will engage their evangelisation impulse. They’ll try to convince you with “it’s so much fun”, “you must join”, “it’s not the same without you”, etc.. Answering “yes, later” fulfils their desire to gather people around and buys you time. Time after which you’ll have no intention of following through, of course.</p>
<p>Don&rsquo;t stay outside too long though. If you abuse it, people will worry where you are and be more motivated to approach you asking if everything is ok.</p>
<p><em>— In a sitting down conference-style event —</em></p>
<p>Joining a restaurant where you’ll have a group meal together? Make sure to be in the middle of the pack. This way there’s already enough people seated when you join the table to let you read the room. Yet, there will still be enough seats available to let you choose the most pleasant or quiet people to sit next to. Don’t be the first ones to sit since you’ll have no control who sits next to you and it’s awkward to move away once you’re seated. Also, don’t be the last ones to sit since all the good places will be gone and you’re now stuck with the group’s leftovers.</p>
<p>Is it a place where everyone’s lined up in chairs, like in a cinema, for a talk or to watch some family holiday pictures? While everyone is setting up things, go grab a beer or sneak into the toilet. Let others occupy the seats first. When you’re back, skip the chairs and stand at the very back against the wall. You’ll be safe from happenstance conversation about what you&rsquo;re watching.</p>
<p>Does someone take a wall spot too close to you? Be discrete but be quick (as if you’ve just realised something) and go pick something else to eat or drink. Then stay around that area and don’t return to where you were on the wall. Remember, it’s more important <em>where</em> (how isolated) the place you’ve pick something from is, than what you picked up.</p>
<p>Sitting down is risky because it affects your mobility but if you want to sit, avoid clusters of empty chairs. An empty cluster might be appealing because there is no one there. But since there are so many free seats, it’s very risky. Someone outside of your control can sit right beside you and start a conversation.</p>
<p>Choose a chair at the end of a line and pull it way from the others if they are movable. Never sit in chairs in the middle of a row: too many chances to get people on either side of them.</p>
<p>If you can stomach the noise of children, and there are some around, pick a chair next to them. That keep most of the other people at bay, especially guys. If you sense someone approaching, look at what the children are doing as if you’re interested. Give a faint smile and focus on whatever they’re doing or chatting about. This will send a message of “being occupied” and people won’t want to bother you.</p>
<p><em>— At the end of the event —</em></p>
<p>Never be the first one to leave the party. You’d have to say goodbye to everyone and explain each time why you’re leaving “so early”. Plus, you’ll have to deal with all the “ooh, already?” and “why don’t you stay longer?” departure rituals.</p>
<p>Pay attention to the first people to leave, and take a “ride” with them. Let them take the blunt of the departure ceremonies. Wait for those to finish and the ones staying get tired and give up trying to convince them. Then you can nudge the hosts with a shrugging “I need to leave as well 🤷” and walkout together with the first people. Timing for this is critical but the resistance will now be minimal. You can finally take yourself out of there, into freedom.</p>
<hr>
<p>Being invisible in a crowded party is a <em>subtle art</em>. Present and mingling with people, while absent without engaging, and without raising suspicion.</p>
<p>Hope these guiding principles and tips can help you survive such places without harm.</p>
<p>Take care.</p>
<p><em>And realise this is a work of fiction, doesn’t necessarily have any parallels with reality… kinda</em> 😏</p>
<p><img loading="lazy" src="kidding-kinda.gif" alt="animated gif with a character looking surprised, the other responding with “I’m kidding” and making a serious face right after"  />

<a href="https://giphy.com/gifs/fx-on-hulu-im-kidding-POlRuKwo6HEnZsp3DQ">via GIPHY</a></p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_navigating-people-the-antisocial-guide-to-activity-7087426042864279552-VNns">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110741040672693409">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/navigating-people-the-antisocial-guide-to-survive-social-gatherings-1e6155d29c9d">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1681661969852399619?s=20">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://t.me/c/1363309933/9114">Telegram</a></li>
</ul>
</details>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>See book <a href="https://www.goodreads.com/book/show/8520610-quiet">Quiet: The Power of Introverts in a World That Can’t Stop Talking by Susan Cain | Goodreads</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>See book <a href="https://www.goodreads.com/book/show/35712351-the-science-of-introverts-and-extroverts-and-everyone-in-between">The Science of Introverts (And Extroverts and Everyone In-Between) by Peter Hollins | Goodreads</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Talking or speaking? Easily recall how to give good feedback</title>
      <link>https://hugo.ferreira.cc/giving-feedback/</link>
      <pubDate>Tue, 13 Jun 2023 21:41:24 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/giving-feedback/</guid>
      <description>There are many guidelines on how to structure feedback but human nature is quite common. A simple mnemonic will help your recall your favourite framework when it matters the most — talk about what you “observe”, its “impact” and then “ask”.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/giving-feedback/eye-hammer-question.jpeg" length="99403" type="image/jpeg" />
      <content:encoded><![CDATA[<p>Negative feedback is never easy to impart on others. Emotions and ego tend to trigger defensive behaviour. This, in turn, creates friction and noise in the communication.</p>
<p>There are several structured ways to help us shape our message for others in a way that helps people receive it well. Unfortunately, some of them are useless and even disrespectful (e.g. the <a href="https://www.forbes.com/sites/forbeshumanresourcescouncil/2022/04/25/why-the-sandwich-approach-to-criticism-is-terrible-advice/">“shit” sandwich</a>, and <a href="http://blog.idonethis.com/sandwich-feedback-performance-management/">others</a>).</p>
<p>The following frameworks are ones that I&rsquo;ve found more useful and helpful.</p>
<hr>
<h2 id="common-feedback-frameworks">Common feedback frameworks</h2>
<h3 id="nvc---nonviolent-communicationhttpsenwikipediaorgwikinonviolent_communication"><a href="https://en.wikipedia.org/wiki/Nonviolent_Communication">NVC - Nonviolent Communication</a></h3>
<p><em>by Marshall Rosenberg (<a href="https://www.cnvc.org/">CNVC</a>)</em></p>
<p>An approach to communication based on principles of nonviolence. Was developed by clinical psychologist Marshall Rosenberg beginning in the 1960s and 1970s.</p>
<p>This is a very popular approach, with lots of books, articles and training going around for it.</p>
<ul>
<li><strong>Observation</strong> — Facts we are seeing, hearing, or touching, as distinct from our evaluation of them</li>
<li><strong>Feelings</strong> — Emotions or sensations, free of thought and story</li>
<li><strong>Needs</strong> — Universal human needs, as distinct from particular strategies for meeting those needs</li>
<li><strong>Requests</strong> — Distinguished from demands in that one is open to hearing a response of &ldquo;no&rdquo; without this triggering an attempt to force the matter</li>
</ul>
<h3 id="sbii---situation-behavior-impact--intenthttpswwwcclorgarticlesleading-effectively-articlesclosing-the-gap-between-intent-vs-impact-sbii"><a href="https://www.ccl.org/articles/leading-effectively-articles/closing-the-gap-between-intent-vs-impact-sbii/">SBI+I - Situation-Behavior-Impact + Intent</a></h3>
<p><em>by Center for Creative Leadership (<a href="https://www.ccl.org/">CCL</a>)</em></p>
<p>A more niche approach written in 2022, from a nonprofit organisation focused on leadership. Their goal is improving the understanding, practice, and development of leadership.</p>
<ul>
<li><strong>Situation</strong> — Clarify and describe what happened, when and where</li>
<li><strong>Behavior</strong> — Describe the observable behaviour, without assuming what the person was thinking</li>
<li><strong>Impact</strong> — Explain what you thought or felt in reaction to the behavior</li>
<li><strong>Intent</strong> — Inquire about their original intentions, to clarify the gap between intent vs. impact</li>
</ul>
<h3 id="core---context-observation-result-next-stepshttpswwwradicalcandorcomcore-feedback"><a href="https://www.radicalcandor.com/core-feedback/">CORE - Context, Observation, Result, nExt stEps</a></h3>
<p><em>by Kim Scott (<a href="https://www.radicalcandor.com/the-book/">Radical Candor</a> book)</em></p>
<p>From the author of a best seller in the business category, published in 2017. This method makes sure you’re not criticising someone’s personality when delivering negative feedback (or even praise).</p>
<ul>
<li><strong>Context</strong> — Cite the specific situation</li>
<li><strong>Observation</strong> — Describe what was said or done</li>
<li><strong>Result</strong> — What is the most meaningful consequence to you and to them?</li>
<li><strong>nExt stEps</strong> — What are the expected next steps?</li>
</ul>
<hr>
<h2 id="a-simple-mnemonic-to-remember">A simple mnemonic to remember</h2>
<p>As you can see, there’s plenty to study and choose from. I recommend you look through the methods in more detail and see what you can relate with more. Practice it whenever you have a chance…</p>
<p>In reality though, situations that bother you and demand these tools happen in real time. Quite often, the timing to say something is in the moment and it’s hard to remember all the above rules.</p>
<p>Unless you’ve practiced enough for these concepts to become <a href="https://en.wikipedia.org/wiki/Four_stages_of_competence">unconscious competence</a> (i.e. have an intuitive level of familiarity with these tools), it can be hard to remember how to say things on the spot.</p>
<p>While still in the <a href="https://en.wikipedia.org/wiki/Four_stages_of_competence">conscious competence</a> phase, this <strong>simple mnemonic</strong> has helped me recall how to structure my feedback:</p>
<ul>
<li>👁️ … talk about what you <strong>Observe</strong></li>
<li>🔨 … talk about what was the <strong>Impact</strong></li>
<li>❓ … then <strong>Ask</strong> a question as follow up</li>
</ul>
<p>This is because there’s a natural overlap between the methods. They emphasise different parts of the conversation. The authors chose different terms for similar underlying principles. But human nature is constant.</p>
<p>Here’s how this mnemonic maps to the frameworks shown above:</p>
<!--
<table>
	<thead>
		<tr>
			<th> </th>
			<th>NVC</th>
			<th>SBI+I</th>
			<th>CORE</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td rowspan="2">👁️ <strong>Observe</strong></td>
			<td rowspan="2">Observation</td>
			<td>Situation</td>
			<td>Context</td>
		</tr>
		<tr>
			<td>Behaviour</td>
			<td>Observation</td>
		</tr>
		<tr>
			<td rowspan="2">🔨 <strong>Impact</strong></td>
			<td>Feelings</td>
			<td rowspan="2">Impact</td>
			<td rowspan="2">Result</td>
		</tr>
		<tr>
			<td>Needs</td>
		</tr>
		<tr>
			<td>❓ <strong>Ask</strong></td>
			<td>Requests</td>
			<td>Intent</td>
			<td>nExt stEps</td>
		</tr>
	</tbody>
</table>
-->
<p><img loading="lazy" src="table.png" alt="comparison table between the different feedback frameworks (NVC, SBI&#43;I, CORE) to highlight how each one maps to the “Observe”, “Impact” and “Ask” principles"  />
</p>
<hr>
<p>One more thing…</p>
<h2 id="start-stop-continue">Start, Stop, Continue</h2>
<p>Beyond the scope of “negative feedback”, we are sometimes asked to provide general feedback about other people. Could be about a new hire during their probation period. Could be preparing for a “<a href="https://medium.com/@joshproduct/speedback-de-stigmatise-feedback-with-speed-dating-principles-4708d493fb63">speedback</a>” session with team members. Could be many other scenarios.</p>
<p>What should we say? What can we talk about?</p>
<p>An easy way to identify topics to talk about is to brainstorm using the <strong>“start, stop, continue”</strong> pattern:</p>
<ul>
<li><strong>Start</strong> — Think whether there are things the person should do, which they are not currently doing</li>
<li><strong>Stop</strong> — Think if you can see anything that the person should not do anymore</li>
<li><strong>Continue</strong> — Think about if some of the person’s current behaviours they should maintain</li>
</ul>
<p>All this is, is a guide to <em>think</em> about different “things to say”:</p>
<ul>
<li>You don’t need to be exhaustive in covering the 3 aspects</li>
<li>You can have several things to say for the same aspect</li>
<li>You don’t have to follow this specific order</li>
<li>You can mix and match different aspects, as it feels more natural to you</li>
</ul>
<p>Happy feedback 🙂</p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_speaking-or-communicating-easily-recall-activity-7074358582716116992-3-A3">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110536856147168624">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1668593984455729152">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://t.me/c/1363309933/8956">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 “The Business” considered harmful</title>
      <link>https://hugo.ferreira.cc/the-business/</link>
      <pubDate>Sun, 04 Jun 2023 22:16:59 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/the-business/</guid>
      <description>Few corporate speak expressions annoy me in as much as these 2 words: 😬
“The business”
This is a pet peeve of mine, for sure. But beyond that, it’s important we stop covering decision makers behind “The Business” curtain.
There is no such entity called “The Business” in companies.
“The Business” isn&amp;rsquo;t a job function or role or group of people.
“The Business” is everyone in the company.
So what is happening in reality, behind “The Business” curtain?</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/the-business/the-business.png" length="2076204" type="image/png" />
      <content:encoded><![CDATA[<p>Few <a href="https://en.wikipedia.org/wiki/Corporate_jargon">corporate speak</a> expressions annoy me in as much as these 2 words: 😬</p>
<blockquote>
<p><em>“The business”</em></p>
</blockquote>
<p>This <em>is</em> a pet peeve of mine, for sure. But beyond that, it’s important we stop covering decision makers behind “The Business” curtain.</p>
<p>There is no such entity called “The Business” in companies.</p>
<p>“The Business” isn&rsquo;t a job function or role or group of people.</p>
<p>“The Business” is everyone in the company.</p>
<hr>
<p>So what is happening in reality, behind “The Business” curtain?</p>
<p>It‘s quite frequent that “The Business” is shorthand for “I&rsquo;m only doing what someone asked me”.</p>
<p>Quite often it means the request came through a chain of so many people, no one knows anymore who asked it and what for.</p>
<p>Behind this expression there’s <strong>always people</strong>: <em>someone</em> who wants something <em>for a reason</em>. They need a problem solved, an opportunity to explore, an experiment to try.</p>
<blockquote>
<p>People are the link to context.</p>
</blockquote>
<p>To be effective in our jobs, we must know who are the people at the source of a decision or request. It’s the only way to sidestep all the “<a href="https://en.wikipedia.org/w/index.php?title=Broken_telephone">broken telephone</a>” effect that exists in any chain of requests.</p>
<p>Being able to ask clarifying questions to the source is essential to get an accurate context. And as we know, <a href="/implicit-context">context is everything</a> for the decisions that affect us and requests we&rsquo;re asked to fulfil.</p>
<hr>
<p>Next time someone says “The Business” asked, decided, demanded, etc. follow these 3 simple steps:</p>
<ol>
<li>Ask “<strong>Who</strong> was it that did that?”</li>
<li>If you didn&rsquo;t get a real person, repeat the question applied to that answer</li>
<li>Continue as often as needed until you get to <em>names</em> of real people</li>
</ol>
<p>Well, it’s actually only 1 step 🙂 — Keep asking who’s the person until generic groups or terms becomes actual people names.</p>
<p>It never ceases to surprise me how hard it is sometimes to get to the names of the people who are making some decisions. It gets worse the larger the company is.</p>
<p>Be prepared for the possibility of some interactions to become something like this:</p>
<blockquote>
<p>X: “The Business” decided to use Foo for everything<br>
Me: Who made that decision?<br>
X: It was at the board level<br>
Me: Who in the board was deciding it?<br>
X: Oh, that was done in the steering committee<br>
Me: And who’s part of the steering committee?<br>
X: VPs, C-level and our main stakeholders<br>
Me: Who are those stakeholders?<br>
X: Jane from Bar and John from Baz<br>
Me: And who from the VPs and C-level belongs in the committed?<br>
X: VP of Tech and VP of Product, and now the CFO and CEO as well<br>
Me: Ok, thanks <em>[*sigh* I guess I can get those last titles from the org chart now]</em></p>
</blockquote>
<p>Now we know who to ask for clarification on the rationale behind the Foo decision. I&rsquo;d bet that decision is more nuanced than the “use Foo for <em>everything</em>” you got at the start.</p>
<hr>
<p><strong>Why go through all this trouble?</strong></p>
<p>Because <a href="/implicit-context">context is everything</a>…<br>
Because people are the link to context…</p>
<p>So, remember to always ask:</p>
<blockquote>
<p><strong><em>Who</em> is “The Business”?</strong></p>
</blockquote>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_the-business-considered-harmful-activity-7071878662735708160-rK-X/">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110498105941254453">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/the-business-considered-harmful-6d8b425929a7">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1666113272095952896">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://t.me/c/1363309933/8926">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Mental model for Booleans vs Enumerates</title>
      <link>https://hugo.ferreira.cc/booleans-vs-enums/</link>
      <pubDate>Mon, 15 May 2023 22:16:15 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/booleans-vs-enums/</guid>
      <description>In programming, Booleans and Enumerates are common data types to represent the concept of “choice”.
When there are several things to choose from, the Enumerate is the only one to support it, so that’s clear.
But what about when you have two things to choose from? There might be some confusion between both data types since either of them supports handling binary choices.
The confusion arrises in particular when you want to add the choice of a new behaviour, on top of an existing one.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/booleans-vs-enums/switch-selector.jpg" length="38597" type="image/jpeg" />
      <content:encoded><![CDATA[<p>In programming, <a href="https://en.wikipedia.org/wiki/Boolean_data_type">Booleans</a> and <a href="https://en.wikipedia.org/wiki/Enumerated_type">Enumerates</a> are common data types to represent the concept of “choice”.</p>
<p>When there are several things to choose from, the Enumerate is the only one to support it, so that’s clear.</p>
<p>But what about when you have two things to choose from? There might be some confusion between both data types since either of them supports handling binary choices.</p>
<p>The confusion arrises in particular when you want to add the choice of a new behaviour, on top of an existing one. For example:</p>
<blockquote>
<p>We&rsquo;re torn between adding a <code>boolean</code> called <code>supportsBarMode</code> or having a more descriptive model with an <code>enum</code> that lists all the supported options <code>[FooMode, BarMode]</code>.</p>
<p>The <code>enum</code> solution feels a bit <a href="https://en.wikipedia.org/wiki/You_aren't_gonna_need_it">YAGNI</a> at the moment, but we&rsquo;re open to suggestions. What do you think?</p>
</blockquote>
<hr>
<p>Don’t tie yourself to whether you’ll need more options in the future or not. Instead, look at how you can <em>communicate intent</em> the best way possible.</p>
<p>The mental model for encoding these binary choices is to identify which of these scenarios we are in:</p>
<ul>
<li><strong>Switch something on/off</strong> — e.g. enabling or disabling an extra option</li>
<li><strong>Select mode of operation</strong> — e.g. choosing between ways of doing things</li>
</ul>
<h3 id="boolean--switch-something-onoff">Boolean = Switch something on/off</h3>
<p><img loading="lazy" src="switch.jpg" alt="red switch with a 1 on top, a 0 on the bottom, and turned to the 1 position"  />
</p>
<p>A Boolean fits the 1st scenario. A light switch is either on (have light) or off (don’t have light). When it’s off, there’s no “default alternative behaviour” associated with it: the thing we want to turn on just isn’t there.</p>
<h3 id="enumerate--select-mode-of-operation">Enumerate = Select mode of operation</h3>
<p><img loading="lazy" src="selector.jpg" alt="a coaxial selector with the input on the bottom, an A and B position of top, and the central nob set to the A position"  />
</p>
<p>An Enumerate fits the 2nd scenario. A coaxial selector is either on position A or on position B. It lets you choose between two options. There is a clear meaning associated with each position.</p>
<hr>
<p>In the example above, the Enumerate data type would be the right choice.</p>
<blockquote>
<p>… an <code>enum</code> that lists all the supported options <code>[FooMode, BarMode]</code></p>
</blockquote>
<p>Even if we never add other options to that Enumerate, it is not a case of <a href="https://en.wikipedia.org/wiki/You_aren't_gonna_need_it">YAGNI</a>. The Enumerate could have only 2 options forever that it would still communicate the correct intent.</p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_mental-model-for-booleans-vs-enumerates-activity-7064254945008529411-hUeH">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110378984935193931">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/mental-model-for-booleans-vs-enumerates-df70d917fb41">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1658489697843433472?s=20">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://springernature.slack.com/archives/C01NT4ECRQ8/p1684150514547979?thread_ts=1650552510.015869&amp;cid=C01NT4ECRQ8">Springer Nature Slack</a></li>
<li><a href="https://t.me/c/1363309933/8809">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Pairing Reviews: Bridging the gap between pair programming and code reviews</title>
      <link>https://hugo.ferreira.cc/pairing-reviews/</link>
      <pubDate>Mon, 08 May 2023 22:16:55 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/pairing-reviews/</guid>
      <description>Paring technical sessions for kick-offs and reviews can be a good alternative for programmers frustrated with async code reviews and unhappy with continuous pair programming.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/pairing-reviews/unspash-code-reviews.jpg" length="578496" type="image/jpeg" />
      <content:encoded><![CDATA[<blockquote>
<p>One thing I have experienced to work well in the recent past is to have a technical/design kickoff with other team members when starting a feature: we trade ideias, discuss options, and align on a way forward</p>
<p>— <a href="https://twitter.com/hugocf/status/1116437142010507266">https://twitter.com/hugocf/status/1116437142010507266</a></p>
</blockquote>
<blockquote>
<p>When the time for code review comes it’s a) obvious who should review it, b) easier to review because people have the context already, c) quicker to review because it becomes more focused on details and easier things to correct</p>
<p>— <a href="https://twitter.com/hugocf/status/1116437755670740992">https://twitter.com/hugocf/status/1116437755670740992</a></p>
</blockquote>
<p>Over the years I’ve worked in many software delivery teams under a multitude of working formats:</p>
<ul>
<li>Sometimes working collocated, others as a remote satellite worker, to completely distributed<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li>
<li>With people having very different skill sets and levels of experience<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></li>
<li>Dealing with many different geographical and cultural backgrounds<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></li>
</ul>
<p>Under very different types of pressures,</p>
<ul>
<li>Greenfield projects with strict deadlines</li>
<li>Rescuing huge legacy codebases</li>
<li>Long running product development</li>
</ul>
<p>All these experiences forced me to reassess some of my long held assumptions about ways of working.</p>
<p>In particular, the dichotomy between <strong>pair programming</strong> and <strong>async code reviews</strong><sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> started to feel too strict and “religious” at times. There are many situations where people don’t want the burden of lengthy code reviews for which they lack context. Many other cases where continuous pair programming is not even possible (e.g. large timezone differences or appalling internet connections).</p>
<h2 id="pair-programming-is-not-for-everyone">Pair programming is not for everyone</h2>
<p><img loading="lazy" src="unsplash-pair-programming.jpg" alt="two men with their backs turned to the camera coding together in a laptop with two other large screens displaying code"  />
</p>
<p><em><a href="https://unsplash.com/photos/fSWOVc3e06w">Photo</a> by <a href="https://unsplash.com/@alvarordesign">Alvaro Reyes</a> on <a href="https://unsplash.com/">Unsplash</a></em></p>
<p>This story started during a project with a tight 3 month deadline. We had to be very strict with our scope and be fast on how we ensured quality in the delivery.</p>
<p>All members had years of exposure to pair programming, so they chose to work like that, as a way to deliver faster. By bouncing ideas and reviewing code on-the-fly, we could evolve the code base as a team in an organic way.</p>
<p>One colleague was struggling though. They couldn&rsquo;t adjust to the format under this particular context and delivery pressures.</p>
<p>Either due to personality traits<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> or personal preferences<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>, whatever it was at the core, the team felt the need to embrace it and make some adjustments on the way we worked.</p>
<p>There are many ways around personal differences to make pair programming work. In fact, this is a common practice in pairing since no two people are alike. But sometimes those differences are irreconcilable and this was such a case.</p>
<p>We all agreed that several people looking at the same piece of code was essential to ensure code quality. So, our initial change was to use the most common alternative in the industry: <strong>async code reviews</strong>.</p>
<h2 id="the-problems-we-faced-with-async-code-reviews">The problems we faced with async code reviews</h2>
<p>Code reviews are easy, right?</p>
<ol>
<li>The team kicks off a story</li>
<li>A developer works on it on their own until development is “done”</li>
<li>Some team members review it</li>
</ol>
<p>and then… well, then what? Then that’s where our problems started.</p>
<p>Setting aside how hard it was for a reviewer to get up to speed with the code to review, due to the lack of detailed context…</p>
<p>Setting aside that, since it required quite a significant mental effort to do the above, finding the time to review was also a problem…</p>
<p>Once a code review was in though, the type of issues we caught would fall under 3 categories:</p>
<ol>
<li>
<p><strong>Finishes and polish</strong></p>
<ul>
<li>Stuff that’s simple and easy to change: better names, move something around, extract a method, inline a variable, etc.</li>
<li>It was easy for the author and reviewer(s) to discuss and align these changes. It improves the code base a little and the cost is very low.</li>
<li>✅ Small benefit</li>
<li>⛔️ Small cost</li>
</ul>
</li>
<li>
<p><strong>Marginal better structure</strong></p>
<ul>
<li>
<p>The change to the codebase is not wrong or unworkable. We could improve something and bring marginal benefits but it is not trivial to change at this stage.</p>
</li>
<li>
<p>These changes ended up not happening. They were hard to justify at this stage with the <em>perception</em> was that the benefits were small. It was also hard to overcome the arguments of “but it’s already working”.</p>
</li>
<li>
<p>✅ Small benefit</p>
</li>
<li>
<p>⛔️ ⛔️ Medium cost</p>
</li>
</ul>
</li>
<li>
<p><strong>Wrong implementation approach</strong></p>
<ul>
<li>This is where something was “lost in translation” completely. This might not be that frequent but we’ve seen it happen enough times to hate the experience.</li>
<li>Catching severe misconceptions in the implementation approach at such a later stage has a very high cost. This means lots of rework, lost time, and waste. Regardless, we must do it.</li>
<li>✅ ✅ ✅ Large benefit</li>
<li>⛔️ ⛔️ ⛔️ Large cost</li>
</ul>
</li>
</ol>
<p>The first category of issues (#1) is a no brainer and hardly a contentious point. This is an obvious benefit of code reviews to improve code quality.</p>
<p>The last category (#3) is very painful and quite a blow to the team. To throw away and rework all the investment at such a late stage is painful. It’s a necessary evil that everyone can agree and, again, a clear benefit of code reviews.</p>
<p>The biggest problem and what concerns us the most were the middle category (#2) of issues. These missed opportunities lie <em>only</em> on the fact that the team caught these issues <em>too late</em>.</p>
<p>There reason these changes are so important relate with the <a href="https://en.wikipedia.org/wiki/Broken_windows_theory">broken windows theory</a>. There’s the <em>perception</em> that these benefits are marginal, but they compound over time. They end up becoming a tangled web inaccurate abstractions, faulty approaches and bad code. These are not straight forward to solve, especially in a time constrained project.</p>
<p><strong>Catching issues too late</strong> is a good summary of the key problems we faced with code reviews.</p>
<p>Pair programming gives realtime feedback, since discussions happen <em>as people write the code</em>. Being used to that, all the waste illustrated above was more that the teams could handle.</p>
<h2 id="our-guiding-principles">Our guiding principles</h2>
<p>When we have conflict between people due to <em>practices we deem fundamental</em>, where do we draw the line?</p>
<p>All this adds tension and complexity to our ways of working. Working through these differences and find effective strategies, requires <strong>compassion</strong> between team members.</p>
<p>More than specific <em>practices</em>, our focus should be in the <em>immutable principles</em> behind those practices. They set the stage and give context for the team’s choices.</p>
<p>These are the key foundational principles that were guiding our directions:</p>
<ol>
<li><strong>Team-based ownership of the entire delivery</strong>
<ul>
<li>At the technical level, this means more than one person understanding and caring for each piece of code written.</li>
<li>Not only the technical aspects (codebase, pipelines, observability) but also including roadmap, backlog, priorities, etc.</li>
<li>Several people together think better than a single one. Over time, this reflects in an increased quality of the code base.</li>
</ul>
</li>
<li><strong>Include all the members of the team as equals</strong>
<ul>
<li>It is usually said that whenever someone leaves or joins a team, it becomes a new team altogether.</li>
<li>Being a cohesive team implies welcoming the participation and voices of all its members.</li>
<li>Seek for “consent” and “acceptance” from the group, rather than aiming for the elusive “consensus” or “agreement” from everyone.</li>
</ul>
</li>
</ol>
<h2 id="a-positive-mix-between-both-approaches">A positive mix between both approaches</h2>
<blockquote>
<p>I think both techniques are clearly a net <em>good</em>, although they each have their particular pros and cons.</p>
<p>I don&rsquo;t think it&rsquo;s a matter of picking one over the other so much as <strong>ensuring you have more than one pair of eyes looking at the code you&rsquo;ve written</strong></p>
<p>— <a href="https://blog.codinghorror.com/about-me/">Jeff Atwood</a> in <a href="https://blog.codinghorror.com/pair-programming-vs-code-reviews/">Pair Programming vs. Code Reviews</a></p>
</blockquote>
<p>How could we leverage the benefits of pair programming and avoid the flaws of async code reviews? Something that incorporates some of the learnings and key strengths of both approaches:</p>
<ul>
<li>Develop code with collaboration built-in from the start</li>
<li>Avoid building a wasteful inventory of code changes pending review</li>
<li>Make the review experience engaging and straightforward, with reduced cognitive load (as possible)</li>
</ul>
<p>So we started doing what you can call a <strong>“sandwich”</strong> of both approaches:</p>
<ul>
<li><strong>Start</strong> with a pair programming session for <strong>technical kick-off</strong> and code design/exploration</li>
<li><strong>Continue</strong> with individual <strong>async development</strong> and implementation</li>
<li><strong>End</strong> with a pair programming session for <strong>code review</strong> and discussion</li>
</ul>
<p>In more detail, the story development workflow became:</p>
<ol>
<li>
<p>Story kick-off with all the team’s disciplines<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup> involved (UX + PO + QA + DEVs)</p>
<ul>
<li>Here we shape the user story acceptance criteria and scenarios.</li>
</ul>
</li>
<li>
<p>Once it’s over, the DEVs (a pair or trio) would stay on for a technical kick-off</p>
<ul>
<li>Here they discuss the actual technical design and implementation approaches</li>
<li>This implies going over the code base and exploring alternatives</li>
<li>Discuss modelling options (e.g. extend a class vs extract an interface), explore potential new patterns or structural refactoring, etc.</li>
</ul>
</li>
<li>
<p>The solo DEV would move on and do the development as discussed with their colleagues in #2</p>
</li>
<li>
<p>Once it’s development finishes, it’s time for the code review</p>
<ul>
<li>
<p>It’s now trivial to identify <em>who</em> should join the code review: those that were in the technical discussion in step #2</p>
</li>
<li>
<p>They join the DEV implementing to walkthrough the code changes and discuss them</p>
</li>
<li>
<p>Depending if the changes are quite simple, if it remains aligned with the initial direction, then this could an async step</p>
</li>
</ul>
</li>
</ol>
<p>Notice that step #3 implies a good level of maturity from the solo DEV implementing the story. They need to reassemble with the people from the pairing kick-off in step #2 whenever the direction diverges:</p>
<ul>
<li>They face a roadblock or start entering a rabbit hole</li>
<li>They realise the initial ideas are no longer valid with new discoveries</li>
<li>The direction becomes impractical or turns out more complex than expected</li>
</ul>
<p>The main takeaway is that the team must discuss technical approaches together, and the earlier this happens, the better. This approach promotes those discussions to happen much earlier than in async code review.</p>
<hr>
<p><strong>So, does this mean more meetings?</strong></p>
<p>No, definitely not. These are work sessions. You start, work together, and finish when the group understands they&rsquo;re in a good place of understanding. It takes 30 min or several half days, depending on the complexity of the work at hand.</p>
<p><strong>Then it’s only for complex stories?</strong></p>
<p>Not at all. Do it for <em>every</em> user story, no matter how simple it seems at first.</p>
<p>While complex stories need to involve the entire DEV team, simpler stories should only need one other developer. And if the story turns out to be very simple, them it’ll take only a few minutes and you’re done.</p>
<p>The most important factor is to build the habit muscle of doing it always. This will help you catch and avoid several blind spots and assumptions. Sometimes behind that seems simple hides a crucial decision when you start trading ideas with others.</p>
<p><strong>Does splitting up and coming together increase Work in Progress (WIP)?</strong><br>
<em>(by <a href="https://beny23.github.io/about/">Gerald Benischke</a>)</em></p>
<p>It’s the same as if you’d be in an “async code review” model where each dev picks up a story individually.</p>
<p>If you switched an entire team doing pair programming into this model, then yes, WIP would increase since you’d now have single devs coding stories instead of pairs.</p>
<p>In our case though, we applied it only to the single dev mentioned in the story above. The two other pairs continued to do pair programming, so there was no significant change in WIP.</p>
<hr>
<h2 id="benefits-of-the-pairing-code-reviews-approach">Benefits of the “pairing code reviews” approach</h2>
<p>To start with, the focus of the reviews became all about the “1. Finishes and polish”. Easy refactoring, practical renames, etc. which code reviews well suited for stayed.</p>
<p>The problems with “2. Marginal better structure” and “3. Wrong implementation approach” disappeared from the reviews. They’d either be all discussed at the start or along the way, close to when they became relevant.</p>
<p>Pairing at the time of code review also helped with the fluidity of the review. Since all had context, it was much easier to discuss and change the code as we went along. Much better than dealing with a lengthy back and forth of asynchronous interruptions.</p>
<p>It lifted the weight of constant pairing, for those who had difficulty with it or which the timezones did not permit. Because it happened only at clear distinct milestones in the development lifecycle,</p>
<p>Also, it removed the feeling a being “evaluated”. It added a more collaborative mindset of working together, of building something together.</p>
<hr>
<p><strong>There are no silver bullets for most things in life. Everything is a tradeoff. With this, you have one more useful approach to consider when your context needs it.</strong></p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_pairing-reviews-bridging-the-gap-between-activity-7061741994934439936-2b9w">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110339721804211796">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/pairing-reviews-bridging-the-gap-between-pair-programming-and-code-reviews-781a1c6ba4bc">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1655976747760746510?s=20">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://equalexperts.slack.com/archives/DDVFQU1FZ/p1683651516481779">Equal Experts Slack</a></li>
<li><a href="https://ios.slack.com/archives/C0721L3CL/p1683650827356959">iOS PT Slack</a></li>
<li><a href="https://t.me/c/1363309933/8770">Telegram</a></li>
</ul>
</details>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>See post section <a href="https://www.martinfowler.com/articles/remote-or-co-located.html#TheManyShadesOfRemoteness">The Many Shades of Remoteness</a> by <a href="https://www.martinfowler.com/aboutMe.html">Martin Fowler</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>See <a href="https://staffeng.com/guides/overview-overview/">Guides for reaching Staff-plus engineering roles</a> by <a href="https://lethain.com/about/">Will Larson</a>.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>See book <a href="https://www.goodreads.com/book/show/22085568-the-culture-map">The Culture Map</a> by <a href="https://erinmeyer.com/about/">Erin Meyer</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>See the <a href="https://docs.github.com/en/get-started/quickstart/github-flow">GitHub flow</a> pull request (PR) model, popularised by GitHub.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>For example, some people have a way of “thinking with their fingers” where they need to do exploratory code refactoring. Others prefer to do a more strict TDD style, write test cases first and let production code evolve in a fluid way. There are those who need conceptual thinking and brainstorming before writing any code.&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>For example, listening to music or chasing “the zone” are things that you cannot do in pairing.&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p>Some people call this “3 amigos” but this is more like “all the amigos”. Every discipline in the team joins to discuss it together.&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Context is everything, even when you don’t see it</title>
      <link>https://hugo.ferreira.cc/implicit-context/</link>
      <pubDate>Mon, 24 Apr 2023 22:16:52 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/implicit-context/</guid>
      <description>We have all heard the common sense1 saying that “context is everything” at some point of our life. It’s a reminder to consider the circumstances before making judgments or decisions.
Especially in consultancy, “context is everything” is a famous adage. What is true in one company, almost never applies directly to another. We always need to do major adjustments to the new context and the different realities.
But what if I told you that we can take this idea even further?</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/implicit-context/kashan-iran-unsplash.jpg" length="2055649" type="image/jpeg" />
      <content:encoded><![CDATA[<p>We have all heard the common sense<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> saying that “context is everything” at some point of our life. It’s a reminder to consider the circumstances before making judgments or decisions.</p>
<p>Especially in consultancy, “context is everything” is a famous adage. What is true in one company, almost never applies directly to another. We always need to do major adjustments to the new context and the different realities.</p>
<hr>
<p>But what if I told you that we can take this idea even further? What if I told you that <em>nothing</em> has advantages or disadvantages, only characteristics?</p>
<p>At first, this might seem like a strange notion. After all, we are so used to consider pros and cons when comparing different products or services.</p>
<p>Take, for example, someone in the market for a home safe. Most suppliers will brag about how resistant to tampering theirs locks are. An advantage, right? After all, that’s what all homeowners will be looking for: protection.</p>
<p>But what if we are talking about a burglar? Now, that <em>same</em> characteristic is a big disadvantages when looking for a home to target.</p>
<p>Still with a burglar in our minds, what if they are looking for a safe to take home and <em>practice</em> breaking into? It’s the same person but now that <em>same</em> characteristic is again an advantage.</p>
<p>We can see many more examples like this in the software development industry. It’s common to find technical analysis of frameworks, libraries, or programming languages. They are usually filled with positive and negative evaluations, advantages and disadvantages.</p>
<p>But what context are the authors using to assess them? Most of the times this is absent, which can lead to controversy and people talking past each other.</p>
<hr>
<p>What the above examples illustrate is the <strong>implicit context</strong> we all have that is very often not said out loud. Not clarifying this full context is the most common pitfall of comparisons.</p>
<p>It’s the implicit context that “the purpose of safes is to protect”. It’s the implicit context that “frameworks should be stable”, or “performant”, or “easy to use”. Same goes for programming languages, where implicit contexts are many and sometimes contradictory. If we dig a little deeper, we will find that all these comparisons are only meaningful under some context.</p>
<p>Everyone has their own <em>implicit</em> context in their minds. In society, within cultures, we share common <em>implicit</em> contexts. This all bleeds in when we talk to each other.</p>
<p>So, what’s the solution? We need to make the <em>implicit</em> context <em>explicit</em>. Even if it seems redundant! Even when “everyone knows this”.</p>
<p>Always question yourself and be aware of the context you bring to every conversation. This include your goals, your constraints, past experiences and values. These are the “tinted glasses” you see the world through, and everyone else has their own.</p>
<p>Be curious about how other people’s <em>implicit</em> context differs from yours. You can gain a better understanding of their perspective and work better together.</p>
<hr>
<p>If you analyse something by yourself, the danger of misunderstandings isn’t there. Implicit and explicit context tend to mix since it’s all internal. But looking for that <em>implicit</em> context might surprise you and shed new light into the “why” of your choices.</p>
<p>When analysing with someone we know very well, relying on a shared <em>implicit</em> context is possible. Misunderstandings are less likely but can still happen. Be very attentive and default to clarifying and making it <em>explicit</em> at the first sign of trouble.</p>
<p>Not relying on <em>implicit</em> context becomes crucial when working in larger collaborative groups. It’s impossible to rely on <em>implicit</em> context because everyone has a different one. This is especially important when working in multicultural environments, which bring even wider <em>implicit</em> context differences.</p>
<p>So, when preparing for a group discussion by yourself, start by gathering the different characteristics of the topic. Aim to do it in an impartial way, devoid of context. Then, with the group, define together which context to assess those characteristics under.</p>
<p>If you’re in the middle of a group brainstorming going sideways, go back to ensure that the context aligns. Clarify what is the agreed-upon context and, if there’s none, define it. Give everyone a shared frame of reference to assess the different solutions.</p>
<hr>
<p>Next time you think about pros and cons of something, take a moment to consider the <em>implicit</em> context.</p>
<p>Remember that <strong>nothing has advantages or disadvantages, only characteristics.</strong> We can assess them under different contexts, and yours will likely differ from someone else’s.</p>
<p>Make all context <em>explicit</em> and be curious about other people’s perspectives. This way you can make work more effective and make better decisions together.</p>
<hr>
<p><strong>Update 2023-05-17:</strong><br>
<em>(via <a href="https://mmitii.mattballantine.com/2023/05/17/pick-up-a-penguin/">Andy Kemp</a>)</em></p>
<p>Interesting research supporting this notion of implicit context in the Scientific America article <a href="https://www.scientificamerican.com/article/people-differ-widely-in-their-understanding-of-even-a-simple-concept-such-as-the-word-penguin1/">People Differ Widely in Their Understanding of Even a Simple Concept Such as the Word &lsquo;Penguin&rsquo;</a>:</p>
<blockquote>
<p>“The probability two people selected at random will share the same concept about penguins is around 12 percent,” Kidd says.</p>
</blockquote>
<p>The reason is people’s different life experiences:</p>
<blockquote>
<p>For example, “people disagree about things like whether penguins are heavy, presumably because they haven’t lifted a penguin.” Here, Kidd hints at where a lot of these differences likely come from: they boil down to a person’s life experiences “If you&rsquo;ve spent time watching penguins walk, you’re maybe more likely to think they’re heavy from their waddle,” Kidd says. “If you&rsquo;ve spent time learning about anatomy, you’ve maybe learned birds have light skeletons and so think penguins are light.”</p>
</blockquote>
<p>And the differences can be quite numerous:</p>
<blockquote>
<p>…the team’s results suggest that at least 10 to 30 quantifiably different concept variants exist for even common nouns such as penguin.</p>
</blockquote>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_context-is-everything-even-when-you-don-activity-7057460932272128000--SHL/">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110272811718806530">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/context-is-everything-even-when-you-dont-see-it-8d56715c7c32">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1651694780768763905">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://equalexperts.blogin.co/posts/blockers-to-collaboration-212218#c240989">Equal Experts Blogin</a></li>
<li><a href="https://t.me/c/1363309933/8716">Telegram</a></li>
</ul>
</details>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I know, sometimes “common sense” is not that common 😏&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Slack Overload? Regain control with Inbox Zero principles</title>
      <link>https://hugo.ferreira.cc/slack-inbox/</link>
      <pubDate>Mon, 17 Apr 2023 20:58:27 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/slack-inbox/</guid>
      <description>The goal is to apply “inbox zero” concepts to Slack and mitigate the pressures to “respond immediately”. The realisation is that &lt;em&gt;sections&lt;/em&gt; can become a pseudo-inbox of &lt;em&gt;channels&lt;/em&gt; that need reading (as opposed to considering &lt;em&gt;messages&lt;/em&gt; the unit to manipulate).</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/slack-inbox/clutter-vs-clean.webp" length="627366" type="image/webp" />
      <content:encoded><![CDATA[<p><em><strong>Update 2024-05-08:</strong> Finish updating the <a href="#setup">full setup</a> description according to the new sections format. Also, add a cover image.</em></p>
<p><em><strong>Update 2024-04-19:</strong> Add illustrative images to the <a href="#context">Context</a> section, including info on <a href="#rivers-not-buckets">Rivers, not buckets</a>.</em></p>
<p><em><strong>Update 2024-02-13:</strong> Introduce headings for easier navigation and highlight <a href="#problem">the core problem</a> with messaging apps.</em></p>
<p><em><strong>Update 2023-10-17:</strong> Replace simplistic “Channels/Someday” channel organisation with a <a href="https://en.wikipedia.org/wiki/MoSCoW_method">MoSCoW</a>-inspired <a href="#sections">sections structure</a> optimised for fast processing.</em></p>
<h2 id="context">Context</h2>
<p>Lets start by recalling a few old principles about processing large volumes of information, and then define the core problem with modern messaging apps, as I see it…</p>
<h3 id="inbox-zero">📥 Inbox zero</h3>
<figure>
    <img loading="lazy" src="inbox-zero.webp"
         alt="A minimalist black and white sketch illustrating the concept of &#39;Inbox Zero&#39;. The image features a simple line drawing of an open, empty email inbox on a computer screen. Beside the screen, a content person is sitting, looking relaxed with hands behind their head, symbolizing satisfaction and relief."/> <figcaption>
            <p>“A black and white sketch image to illustrate the concept of inbox zero”
                    <a href="https://openai.com/dall-e">(DALL·E)</a></p>
        </figcaption>
</figure>

<p>“Inbox zero” is a pivotal concept to deal with the constant influx of information of modern life. <a href="https://en.wikipedia.org/wiki/Merlin_Mann#Writing">Merlin Mann coined it</a> in 2006, during a <a href="http://www.43folders.com/2006/04/05/wrapup">series of posts on 43Folders</a>.</p>
<blockquote>
<p>That “zero?” It’s not how many mes­sages are in your inbox–it’s how much of your own <em>brain</em> is in that inbox. Especially when you don’t want it to be. That’s it.</p>
<p>— <a href="http://inboxzero.com">Inbox Zero</a> <em>(<a href="https://web.archive.org/web/20110712000524/http://inboxzero.com:80/">Internet Archive 2011-07-12</a>)</em></p>
</blockquote>
<p>It was not about “perfection” but rather a way for us to take back control of our time and avoid being reactive. To do that, you triage messages to focus on what matters:</p>
<ol>
<li>Take fixed times in the day to go through your inboxes — close or ignore them outside of those times</li>
<li>Make decisions, not actions — triage fast and act later, so you’re not derailed into a long essays</li>
</ol>
<p>Once you’re done for the time slot, you can get out of that “new/unread” mind space. Go back to doing your actions, according to whichever criteria you think fits best.</p>
<p>At the time, this concept appeared to deal with the problems of overwhelmed email inboxes. Its core principles expand beyond email though. They are essential to get out of a reactivity loop and quite generic that they apply to other areas or our life:</p>
<blockquote>
<p><strong>Accept that almost everything in your life is an inbox</strong></p>
<p>— <a href="https://www.wired.co.uk/profile/natasha-bernal">Natasha Bernal</a> on <a href="https://www.wired.co.uk/article/inbox-zero-mentality">Everything you thought you knew about inbox zero is wrong | WIRED UK</a> <em>(<a href="https://web.archive.org/web/20240225133459/https://www.wired.co.uk/article/inbox-zero-mentality">Internet Archive 2024-02-25</a>)</em></p>
</blockquote>
<h3 id="rivers-not-buckets">⛲️ Rivers, not buckets</h3>
<figure><a href="https://sketchplanations.com/rivers-and-buckets">
    <img loading="lazy" src="rivers-and-buckets.webp"
         alt="Illustration displaying two figures by a riverbank, metaphorizing information flow. One figure sits calmly on a rock, fishing in the river, while the other stands overwhelmed by multiple buckets labeled with tasks like &#39;To Read&#39;, &#39;Email&#39;, &#39;Visit&#39;, and &#39;Listen&#39;, suggesting the challenge of managing a constant stream of tasks and information."/> </a><figcaption>
            <p>“<a href="https://sketchplanations.com/rivers-and-buckets">Instead of a bucket list to get through, try thinking of it as a river where attractive options drift by</a>”
                    <a href="https://sketchplanations.com">(Sketchplanations)</a></p>
        </figcaption>
</figure>

<p><a href="https://en.wikipedia.org/wiki/Dave_Winer">Dave Winer</a> id one of the creators of the <a href="https://en.wikipedia.org/wiki/RSS">RSS</a> specification and a <a href="https://en.wikipedia.org/wiki/Dave_Winer#:~:text=Winer%27s%20Scripting%20News%2C%5B3%5D%20described%20as%20%22one%20of%20the%20%5Bweb%27s%5D%20oldest%20blogs%2C%22%5B47%5D%20launched%20in%20February%201997%5B19%5D%3A%E2%80%8A59%E2%80%8A%5B48%5D%20and%20earned%20him%20titles%20such%20as%20%22protoblogger%22%5B49%5D%20and%20%22forefather%20of%20blogging">forefather of blogging</a>. He started advocating the concept of a <a href="http://scripting.com/stories/2009/09/02/isRiverOfNewsEnough.html">River of News</a> in the early 2000s:</p>
<blockquote>
<p>They call them streams, lifestreams, etc, but they&rsquo;re all the same basic idea. Park yourself on the riverbank and watch the news flow by. If you miss something, not to worry, if it&rsquo;s important some new story will refer to it.</p>
</blockquote>
<p>Since then, the “stream of information” concepts have spread to most online experiences. There’s prime examples in all the social media applications, newspapers, aggregators, etc.</p>
<p><a href="https://en.wikipedia.org/wiki/Oliver_Burkeman">Oliver Burkeman</a> expands on this concept and urges you to <a href="https://www.oliverburkeman.com/river">treat your to-read pile like a river</a>. In this approach, you cherry-pick the most important things that stand out, and let the other ones drop:</p>
<blockquote>
<p>To return to information overload: this means treating your &ldquo;to read&rdquo; pile like a river (a stream that flows past you, and from which you pluck a few choice items, here and there) instead of a bucket (which demands that you empty it).</p>
</blockquote>
<p>There’s also an underlying need that is worth highlighting, and it might not seem obvious at first sight. <strong>We must be able to identify which</strong> of the pieces of info floating through <strong>are important to us</strong>.</p>
<h3 id="problem">💬 Messaging apps problem</h3>
<figure>
    <img loading="lazy" src="messaging-apps.webp"
         alt="A cartoon-style sketch depicting a frustrated figure surrounded by numerous chat bubbles to represent the overwhelming flow of instant messages. The workspace around the figure appears cluttered with multiple papers, vibrating phones, laptops and gadgets."/> <figcaption>
            <p>“Illustrate the text in this section in the cartoon-style”
                    <a href="https://openai.com/dall-e">(DALL·E)</a></p>
        </figcaption>
</figure>

<p>Nowadays work happens on instant message applications, not email. These types of applications are quite bad in letting us apply the above concepts:</p>
<ul>
<li>Their structure revolves around immediacy of synchronous messages and responses</li>
<li>Their core unit to manipulate is the <em>channel</em>, not individual <em>messages</em></li>
</ul>
<p><strong>Slack</strong>, in particular, is one of the worst offenders in this matter. Many of of their design decisions reinforce the notion of immediacy and having to “keep up” with it. For example:</p>
<ul>
<li>The frequent “X is typing” notices</li>
<li>The inability to read recent messages and keep older ones unread for later</li>
</ul>
<hr>
<h2 id="solution">Solution</h2>
<h3 id="solution">⏱️ The gist of the solution</h3>
<p>The goal is to apply the “inbox zero” concepts outlined above and mitigate the pressures to “respond immediately”.</p>
<p>The realisation is that <em>sections</em> can become a pseudo-inbox of <em>channels</em> that need reading (as opposed to considering <em>messages</em> the unit to manipulate).</p>
<p>This is how I setup my <strong>Slack</strong> channels <em>sections</em> to make them behave more like an inbox:</p>
<ul>
<li>Show channels with <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">Unread messages only</a></li>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">By most recent</a></li>
</ul>
<p><img loading="lazy" src="slack-section-inbox.webp" alt="Slack context menu displaying the “Show and sort” details of a sidebar section"  />
</p>
<h3 id="sections">🗂️ Organise for fast processing</h3>
<p>In practice, the most granular unit you can manage your “unreads” in Slack is the <em>channel</em>, not the <em>message</em>.</p>
<p>Depending on how far back I am with the backlog of <del>messages</del> channels  to read, I want to be more flexible to decide where to stop (i.e. I’ve seen what’s important) and “mark all as read” the rest (i.e. <a href="https://sketchplanations.com/rivers-and-buckets">“rivers, not buckets”</a>).</p>
<p>As for which sections to use, I’ve ended up with a MoSCoW-inspired list where I essentially answer the following questions for each channel:</p>
<ul>
<li>How directly related to my work/role is it?
<ul>
<li>✅ Yes, very</li>
<li>☑️ Meh, kinda</li>
<li>ℹ️ Not really</li>
</ul>
</li>
<li>Am I keen on reading/seeing new messages on it?
<ul>
<li>👀 Yes</li>
<li>🙈 Nope</li>
</ul>
</li>
</ul>
<p>The decision matrix for where to save each channel then becomes something like this:</p>
<table>
<thead>
<tr>
<th>Directly related to my role?</th>
<th>Am I keen on reading it?</th>
<th></th>
<th>Section</th>
</tr>
</thead>
<tbody>
<tr>
<td>✅ Yes</td>
<td>👀 Yes</td>
<td>➔</td>
<td>🔴 <strong>Must</strong></td>
</tr>
<tr>
<td>✅ Yes</td>
<td>🙈 Nope</td>
<td>➔</td>
<td>🟠 <strong>Should</strong></td>
</tr>
<tr>
<td>☑️ Kinda</td>
<td>👀 Yes</td>
<td>➔</td>
<td>🟢 <strong>Want</strong></td>
</tr>
<tr>
<td>☑️ Kinda</td>
<td>🙈 Nope</td>
<td>➔</td>
<td>🟡 <strong>Could</strong></td>
</tr>
<tr>
<td>ℹ️ Nope</td>
<td>👀 Yes</td>
<td>➔</td>
<td>🔵 <strong>Nice</strong></td>
</tr>
<tr>
<td>ℹ️ Nope</td>
<td>🙈 Nope</td>
<td>➔</td>
<td>⚫️ <strong>Maybe</strong></td>
</tr>
</tbody>
</table>
<p>In practice, the order of those sections in Slack changed a little bit over time and now follow what is roughly two sets of “traffic lights”: 🚥</p>
<ul>
<li>🔴 <strong>Must</strong>, 🟠 <strong>Should</strong>, 🟢 <strong>Want</strong> — Allways read, and read regularly
<ul>
<li><em>(if on a very tight time crunch, “Want” might be skipped)</em></li>
</ul>
</li>
<li>🔵 <strong>Nice</strong>, 🟡 <strong>Could</strong>, ⚫️ <strong>Maybe</strong> — Read sproradically, depending on time and energy
<ul>
<li><em>(good candidates for the context menu action “Manage” ➤ “Mark all as read”)</em></li>
</ul>
</li>
</ul>
<p>Putting it all together:</p>
<p><img loading="lazy" src="slack-section-list.webp" alt="Slack sidebar view of sections: Must, Should, Want, Nice, Could, Maybe"  />
</p>
<p>This is now the most battle tested setup I have stayed with for many months. Most past setups broke down on the “coming back from holidays” huge backlog of stuff to read.</p>
<p>This setup lets me manage my time/energy more effectively and use the “mark all as read” more often, once the core channels are cleared.</p>
<h3 id="processing">📨 Processing inboxes</h3>
<p>With this, my daily process becomes, at specific times during the day:</p>
<ol>
<li>Deal with <strong>Direct messages</strong></li>
<li>Check for <strong>Threads</strong> updates</li>
<li>Process the updated <strong>Channels</strong> in the first section 🔴 <strong>Must</strong></li>
<li>Continue to the second section 🟠 <strong>Should</strong></li>
<li>If time permitting, continue going down to the 🟢 <strong>Want</strong> section</li>
</ol>
<p>When I have some more relaxed time, usually at the end of the day:</p>
<ol start="6">
<li>Skim and cherry-pick from the remaining sactions channels some messages that spark my curiosity</li>
<li><code>Shift-Esc</code> to “mark all as read” and have an clean slate for next day</li>
</ol>
<style type="text/css">
    .notice {
        --root-color: #444;
        --root-background: #eff;
        --title-color: #fff;
        --title-background: #7bd;
        --warning-title: #c33;
        --warning-content: #fee;
        --info-title: #fb7;
        --info-content: #fec;
        --note-title: #6be;
        --note-content: #e7f2fa;
        --tip-title: #5a5;
        --tip-content: #efe;
    }

    @media (prefers-color-scheme:dark) {
        .notice {
            --root-color: #ddd;
            --root-background: #eff;
            --title-color: #fff;
            --title-background: #7bd;
            --warning-title: #800;
            --warning-content: #400;
            --info-title: #a50;
            --info-content: #420;
            --note-title: #069;
            --note-content: #023;
            --tip-title: #363;
            --tip-content: #121;
        }
    }

    body.dark .notice, [data-theme="dark"] .notice {
        --root-color: #ddd;
        --root-background: #eff;
        --title-color: #fff;
        --title-background: #7bd;
        --warning-title: #800;
        --warning-content: #400;
        --info-title: #a50;
        --info-content: #420;
        --note-title: #069;
        --note-content: #023;
        --tip-title: #363;
        --tip-content: #121;
    }

    .notice {
        padding: 18px;
        line-height: 24px;
        margin-bottom: 24px;
        border-radius: 4px;
        color: var(--root-color);
        background: var(--root-background);
    }

    .notice p:last-child {
        margin-bottom: 0;
    }

    .notice-title {
        margin: -18px -18px 12px;
        padding: 4px 18px;
        border-radius: 4px 4px 0 0;
        font-weight: 700;
        color: var(--title-color);
        background: var(--title-background);
    }

    .notice.warning .notice-title {
        background: var(--warning-title);
    }

    .notice.warning {
        background: var(--warning-content);
    }

    .notice.info .notice-title {
        background: var(--info-title);
    }

    .notice.info {
        background: var(--info-content);
    }

    .notice.note .notice-title {
        background: var(--note-title);
    }

    .notice.note {
        background: var(--note-content);
    }

    .notice.tip .notice-title {
        background: var(--tip-title);
    }

    .notice.tip {
        background: var(--tip-content);
    }

    .icon-notice {
        display: inline-flex;
        align-self: center;
        margin-right: 8px;
    }

    .icon-notice img, .icon-notice svg {
        height: 1em;
        width: 1em;
        fill: currentColor;
    }

    .icon-notice img, .icon-notice.baseline svg {
        top: .125em;
        position: relative;
    }
</style><div class="notice tip" >
    <p class="notice-title">
        <span class="icon-notice baseline">
            <svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20"><path d="m429-336 238-237-51-51-187 186-85-84-51 51 136 135Zm51 240q-79 0-149-30t-122.5-82.5Q156-261 126-331T96-480q0-80 30-149.5t82.5-122Q261-804 331-834t149-30q80 0 149.5 30t122 82.5Q804-699 834-629.5T864-480q0 79-30 149t-82.5 122.5Q699-156 629.5-126T480-96Z"/></svg>
        </span>Tip</p><p>You can take advantage of the <strong>Unread messages</strong> sidebar item to speed up this process. See the <a href="#sidebar-unread-messages">Tips and tricks</a> section below.</p></div>

<h3 id="setup">🚧 Full setup</h3>
<p>The sidebar consists of the following sections, in this order:</p>
<p><img loading="lazy" src="slack-sidebar.webp" alt="Screenshot of the full sidebar showing all the different sections described here"  />
</p>
<ol>
<li><strong>Starred</strong> default section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">Alphabetically</a> and showing <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">All</a> channels</li>
<li><em>Expanded</em> all the time</li>
<li>Contains conversations that I want to remain “pinned” on the top of the sidebar for a short time, regardless of read or not</li>
<li>Used for ongoing group messages or temporary channels with an active conversation for a few days or so</li>
<li>Direct messages of <code>@Slackbot</code> (notices and some mentions) and my own user <code>@me</code> (for scratch notes) are always starred here</li>
</ul>
</li>
<li><strong>Direct messages</strong> default section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">By most recent</a> and showing channels with <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">Unread messages only</a></li>
<li><em>Expanded</em> all the time</li>
</ul>
</li>
<li><strong>Temp</strong> <a href="https://slack.com/help/articles/360043207674-Organize-your-sidebar-with-custom-sections#create-custom-sections"><em>custom</em></a> section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">By most recent</a> and showing channels with <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">Unread messages only</a></li>
<li><em>Collapsed</em> all the time</li>
<li>Like temporary solutions tend to last forever, so the same happens with temporary channels</li>
<li>This collects temporary channels so I can the person nagging to archive them when they’ve served their purpose</li>
<li>I usually set a reminder on a relevant message as a trigger for when it’s time to archive</li>
</ul>
</li>
<li>🔴 <strong>Must</strong> <a href="https://slack.com/help/articles/360043207674-Organize-your-sidebar-with-custom-sections#create-custom-sections"><em>custom</em></a> section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">By most recent</a> and showing channels with <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">Unread messages only</a></li>
<li><em>Expanded</em> all the time</li>
<li>This section contains <em>only</em> the channels that are <em><strong>essential</strong> to my day-to-day work</em>, as <a href="#sections">described above</a></li>
</ul>
</li>
<li>🟠 🟢 🔵 🟡 ⚫️ the other <a href="https://slack.com/help/articles/360043207674-Organize-your-sidebar-with-custom-sections#create-custom-sections"><em>custom</em></a> section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">By most recent</a> and showing channels with <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">Unread messages only</a></li>
<li><em>Collapsed</em> most of the time</li>
<li>The remaining less critical channels end up in these sections, as <a href="#sections">described above</a></li>
</ul>
</li>
<li><strong>Channels</strong> default section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">Alphabetically</a> and showing <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">All</a> channels</li>
<li><em>Expanded</em> all the time</li>
<li>This section is usually empty</li>
<li>Only temporarily, it can contain channels I’ve just joined and have not yet been sorted into their right section, as <a href="#sections">described above</a></li>
</ul>
</li>
<li><strong>Apps</strong> default section
<ul>
<li>Sorted <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">Alphabetically</a> and showing <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#choose-which-conversations-to-show">All</a> channels</li>
<li><em>Collapsed</em> most of the time</li>
<li>Easy access to apps I use on occasion but not so often that I remember their name</li>
</ul>
</li>
</ol>
<hr>
<h2 id="information">Information</h2>
<h3 id="tips">💡 Tips and tricks</h3>
<h4 id="navigation-alternatives">Navigation alternatives</h4>
<p>With this approach, channels and conversations disappear from the sidebar once we read them. There are few options to navigate around and finding previous channels or conversations:</p>
<ul>
<li>Shortcut <code>CMD-K</code> to find and jump to a specific channel</li>
<li>History 🕒 view to go back to recent chats and last visited channels</li>
<li><strong>DMs</strong> view on the navigation bar to quickly get back to a group conversation</li>
<li><strong>Threads</strong> view, to see updates on conversations where I choose to <a href="https://slack.com/help/articles/115000769927-Use-threads-to-organize-discussions-#manage-thread-notifications">Get notified about new replies</a></li>
</ul>
<h4 id="sidebar-unread-messages">Sidebar “Unread messages”</h4>
<p>You can take advantage of the <a href="https://slack.com/intl/en-gb/help/articles/212596808-Adjust-your-sidebar-preferences#customise-the-top-of-your-sidebar">sidebar <strong>Unread messages</strong></a> to process channels and messages in line with the sections concept shown above:</p>
<ul>
<li>Choose “Sorted like your sidebar”</li>
<li>Display only the 🔴 <strong>Must</strong> section</li>
<li>Once cleared, you can easily <strong>Jump to the 🟠 <strong>Should</strong> section</strong>
<ul>
<li>… and so forth, until all sections are cleared one after the other</li>
</ul>
</li>
</ul>
<p><img loading="lazy" src="slack-unread-messages.webp" alt="Slack message from the “Unread messages” section after all is cleared saying “🎉 You’ve cauch up on ‘Must’. Jump to the ‘Should’ section”"  />
</p>
<h3 id="questions">❓ Questions</h3>
<h4 id="does-it-mean-that-with-this-you-have-slack-under-control-almost-empty-and-youre-very-responsive">Does it mean that with this you have Slack under control, almost empty, and you’re very responsive?</h4>
<p>Of course not 🙂</p>
<p>Days still go haywire and messages backlog accumulates. And quite often it all becomes chaotic. That’s a consequent of the environments we work in.</p>
<p>With this setup though, I’m able to take care of the most urgent and important messages in those chaotic days. Also, it’s easier to recover from a crazy week without the fear of missing out (<abbr title="Fear Of Missing Out">FOMO</abbr>) some interesting message.</p>
<h4 id="what-about-using-sections-to-organise-and-classify-channels-by-type-scope-urgency-category-etc">What about using sections to organise and classify channels by type, scope, urgency, category, etc.?</h4>
<p>Before, I was using different sections to categorise and classify channels by themes, scope, etc. It was a way to scratch my itch for having everything well organised and in their “right” places.</p>
<p>I stopped doing it because it was getting hard for me to maintain them and was getting lost on too many places to check. There was no easy way to triage what was recent vs old and important vs secondary.</p>
<p>It was a hard to kill all those sections curated with much care, after lots of time invested. This was quite scary to do 😬 but the benefits and simplicity gained from switching to a setup optimised for <em>processing new stuff</em> have more than made up for it.</p>
<h4 id="what-about-the-mobile-app-newest-to-oldest-view">What about the mobile app “Newest to oldest” view?</h4>
<p>This inbox approach started in the Slack mobile app. I switched my channels list to <a href="https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences#sort-your-conversations">sort by “Newest to oldest”</a> (previously called “Recent activity”). This lists updated channels under “Today”, “Yesterday”, and “Last 7 days” groupings.</p>
<p>This change was such huge improvement. I found myself switching from desktop to my smartphone to check Slack messages. I could focus only on the “Today” view and keep up-to-date with what was changing (even if there was some past backlog).</p>
<p>The only drawback was that there was no easy way to distinguish between <em>important</em> vs <em>unimportant</em> channels. Triage of what could wait for later in the “Today” section was only visual.</p>
<p>Shortly after, a colleague shared a similar “timeline” setup of their desktop sidebar. Inspired by it, I decided to take the plunge and experiment with this “Slack as an inbox” setup in both desktop and mobile.</p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_slack-overload-regain-control-with-inbox-activity-7054122110918504448-yqGl">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110220664447192955">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/slack-overload-regain-control-with-inbox-zero-principles-7187fb283664">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1648357045609873408">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://equalexperts.blogin.co/posts/sharing-ways-to-reduce-information-overload-201881#c237802">Equal Experts Blogin</a></li>
<li><a href="https://ios.slack.com/archives/C0721L3CL/p1681834179011219">iOS PT Slack</a></li>
<li><a href="https://springernature.slack.com/archives/C04HV45EZ4H/p1681834348685239?thread_ts=1672850109.129719&amp;cid=C04HV45EZ4H">Springer Nature Slack</a></li>
<li><a href="https://t.me/c/1363309933/8632">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Hearing or listening? Unlock the value of receiving feedback</title>
      <link>https://hugo.ferreira.cc/receiving-feedback/</link>
      <pubDate>Mon, 10 Apr 2023 07:07:28 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/receiving-feedback/</guid>
      <description>Most information on feedback focuses on how to give negative feedback. But what about receiving negative feedback? How better would it be if both ends shared the burden of having productive conversations? Let&amp;rsquo;s put our egos to the side and be emphatic with those who give us criticism, so the burden isn’t on the speaker alone.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/receiving-feedback/ignore-think-target.webp" length="303920" type="image/webp" />
      <content:encoded><![CDATA[<p>Whenever the topic of feedback comes up, the emphasis is usually on how to <em>give feedback</em> in an effective way.</p>
<p>The concerns are also usually about <em>negative feedback</em>. It’s quite easy to give praise or positive feedback to people, since they receive it very well in general.</p>
<p>The internet is full of advice and frameworks to help us shape our message in a way that people receive it well. For example:</p>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Nonviolent_Communication">NVC (Nonviolent Communication)</a></li>
<li><a href="https://www.ccl.org/articles/leading-effectively-articles/sbi-feedback-model-a-quick-win-to-improve-talent-conversations-development/">SBI (Situation-Behavior-Impact)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Praise_sandwich">The feedback sandwich</a></li>
<li>and many others, I’m sure…</li>
</ul>
<p>It makes sense that it is so. It’s a natural psychological reaction for people to become defensive when they are criticised.</p>
<hr>
<p>But what about the other side of the coin, <strong>the way we <em>receive</em> feedback</strong>?</p>
<p>Aren’t we loosing valuable information if the success of <em>negative feedback</em> is only on the speaker?</p>
<p>Won’t some difficult conversations not happen if the burden is only on the person <em>shaping the message</em>?</p>
<p>I, for one, have refrained on occasion from giving <em>negative feedback</em> to people because of that. Sometimes the emotional bandwidth to tone down my initial impulse wasn’t there. Sometimes I didn&rsquo;t have energy to do the mental gymnastics needed to restructure it into a thoughtful message.</p>
<p><strong>Poorly shaped <em>negative feedback</em></strong> can take many common forms:</p>
<ul>
<li>It can be sloppy, too blunt, or even aggressive</li>
<li>Can come from a colleague, a boss, or a client</li>
<li>Someone might think they are better than those around them</li>
<li>In some environments, competition and antagonism can be the norm</li>
</ul>
<p>And yet, there seems to be lack of awareness and interest on how to deal with it.</p>
<p><img loading="lazy" src="google-trends.png" alt="Google Trends chart from 2010 to 2023, showing high interest for &amp;ldquo;giving feedback&amp;rdquo; and around one third of it for &amp;ldquo;receiving feedback&amp;rdquo; and residual for more specifically &amp;ldquo;receiving negative feedback&amp;rdquo;"  />
</p>
<p><a href="https://trends.google.com/trends/explore?date=2010-01-01%202023-03-31&amp;q=%22giving%20feedback%22,%22receiving%20negative%20feedback%22,%22receiving%20feedback%22&amp;hl=en-US">Source</a><br>
<em>(blue = “giving feedback”, yellow = “receiving feedback”, red = “receiving negative feedback”)</em></p>
<hr>
<p>Consider this real example of feedback to a technical proposal, many years ago. At the time, several people pilled on the proposal, with lots of comments received like these:</p>
<blockquote>
<p>This change makes absolutely no sense to me.</p>
</blockquote>
<blockquote>
<p>I’d vote against this immediately! Why not just use [some simplistic alternative] instead?</p>
</blockquote>
<blockquote>
<p>Sure, let’s all do [insert gross exaggeration / ridiculous simplification] from now on.</p>
</blockquote>
<p>What do you think each person was <strong><em>actually</em> saying</strong>?</p>
<p><em>“You’re incompetent. This idea is stupid.”</em></p>
<p>or,</p>
<p><em>“I’m missing the context where this makes sense.”</em></p>
<p>We can interpret both these thoughts from the comments above. The first one is more likely to be the one we latch on (because of our ego, our sense of self-preservation, etc.). Yet, <strong>we get to choose which interpretation</strong> to focus on and respond to.</p>
<hr>
<p>At its core, <strong>feedback is only information</strong>. It’s very easy for emotion and flawed terms to <strong>camouflage</strong> that information, tough.</p>
<p>We can approach the feedback we’re given like detectives or scientists solving an interesting puzzle. Investigate beyond what’s most obvious and uncover the information behind it.</p>
<p><strong>Show <a href="https://www.wired.co.uk/article/tania-singer-compassion-burnout">compassion</a> when we’re on the receiving end</strong> of feedback given in a “bad” way:</p>
<ol>
<li>
<p>🙉 Ignore “intention”, remove “tone”, <strong>strip the message down</strong> to its essence to <strong>put it into perspective</strong></p>
</li>
<li>
<p>🤔 Take the feedback in and relax by thinking <strong>what would it take for you</strong> to be the one saying that</p>
</li>
<li>
<p>🎯 Thank the person for <strong>the essence of their point and consider</strong>, in a factual unemotional manner, what to do with it</p>
</li>
</ol>
<p>One of the core principles of Stoicism can guide us here: the <a href="https://www.njlifehacks.com/what-is-stoicism-overview-definition-10-stoic-principles/#tab-con-3">acceptance of things we cannot control</a>. And we cannot control other people’s words, only ours!</p>
<p>In the words of the ancient Greek philosopher <a href="https://dailystoic.com/Epictetus">Epictetus</a>:</p>
<blockquote>
<p>Remember that it is not he who gives abuse or blows, who affronts, but the view we take of these things as insulting. When, therefore, anyone provokes you, be assured that it is your own opinion which provokes you. Try, therefore, in the first place, not to be bewildered by appearances. For if you once gain time and respite, you will more easily command yourself.</p>
<p>— in <a href="https://www.gutenberg.org/files/45109/45109-h/45109-h.htm#:~:text=XX">The Enchiridion, Section XX</a></p>
</blockquote>
<p>So remember:</p>
<ul>
<li>How you <em><strong>perceive</strong></em> other people’s words has more impact on you than the way people <em><strong>said them</strong></em> or their <em><strong>real intention</strong></em>.</li>
<li>You are <em><strong>in full control</strong></em> of how you interpret what others said and you <em><strong>cannot control</strong></em> how other people say it.</li>
</ul>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_hearing-or-listening-unlock-the-value-of-activity-7051114606546599936-ayz3">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110173632822874183">Mastodon</a></li>
<li><a href="https://medium.com/@hugocf/hearing-or-listening-unlock-the-value-of-receiving-feedback-705b9a09c4a0">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1645348145243488256?s=46&amp;t=CRTJdFXlXcMMriFKo3jM0g">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://ios.slack.com/archives/C0721L3CL/p1681116824485679">iOS PT Slack</a></li>
<li><a href="https://sa-il.slack.com/archives/CQ32FU1SR/p1681227201731269">SA-IL Slack</a></li>
<li><a href="https://t.me/c/1363309933/8552">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 From Chaos to Strategy: Embracing Firefighting at Work</title>
      <link>https://hugo.ferreira.cc/firefighting/</link>
      <pubDate>Mon, 03 Apr 2023 22:16:43 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/firefighting/</guid>
      <description>We use the analogy of firefighting when people handle unexpected problems at work. Instead of reacting in a chaotic manner like civilians, adopt the strategic approach of trained firefighters. This involves having a plan, clarifying roles, training people and practicing together. Doing so, we can create a better culture of preparedness in our companies.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/firefighting/unsplash-firefighter.jpg" length="2638464" type="image/jpeg" />
      <content:encoded><![CDATA[<p>We’ve all heard people say they&rsquo;re in “firefighting mode” or “putting out fires” at work. They mean they’re dealing with unexpected problems and everything feels chaotic. But have you ever thought about <em>why</em> we use the analogy of firefighting for this kind of scenario?</p>
<p>Picture a real life fire. People feel confused, scared, and don&rsquo;t know what to do. They’re stressed and drop everything, scrambling around to deal with the emergency. They disperse their focus and their actions are erratic. Chaos is all around.</p>
<p><img loading="lazy" src="teamwork-chaos.webp" alt="A man standing in an office with a fire in his hand, a woman running on top of a ostrich, a man on top of a desk, and people scrambling everywhere"  />
</p>
<p><em><a href="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExODY4OGIxZTZlNmE1NDgxMTg1NDk0YTY1ZTJiZDZhNGI3ODUyOTMxOSZjdD1n/ZD8ZjehSsLDZQRKJjJ/giphy.gif">Source</a></em></p>
<p>As you can imagine, I don‘t think this is how we should react. What might surprise you is that I don’t think the analogy is wrong. I’d argue though, that we should embrace it even further.</p>
<h2 id="even-firefighting-needs-a-strategy">Even firefighting needs a strategy</h2>
<p><strong>Trained firefighters</strong> make up another crucial group of people in firefighting. Their <em>actions</em> and <em>attitudes</em> are completely different from those described above:</p>
<ul>
<li>They have a well thought out <strong>strategy</strong> for tackling fires, which they adjust to the reality on the ground</li>
<li>They have pre-established <strong>roles</strong> and <strong>communication</strong> lines, so everyone knows what to do</li>
<li>They follow <strong>safety rules</strong> of engagement based on their learnings from past emergencies</li>
<li>They <strong>train</strong> together, in controlled environments simulating reality, to improve their coordination</li>
</ul>
<p>With this, they are ready to handle emergencies with calm and expertise. When fires do occur, they feel “familiar”. Even considering the natural levels of stress and adrenaline involved in these situations.</p>
<p><img loading="lazy" src="teamwork-order.gif" alt="A group of firefighters coordinating together to pass along buckets of water to the top of a ladder"  />
</p>
<p><em><a href="https://www.youtube.com/shorts/UQLUP6PwGRk">Source</a></em></p>
<p>Consider the case of forest fires and how trained firefighters behave when they’re on the scene:</p>
<ul>
<li>Headquarters coordinates efforts based on constant reports from the field</li>
<li>Coordination teams choose where to best deploy their people and physical resources</li>
<li>They take changing context into account (e.g. weather and wind forecasts) to decide which fire fronts to attack first</li>
<li>At times, they even decide which areas to let burn to create a natural barrier for other advancing fires</li>
</ul>
<hr>
<p>So, why can&rsquo;t we operate in a similar way in our companies? Why are we in constant in firefighting mode, reacting to emergencies as they arise?</p>
<p>We can choose to look at “firefighting” in a strategic way. We can seek to act like “trained firefighters”, rather than in a chaotic way like “civilians”:</p>
<ul>
<li><strong>Have a plan</strong> in place for handling unexpected problems</li>
<li>Make sure people <strong>understand their role</strong> in responding to unexpected challenges</li>
<li><strong>Train</strong> people on <strong>how to respond</strong> to crises in a calm and efficient manner</li>
<li><strong>Practice</strong> how to <strong>work together</strong> to find solutions in emergencies</li>
</ul>
<p>This way we can create a better culture of preparedness in our companies. Like trained firefighters, we can be ready to handle whatever challenges come our way.</p>
<p>So, the next time you find yourself in firefighting mode at work, remember that you have a choice. Don’t react in a chaotic manner, like a civilian in a fire. <strong>Be strategic like a trained firefighter.</strong></p>
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://www.linkedin.com/posts/hugocf_from-chaos-to-strategy-embracing-firefighting-activity-7048651523198754817-ZODQ">LinkedIn</a></li>
<li><a href="https://mastodon.online/@hugocf/110142785028504109">Mastodon</a></li>
<li><a href="https://hugocf.medium.com/from-chaos-to-strategy-embracing-firefighting-at-work-1ec65a6be852">Medium</a></li>
<li><a href="https://twitter.com/hugocf/status/1642784438873407489">Twitter</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://ios.slack.com/archives/C0721L3CL/p1680511769840369">iOS PT Slack</a></li>
<li><a href="https://sa-il.slack.com/archives/CQ32FU1SR/p1680539980852139">SA-IL Slack</a></li>
<li><a href="https://t.me/c/1363309933/8513">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Thermal throttling: “Gone in a cloud of dust”</title>
      <link>https://hugo.ferreira.cc/thermal-throttling/</link>
      <pubDate>Fri, 12 Aug 2022 22:16:16 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/thermal-throttling/</guid>
      <description>When no matter how much you treat some problems as a “software” issue, there’s no escaping the “hardware” truth.</description>
      <content:encoded><![CDATA[<p>For a long time now, my company assigned <strong>MacBook Pro</strong> based with <strong>Intel Core i7</strong> silicon, had been having weird thermal throttling behaviours.</p>
<p>More often than not, when doing <strong>Google Meet</strong> calls on <strong>Chrome</strong>, sharing screen, and/or opening large <strong>Miro</strong> boards, the computer would start getting slower and slower, to the point of becoming completely useless.</p>
<p>Opening <strong>Activity Monitor</strong> would show the dreaded <code>kernel_task</code> taking a huge percentage of CPU  time.</p>
<figure><a href="https://www.davidschlachter.com/misc/kernel_task">
    <img loading="lazy" src="kernel_task.png"
         alt="Screenshot of macOS “Activity Monitor” showing a “kernel task” process taking 254% of CPU"/> </a><figcaption>
            <p>Example of <strong>Activity Monitor</strong> with a spiking <code>kernel_task</code> process
                    <a href="https://www.davidschlachter.com/misc/kernel_task">(source)</a></p>
        </figcaption>
</figure>

<p><strong>macOS</strong> uses <code>kernel_task</code> to <a href="https://support.apple.com/en-us/102172">help manage CPU temperature by making the CPU less available to processes that are using it intensely</a>. This means that what <strong>Activity Monitor</strong> shows is only a “symptom”, not the cause of the “disease”.</p>
<hr>
<p>I installed <a href="https://crystalidea.com/macs-fan-control"><strong>Macs Fan Control</strong></a> and for a while was monitoring the fans behaviour like a hawk.</p>
<p>It became clear that even forcing the fans to work full blast all the time, the thermal throttling would still happen in an all too regular basis.</p>
<p>With all the software solutions exhausted (app upgrades, clearing caches, full restarts, safe mode, etc.) and a similar report of clogged fans by a colleague, it was time to gain the courage to open up the laptop and inspect the fans directly.</p>
<p>Thanks to the wonderful <a href="https://www.ifixit.com/Device/MacBook_Pro"><strong>iFixIt</strong> guides</a>, the task was a fairly simple one <a href="https://www.ifixit.com/Guide/MacBook+Pro+16-Inch+2019+Lower+Case+Replacement/135013">for that particular model</a>.</p>
<hr>
<p>The results were striking and these images speak more loudly that any words could ever do:</p>
<p><em><strong>Before</strong></em></p>
<table>
<thead>
<tr>
<th>Left fan</th>
<th>Right fan</th>
</tr>
</thead>
<tbody>
<tr>
<td><img loading="lazy" src="left-fan-before.jpg" alt="left mackbook pro fan clogged up with dust, blocking all of the air flow dividers"  />
</td>
<td><img loading="lazy" src="right-fan-before.jpg" alt="right mackbook pro fan clogged up with dust, blocking all of the air flow dividers"  />
</td>
</tr>
</tbody>
</table>
<p><em><strong>After</strong></em><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
<table>
<thead>
<tr>
<th>Left fan</th>
<th>Right fan</th>
</tr>
</thead>
<tbody>
<tr>
<td><img loading="lazy" src="left-fan-after.jpg" alt="left mackbook pro fan completely clean with the air dividers visible"  />
</td>
<td><img loading="lazy" src="right-fan-after.jpg" alt="right mackbook pro fan completely clean with the air dividers visible"  />
</td>
</tr>
</tbody>
</table>
<p>Suffice to say that it works and feels like a brand new laptop now. 🎉</p>
<!-- TODO: Review captions format -->
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>The recommended way to clean these fans is <a href="https://superuser.com/a/199540/54980">using a spray can of compressed air</a>. In my particular case, having none of those around, I used a <a href="tools.jpg">very low suction portable vacuum and a small brush</a> (to loosen the harder bits) but please follow the recommendations due to the risk of damaging the fans (if the air flow causes them to spin too fast) or other electronic components (from the static electricity generated).&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Histórias curtas</title>
      <link>https://hugo.ferreira.cc/historias-curtas/</link>
      <pubDate>Thu, 16 Jul 2020 22:16:49 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/historias-curtas/</guid>
      <description>&lt;p&gt;Pequenas &lt;strong&gt;histórias de 6 palavras&lt;/strong&gt; são inspiradas num famoso desafio colocado ao escritor Hernest Hemingway.&lt;/p&gt;</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/historias-curtas/baby-shoes.webp" length="171034" type="image/webp" />
      <content:encoded><![CDATA[<p>Pequenas <strong>histórias de 6 palavras</strong> são inspiradas num famoso desafio colocado ao escritor Hernest Hemingway.</p>
<p>A história que ele criou foi esta:</p>
<blockquote>
<p><strong>For sale: baby shoes, never worn.</strong><br>
<em>(Vende-se: sapatos de bebés, nunca usados.)</em></p>
<p>— Hernest Hemingway</p>
</blockquote>
<p>Criar estas histórias é um bom exercício de “storytelling”, útil para “quebrar gelo”, vencer a síndrome da “página em branco” e fazer os fluidos criativos começarem a correr.</p>
<p>O desafio partiu de um <a href="https://www.instagram.com/p/CCqXf40s28T/">post no Instagram do Virgílio Varela</a>, onde explica o formato e propõe alguns exemplos:</p>
<blockquote>
<p>O que é fantástico é que não precisamos dizer tudo para criar uma história inesperada e surpreendente.</p>
<p><em>“Estranhos, melhores amigos, amantes, estranhos.”</em></p>
<p><em>“Fugi pra floresta, fui dentro, encontrei-me.”</em></p>
<p><em>“Casei-me A minha mãe tinha razão…”</em></p>
<p><em>“Ele pediu desculpas. Ela não aceitou.”</em></p>
<p>🗣️ Partilha aqui as tuas histórias de 6 palavras!</p>
</blockquote>
<hr>
<p>Por algum motivo o desafio ficou-me na cabeça, e assim sendo, aqui seguem as minhas modestas contribuições:</p>
<blockquote>
<p>“Vem à aventura”. Morreu dias depois. <a href="https://www.instagram.com/p/CCqXf40s28T/c/17872566445791198/r/17851392131169721/">🔗</a></p>
</blockquote>
<blockquote>
<p>Tudo correu mal. Que grande alívio! <a href="https://www.instagram.com/p/CCqXf40s28T/c/17872566445791198/r/17847657785204137/">🔗</a></p>
</blockquote>
<blockquote>
<p>Bateu no inimigo. Partiu-se o espelho. <a href="https://www.instagram.com/p/CCqXf40s28T/c/17872566445791198/r/17843675342288274/">🔗</a></p>
</blockquote>
<p>Estilo “adivinha”: 😉</p>
<blockquote>
<p>Não há. Só temos…<br>
Pode ser. <a href="https://www.instagram.com/p/CCqXf40s28T/c/17872566445791198/r/17845664900274921/">🔗</a></p>
</blockquote>
<p>“Hacking the format”: 😏</p>
<blockquote>
<p>Era uma vez … felizes para sempre. <a href="https://www.instagram.com/p/CCqXf40s28T/c/17872566445791198/r/17868658474896311/">🔗</a></p>
</blockquote>
<hr>
<p>Que histórias curtas consegues inventar com 6 palavras apenas?</p>
<p><strong>É a tua vez…</strong></p>]]></content:encoded>
    </item>
    <item>
      <title>💭 Working from ~~Home~~ Hell</title>
      <link>https://hugo.ferreira.cc/wfhell/</link>
      <pubDate>Fri, 27 Mar 2020 22:17:05 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/wfhell/</guid>
      <description>After 15 days of confinement due to COVID-19, with 2 adults working and 3 children attending school remotely, “WFH” is standing more closely to “Working from &lt;strong&gt;Hell&lt;/strong&gt;” than “Working from &lt;em&gt;Home&lt;/em&gt;”. 😱</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/wfhell/work-from-hell.png" length="2185853" type="image/png" />
      <content:encoded><![CDATA[<p>Let me give you a sneak peak of my past 15 days in COVID-19 induced confinement, “working from home”. 👀</p>
<p>Yesterday I kept a pen and paper always by my side and noted the times of what happened during the day. ✍️</p>
<p>In summary, got some focused periods here and there 👨‍💻 but the interruptions ❌ are killing me slowly. Handling them can take anywhere from 2 to 20 mins.</p>
<p>To be honest, this was a pretty typical day, similar to most other lockdown days. Not exaggerating at all, unfortunately. 😩</p>
<blockquote>
<p><strong>Repeat after me</strong>: This has <em>nothing</em> to do with working remotely!</p>
</blockquote>
<hr>
<p>▶️ 🚦 Sit down to work</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>11 min</strong> of work</p>
<p>❌ 🤔 Wife: “So how are we planning lunch and shopping today?”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>38 min</strong> of work</p>
<p>❌ 💡 Wife: “I’ve had another idea for lunch and shopping”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>41 min</strong> of work</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 📆 A few scheduled meetings</p>
<p>⏸️ 🛒 Local market shopping</p>
<p>⏸️ 🛍️ Pick up take away food</p>
<p>⏸️ 🚗 Deliver shopping to in-laws</p>
<p>⏸️ 🍽️ Family lunch</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>15 min</strong> of work</p>
<p>❌ 💻 Daughter: “Daddy, the online lessons’ screen is frozen, I can’t type!”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>45 min</strong> of work</p>
<p>❌ 🗣️ Daughter: “Daddy, Z. wants to talk to you” <em>[a relative who’s a teacher and is helping my daughter on occasion]</em></p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>19 min</strong> of work</p>
<p>❌ 😭 Daughter: “DAD, my brother R. is accusing me of farting. WITHOUT EVIDENCE! And I didn’t do it!”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>2 min</strong> of work</p>
<p>❌ 😱 Son R: “MOM, DAD, my sister is chewing with her mouth open!!!”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>6 min</strong> of work</p>
<p>❌ 😢 Daughter: “DAD, my brothers don’t make room for me to stay in front of the laptop camera” <em>[while zoom calling with their cousins]</em></p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>6 min</strong> of work</p>
<p>❌ 💻 Son R.: “Daddy, T. made the zoom window disappear and we can’t find it anymore”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>22 min</strong> of work</p>
<p>❌ ⚽️ Son R.: “Daddy, you promised yesterday to play football in the living room with us!”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “Ok, let me just finish something here…”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>8 min</strong> of work</p>
<p>❌ ⚽️ Son T.: “Daddy, are you coming or not?!”</p>
<img style="margin-left: 1.5rem" src="https://emojis.slackmojis.com/emojis/images/1643514342/3164/table_flip.png" alt="Table flip">
<p><span style="display: inline-block; width: 1.5rem"></span> 🥅 Me: “FINE. I’m the goalie!”</p>
<p>⏸️ 🍽️ Family dinner</p>
<p>⏸️ <img style="display: inline-block; vertical-align: middle; height: 1.5rem; margin: auto" src="https://emojis.slackmojis.com/emojis/images/1643514041/5/sheepy.gif" alt="Jumping sheep"> Herding children to get them ready for bed</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>15 min</strong> of work</p>
<p>❌ 🗣️ Wife: “Are you putting the kids to bed?”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “Finishing something here, can you do it please?”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>12 min</strong> of work</p>
<p>❌ 🗣️ Wife: “The kids are in bed”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “Ok, coming soon”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>19 min</strong> of work</p>
<p>❌ 😱 Wife: “THE KIDS ARE IN BED!”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “OK! FINE!!!” 🙄</p>
<p>⏸️ 🛌 Goodnight to kids</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>5 min</strong> of work</p>
<p>❌ 💻 Wife: “Can you help me figure out something here with the computer!”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “Ok, ok… Just a sec!”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>7 min</strong> of work</p>
<p>❌ 🗣️ Wife: “About that computer thing, never mind, I’ve sorted it”<br>
<span style="display: inline-block; width: 1.5rem"></span> <span style="display: inline-block; width: 1.5rem"></span> Me: “Oh… hum… ok…” <img style="display: inline-block; vertical-align: middle; height: 1.5rem; margin: auto" src="https://emojis.slackmojis.com/emojis/images/1643514112/722/sigh.gif" alt="Sigh"></p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>50 min</strong> of work</p>
<p>❌ 👁️ Wife: “Have you read that email from the kids teacher?”</p>
<p><span style="display: inline-block; width: 1.5rem"></span> 👨‍💻 <strong>21 min</strong> of work</p>
<p>⏹️ 🫠 <em>(enough for the day)</em></p>
<img style="margin-left: 1.5rem" src="https://emojis.slackmojis.com/emojis/images/1643514169/1340/try_not_to_cry.gif" alt="Try not to cry: person rocking on the flow huging their knees ">
<hr>
<details>
<summary>Shared to…</summary>
<ul>
<li><a href="https://hugocf.medium.com/working-from-hell-b6d2e371cf0e">Medium</a></li>
</ul>
<p>🔒 <em>(groups)</em></p>
<ul>
<li><a href="https://t.me/c/1363309933/9341">Telegram</a></li>
</ul>
</details>
]]></content:encoded>
    </item>
    <item>
      <title>💭 PHP shenanigans</title>
      <link>https://hugo.ferreira.cc/php-shenanigans/</link>
      <pubDate>Mon, 15 Apr 2019 00:46:48 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/php-shenanigans/</guid>
      <description>&lt;p&gt;Pop quiz about &lt;a href=&#34;https://www.php.net/&#34;&gt;PHP&lt;/a&gt; and something we’ve stumbled upon last week, while working on a client’s codebase.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Pop quiz about <a href="https://www.php.net/">PHP</a> and something we’ve stumbled upon last week, while working on a client’s codebase.</p>
<p>Given the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Foo</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">public</span> <span class="nv">$bar</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bar</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">$a</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Foo</span><span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nv">$b</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Foo</span><span class="p">(</span><span class="s1">&#39;b&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nv">$c</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Foo</span><span class="p">(</span><span class="s1">&#39;c&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">$result</span> <span class="o">=</span> <span class="nx">array_diff</span><span class="p">(</span> <span class="p">[</span><span class="nv">$a</span><span class="p">,</span> <span class="nv">$b</span><span class="p">,</span> <span class="nv">$c</span><span class="p">],</span> <span class="p">[</span><span class="nv">$a</span><span class="p">,</span> <span class="nv">$b</span><span class="p">]</span> <span class="p">);</span>
</span></span></code></pre></div><p>What would you <em>expect</em> the result to be?</p>
<p>1️⃣ <code>Array( )</code><br>
2️⃣ <code>Array( [0] =&gt; Foo( [bar] =&gt; c ) )</code><br>
3️⃣ <code>Array( [2] =&gt; Foo( [bar] =&gt; c ) )</code><br>
4️⃣ <code>Object of class Foo could not be converted to string</code></p>
<p>I’ll give you some moments to think it over…</p>
<hr>

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
  <iframe src="https://www.youtube.com/embed/S3wsCRJVUyg?rel=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="More moments later…"></iframe>
</div>

<hr>

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
  <iframe src="https://www.youtube.com/embed/u3UtCnXG2io?rel=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="More moments later…"></iframe>
</div>

<hr>
<p>“Obviously” [not 🙄] the right answer is option <strong>4</strong> …</p>
<blockquote>
<p>4️⃣ <code>Object of class Foo could not be converted to string</code></p>
</blockquote>
<p>… because for the <a href="https://www.php.net/manual/en/function.array-diff.php"><code>array_diff</code></a> function …</p>
<blockquote>
<p>Two elements are considered equal if and only if <code>(string) $elem1 === (string) $elem2</code>. That is, when the <a href="https://www.php.net/manual/en/language.types.string.php#language.types.string.casting">string representation</a> is the same.</p>
</blockquote>
<p>… and, adding insult to injury, objects <em><strong>don’t</strong> have a default</em> string representation.</p>
<p>😱 🤦‍♂️ x 100</p>
<iframe src="https://giphy.com/embed/wj8VEUZVVEuls6pOw7" width="480" height="480" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
<hr>
<p>Funnily enough [not at all 😤] implementing the string conversion magic method …</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="k">public</span> <span class="k">function</span> <span class="fm">__toString</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">bar</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>… then option <strong>3</strong> becomes the answer …</p>
<blockquote>
<p>3️⃣ <code>Array( [2] =&gt; Foo( [bar] =&gt; c ) )</code></p>
</blockquote>
<p>… because “arrays” in PHP don’t exist and, in reality, are nothig more than key-value maps in disguise, with the index numbers as the keys. 😕</p>
<p>This means you&rsquo;d need to wrap it all around an <a href="https://www.php.net/manual/en/function.array-values.php"><code>array_values</code></a> call to “reset” all the <del>indexes</del> keys of the <del>array</del> map back to zero.</p>
<iframe src="https://giphy.com/embed/zBZk5FD18QhjP35Goa" width="480" height="480" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
<hr>
<p>Guess I need to make this old article my new bed time reading, to read over and over and over again: <a href="https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/">PHP: a fractal of bad design / fuzzy notepad</a></p>]]></content:encoded>
    </item>
    <item>
      <title>💭 Educating security</title>
      <link>https://hugo.ferreira.cc/educating-security/</link>
      <pubDate>Mon, 18 Mar 2019 22:16:38 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/educating-security/</guid>
      <description>A real story of how following good security practices is both easier to do than ad-hoc methods, and it spreads quickly to others.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/educating-security/chalk-board.png" length="2258007" type="image/png" />
      <content:encoded><![CDATA[<p><em>For a bit of context…</em></p>
<p>In 2018, the <a href="https://www.linkedin.com/in/hugocf/">company I’m working in</a> decided to rollout <a href="https://1password.com/business">1Password Business</a> to all employees, which includes ​free <a href="https://1password.com/personal">family accounts​</a> for personal usage.</p>
<p>I had heard about 1Password before but thought of it as just one more password manager amongst many. For my needs, the default solutions bundled in browsers and operating systems were more than enough.</p>
<p>Last year I got the chance of using 1Password with a Team Vault for work (in a project for a client). It gave me the hands-on experience of how powerful the software is and the wide range of possibilities it gives, but I paid no more attention to it.</p>
<hr>
<p>Fast forward to February 2019, when my two 10 year old twins brought home their new school assigned tablets. With them, along came the usual myriad of access credentials for school email accounts, digital books and resources, online classroom forums, etc.</p>
<p>Both their devices and access credentials came predefined with default rules for passwords, like <code>​[school process number][first name]​</code> (e.g. <code>​12345hugo​</code>) — quite convenient for those setting up the devices, right?</p>
<p>Students’ full names and process numbers are posted in the school lobby for all to see at the beginning of the school year. It shows who was placed in that school and in which class.</p>
<p>This means that, if not changed, everyone knows everyone else’s passwords! 😱</p>
<p>Security wise, an <em><strong>appalling</strong></em> default practice.</p>
<hr>
<blockquote>
<p>As the twig is bent, so is the tree inclined</p>
</blockquote>
<p>I’m a firm beliver that security cannot be an afterthought and it needs to be ​designed and built-in right from the start​.</p>
<p>“No way”, I thought as a parent. “They are going learn good security practices from the start…”</p>
<p>“So, what was this ‘1Password Family plan’ thing again? 🤔”</p>
<p>A few hours spent on a weekend exploring it and not very long after I had each one of them setup with:</p>
<ol>
<li>Their own vault on their tablets with auto-generated credentials for all the school services</li>
<li>Another shared vault with the family stuff (e.g. home wifi password)</li>
<li>A chosen strong and long master password made up of words of “things they like” (inspired by <a href="https://xkcd.com/936/">​xkcd: Password Strength​</a>)</li>
</ol>
<hr>
<p>That same week, arriving from school, one of my kids asked:</p>
<p>— “How can we setup and install this vaults thing?”<br>
— “Why do you want to know?”<br>
— “To tell my friends. They saw me using it and also want it, but their parents don’t know how to do it” 😁</p>
<p><strong>Planting a seed</strong> and <strong>leading by example</strong>, two of the most effective ways of driving change, displayed here in practice in the real world.</p>
<p><em>(So, anyone know a simple ​“1Password: Getting Started Guide for Kids”​ that I can translate to Portuguese and have them send their friends?)</em> 😉</p>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Scala Enumerations Summary</title>
      <link>https://hugo.ferreira.cc/scala-enums/</link>
      <pubDate>Sun, 14 May 2017 12:47:21 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/scala-enums/</guid>
      <description>Comparison between different ways of doing enumerates, with &lt;code&gt;scala.Enumeration&lt;/code&gt;, &lt;code&gt;case object&lt;/code&gt; and Java’s &lt;code&gt;Enum&lt;/code&gt;.</description>
      <content:encoded><![CDATA[<p><em><strong>Update 2017-07-01</strong>: <a href="https://github.com/lampepfl/dotty/issues/1970">“Add enum construct”</a> is a new proposal by Martin Odersky to add the keyword <code>enum</code> to Dotty, which might render many of these considerations irrelevant.</em></p>
<p>Quite often the topic of how to do enumerations in Scala pops up in internal discussions at work, and more
often than not I found myself referring back to the same bookmarks and revisiting the pros &amp; cons of different techniques.</p>
<p>I believe there are no such things as <em>advantages</em> or <em>disadvantages</em>. What we have are <em>characteristics</em> being interpreted under a certain <em>context</em>, which makes them shine in a positive or negative light.</p>
<p>This post summarises the <strong>characteristics</strong> of the 3 most common ways of making enumerations in Scala, hoping it helps you make the choices and <strong>tradeoffs</strong>  that are more suitable for your particular use case:</p>
<ul>
<li>Abstract class <a href="http://www.scala-lang.org/api/current/index.html#scala.Enumeration"><strong><code>scala.Enumeration</code></strong></a></li>
<li>Algebraic data types with <a href="http://stackoverflow.com/a/26690131/1380781"><strong><code>case object|class</code></strong></a> extending a <code>sealed trait</code></li>
<li>Java <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html"><strong><code>Enum</code></strong></a></li>
</ul>
<p>There are several libraries out there which add enumeration capabilities with different characteristics, but I’m only interested in what is possible to do out of the box with plain vanilla Scala, and keeping things as simple as possible.</p>
<h2 id="references--sources">References &amp; Sources</h2>
<p>If you want to explore further, these were the key references and sources used in this post…</p>
<p>Undersore:</p>
<ul>
<li><a href="http://underscore.io/blog/posts/2014/09/03/enumerations.html">Scala Enumerations - Underscore</a></li>
<li><a href="http://underscore.io/blog/posts/2015/06/02/everything-about-sealed.html">Everything You Ever Wanted to Know About Sealed Traits in Scala - Underscore</a></li>
<li><a href="http://underscore.io/blog/posts/2015/06/04/more-on-sealed.html">More on Sealed Traits in Scala - Underscore</a></li>
</ul>
<p>StackOverflow:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/1898932/case-objects-vs-enumerations-in-scala">Case objects vs Enumerations in Scala - Stack Overflow</a></li>
<li><a href="http://stackoverflow.com/questions/28589022/enumeration-concept-in-scala-which-option-to-take">Enumeration concept in Scala - Which option to take? - Stack Overflow</a></li>
<li><a href="http://stackoverflow.com/questions/26689951/writing-algebraic-data-type-in-scala">Writing Algebraic Data Type in Scala - Stack Overflow</a></li>
</ul>
<p>Spaghetti and Hammers:</p>
<ul>
<li><a href="http://pedrorijo.com/blog/scala-enums/">Scala Enumerations - Part 1</a></li>
<li><a href="http://pedrorijo.com/blog/scala-enums-part2/">Scala Enumerations - Return of the (Java) Jedi</a></li>
</ul>
<h2 id="what-do-they-give-you">What do they give you?</h2>
<ul>
<li>✅ Fully supported out of the box or straightforward to do</li>
<li>⚠️ Has workaround but at the cost of boilerplate code or manual work</li>
<li>⛔️ Not supported or too cumbersome to use</li>
</ul>
<table>
<thead>
<tr>
<th>Topic</th>
<th>Characteristic</th>
<th style="text-align:center">Scala <code>scala.Enumeration</code></th>
<th style="text-align:center">Scala <code>case object</code></th>
<th style="text-align:center">Java <code>Enum</code></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Customizable</strong></td>
<td>Support custom data fields other than “name” and “index”</td>
<td style="text-align:center">⚠️</td>
<td style="text-align:center">⚠️</td>
<td style="text-align:center">⚠️</td>
</tr>
<tr>
<td><strong>Indexed</strong></td>
<td>Items have a consecutive incremental numeric value</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Indexed</strong></td>
<td>Items can be retrieved via their index</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Ordered</strong></td>
<td>Enum items naturally ordered according to their index<br>(Item1 &lt; Item2)</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Iterable</strong></td>
<td>Capable of iterating over the enum items as a collection</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⚠️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Pattern Matching</strong></td>
<td>Ability to do pattern matching on the items</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Pattern Matching</strong></td>
<td>Compile time warning about <em>exhaustive pattern matching</em></td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Serialization</strong></td>
<td>Each enum item has an associated “name” value<br>(Item ➔ <code>String</code>)</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Serialization</strong></td>
<td>Instantiate an enum item from a “name”<br>(<code>String</code> ➔ Item)</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⚠️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Types</strong></td>
<td>Items are instances of the enumeration, not separate classes</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Types</strong></td>
<td>Has distinct type after type erasure (i.e. can be used for method overloading)</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
<td style="text-align:center">✅</td>
</tr>
<tr>
<td><strong>Interop</strong></td>
<td>Ease of use in mixed Scala/Java projects</td>
<td style="text-align:center">⚠️</td>
<td style="text-align:center">⛔️</td>
<td style="text-align:center">✅</td>
</tr>
</tbody>
</table>
<h2 id="how-to-declare-them">How to declare them?</h2>
<p>This uses the simplest example of <code>WeekDays</code> (with <em>index</em> for Monday starting at 1) whenever possible. When manual customizations are needed to implement a certain feature, those are illustrated in <code>CustomEnum</code>.</p>
<p>💻 <strong>All code and tests below are available for download in the <a href="https://github.com/hugocf/scala-enums"><code>scala-enums</code></a> GitHub repo.</strong></p>
<h3 id="scalaenumeration"><code>scala.Enumeration</code></h3>
<p>Simple version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="c1">// file: enumeration/WeekDay.scala
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">object</span> <span class="nc">WeekDay</span> <span class="k">extends</span> <span class="nc">Enumeration</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">type</span> <span class="kt">WeekDay</span> <span class="o">=</span> <span class="nc">Value</span>
</span></span><span class="line"><span class="cl">  <span class="k">val</span> <span class="nc">Mon</span><span class="o">,</span> <span class="nc">Tue</span><span class="o">,</span> <span class="nc">Wed</span><span class="o">,</span> <span class="nc">Thu</span><span class="o">,</span> <span class="nc">Fri</span><span class="o">,</span> <span class="nc">Sat</span><span class="o">,</span> <span class="nc">Sun</span> <span class="k">=</span> <span class="nc">Value</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>With tweaks for customizable fields:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="c1">// file: enumeration/CustomEnum.scala
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">object</span> <span class="nc">CustomEnum</span> <span class="k">extends</span> <span class="nc">Enumeration</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">type</span> <span class="kt">CustomEnum</span> <span class="o">=</span> <span class="nc">Value</span>
</span></span><span class="line"><span class="cl">  <span class="k">val</span> <span class="nc">Foo</span> <span class="k">=</span> <span class="nc">CustomEnumVal</span><span class="o">(</span><span class="s">&#34;This is a foo&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">val</span> <span class="nc">Bar</span> <span class="k">=</span> <span class="nc">CustomEnumVal</span><span class="o">(</span><span class="s">&#34;This is a bar&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">val</span> <span class="nc">Baz</span> <span class="k">=</span> <span class="nc">CustomEnumVal</span><span class="o">(</span><span class="s">&#34;This is a baz&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">protected</span> <span class="k">case</span> <span class="k">class</span> <span class="nc">CustomEnumVal</span><span class="o">(</span><span class="n">custom</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Val</span>
</span></span><span class="line"><span class="cl">  <span class="k">implicit</span> <span class="k">def</span> <span class="n">convert</span><span class="o">(</span><span class="n">value</span><span class="k">:</span> <span class="kt">Value</span><span class="o">)</span><span class="k">:</span> <span class="kt">CustomEnumVal</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">asInstanceOf</span><span class="o">[</span><span class="kt">CustomEnumVal</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><h3 id="case-object"><code>case object</code></h3>
<p>Simple version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="c1">// file: caseobject/WeekDay.scala
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">object</span> <span class="nc">WeekDay</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">sealed</span> <span class="k">trait</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Mon</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Tue</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Wed</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Thu</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Fri</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Sat</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Sun</span> <span class="k">extends</span> <span class="nc">WeekDay</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>With tweaks for customizable fields, indexing, ordering, iteration, and serialization:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="c1">// file: caseobject/CustomEnum.scala
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">object</span> <span class="nc">CustomEnum</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">CustomEnum</span><span class="o">(</span><span class="k">val</span> <span class="n">order</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="k">val</span> <span class="n">custom</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">CustomEnum</span><span class="o">]</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">def</span> <span class="n">compare</span><span class="o">(</span><span class="n">that</span><span class="k">:</span> <span class="kt">CustomEnum</span><span class="o">)</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="n">order</span> <span class="o">-</span> <span class="n">that</span><span class="o">.</span><span class="n">order</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Foo</span> <span class="k">extends</span> <span class="nc">CustomEnum</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="s">&#34;This is a foo&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Bar</span> <span class="k">extends</span> <span class="nc">CustomEnum</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="s">&#34;This is a bar&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">object</span> <span class="nc">Baz</span> <span class="k">extends</span> <span class="nc">CustomEnum</span><span class="o">(</span><span class="mi">3</span><span class="o">,</span> <span class="s">&#34;This is a baz&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">object</span> <span class="nc">CustomEnum</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="n">all</span> <span class="k">=</span> <span class="nc">Seq</span><span class="o">(</span><span class="nc">Foo</span><span class="o">,</span> <span class="nc">Bar</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="n">withOrder</span><span class="o">(</span><span class="n">o</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">CustomEnum</span><span class="o">]</span> <span class="k">=</span> <span class="n">all</span><span class="o">.</span><span class="n">find</span><span class="o">(</span><span class="k">_</span><span class="o">.</span><span class="n">order</span> <span class="o">==</span> <span class="n">o</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="n">withName</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">CustomEnum</span><span class="o">]</span> <span class="k">=</span> <span class="n">all</span><span class="o">.</span><span class="n">find</span><span class="o">(</span><span class="k">_</span><span class="o">.</span><span class="n">toString</span> <span class="o">==</span> <span class="n">n</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><h3 id="java-enum">Java <code>Enum</code></h3>
<p>Simple version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// file: javaenum/WeekDay.java</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">enum</span><span class="w"> </span><span class="n">WeekDay</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">MON</span><span class="p">,</span><span class="w"> </span><span class="n">TUE</span><span class="p">,</span><span class="w"> </span><span class="n">WED</span><span class="p">,</span><span class="w"> </span><span class="n">THU</span><span class="p">,</span><span class="w"> </span><span class="n">FRI</span><span class="p">,</span><span class="w"> </span><span class="n">SAT</span><span class="p">,</span><span class="w"> </span><span class="n">SUN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>With tweaks for customizable fields:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// file: javaenum/CustomEnum.java</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">enum</span><span class="w"> </span><span class="n">CustomEnum</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">FOO</span><span class="p">(</span><span class="s">&#34;This is a foo&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">BAR</span><span class="p">(</span><span class="s">&#34;This is a bar&#34;</span><span class="p">),</span><span class="w"> </span><span class="n">BAZ</span><span class="p">(</span><span class="s">&#34;This is a baz&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">custom</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">CustomEnum</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">value</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">this</span><span class="p">.</span><span class="na">custom</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">value</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h2 id="usage-examples">Usage Examples</h2>
<h3 id="customizable-support-custom-data-fields-other-than-name-and-index">Customizable: Support custom data fields other than “name” and “index”</h3>
<p><strong>⚠️ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Foo</span><span class="o">.</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span></code></pre></div><p><strong>⚠️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Foo</span><span class="o">.</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span></code></pre></div><p><strong>⚠️ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">FOO</span><span class="o">.</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span></code></pre></div><h3 id="indexed-items-have-a-consecutive-incremental-numeric-value">Indexed: Items have a consecutive incremental numeric value</h3>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span><span class="o">.</span><span class="n">id</span> <span class="n">shouldBe</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span><span class="o">.</span><span class="n">id</span> <span class="n">shouldBe</span> <span class="mi">7</span>
</span></span></code></pre></div><p><strong>⛔️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Foo</span><span class="o">.</span><span class="n">order</span> <span class="n">shouldBe</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"><span class="nc">Bar</span><span class="o">.</span><span class="n">order</span> <span class="n">shouldBe</span> <span class="mi">2</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<p>The initial constant position in the enum declaration is assigned a fixed ordinal of 0 (zero).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">MON</span><span class="o">.</span><span class="n">ordinal</span> <span class="n">shouldBe</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"><span class="nc">SUN</span><span class="o">.</span><span class="n">ordinal</span> <span class="n">shouldBe</span> <span class="mi">6</span>
</span></span></code></pre></div><h3 id="indexed-items-can-be-retrieved-via-their-index">Indexed: Items can be retrieved via their index</h3>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="n">the</span> <span class="o">[</span><span class="kt">NoSuchElementException</span><span class="o">]</span> <span class="n">thrownBy</span> <span class="nc">WeekDay</span><span class="o">(</span><span class="mi">0</span><span class="o">)</span> <span class="n">should</span> <span class="n">have</span> <span class="n">message</span> <span class="s">&#34;key not found: 0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Mon</span>
</span></span><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">(</span><span class="mi">7</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Sun</span>
</span></span></code></pre></div><p><strong>⛔️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withOrder</span><span class="o">(</span><span class="mi">0</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">None</span>
</span></span><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withOrder</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Some</span><span class="o">(</span><span class="nc">Foo</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withOrder</span><span class="o">(</span><span class="mi">2</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Some</span><span class="o">(</span><span class="nc">Bar</span><span class="o">)</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">values</span><span class="k">:</span> <span class="kt">Array</span><span class="o">[</span><span class="kt">WeekDay</span><span class="o">]</span> <span class="k">=</span> <span class="nc">WeekDay</span><span class="o">.</span><span class="n">values</span><span class="o">()</span>  <span class="c1">// every call returns a newly cloned array
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">values</span><span class="o">(</span><span class="mi">0</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">MON</span>
</span></span><span class="line"><span class="cl"><span class="n">values</span><span class="o">(</span><span class="mi">6</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">SUN</span>
</span></span><span class="line"><span class="cl"><span class="n">the</span> <span class="o">[</span><span class="kt">ArrayIndexOutOfBoundsException</span><span class="o">]</span> <span class="n">thrownBy</span> <span class="n">values</span><span class="o">(</span><span class="mi">7</span><span class="o">)</span> <span class="n">should</span> <span class="n">have</span> <span class="n">message</span> <span class="s">&#34;7&#34;</span>
</span></span></code></pre></div><h3 id="ordered-enum-items-naturally-ordered-according-to-their-index">Ordered: Enum items naturally ordered according to their index</h3>
<p><strong>✅️️ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span> <span class="o">&lt;</span> <span class="nc">Tue</span> <span class="n">shouldBe</span> <span class="kc">true</span>
</span></span></code></pre></div><p><strong>⛔️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Foo</span> <span class="o">&lt;</span> <span class="nc">Bar</span> <span class="n">shouldBe</span> <span class="kc">true</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">MON</span><span class="o">.</span><span class="n">ordinal</span> <span class="o">&lt;</span> <span class="nc">TUE</span><span class="o">.</span><span class="n">ordinal</span> <span class="n">shouldBe</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="nc">MON</span><span class="o">.</span><span class="n">compareTo</span><span class="o">(</span><span class="nc">TUE</span><span class="o">)</span> <span class="n">should</span> <span class="n">be</span> <span class="o">&lt;</span> <span class="mi">0</span>
</span></span></code></pre></div><h3 id="iterable-capable-of-iterating-over-the-enum-items-as-a-collection">Iterable: Capable of iterating over the enum items as a collection</h3>
<p><strong>✅️️ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">.</span><span class="n">values</span> <span class="n">shouldBe</span> <span class="nc">ValueSet</span><span class="o">(</span><span class="nc">Mon</span><span class="o">,</span> <span class="nc">Tue</span><span class="o">,</span> <span class="nc">Wed</span><span class="o">,</span> <span class="nc">Thu</span><span class="o">,</span> <span class="nc">Fri</span><span class="o">,</span> <span class="nc">Sat</span><span class="o">,</span> <span class="nc">Sun</span><span class="o">)</span>
</span></span></code></pre></div><p><strong>⚠️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">all</span> <span class="n">shouldBe</span> <span class="nc">Seq</span><span class="o">(</span><span class="nc">Foo</span><span class="o">,</span> <span class="nc">Bar</span><span class="o">,</span> <span class="nc">Baz</span><span class="o">)</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">.</span><span class="n">values</span> <span class="n">shouldBe</span> <span class="nc">Array</span><span class="o">(</span><span class="nc">MON</span><span class="o">,</span> <span class="nc">TUE</span><span class="o">,</span> <span class="nc">WED</span><span class="o">,</span> <span class="nc">THU</span><span class="o">,</span> <span class="nc">FRI</span><span class="o">,</span> <span class="nc">SAT</span><span class="o">,</span> <span class="nc">SUN</span><span class="o">)</span>
</span></span></code></pre></div><h3 id="pattern-matching-ability-to-do-pattern-matching-on-the-items">Pattern Matching: Ability to do pattern matching on the items</h3>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span> <span class="k">=</span> <span class="nc">Sun</span>   <span class="c1">// Default inferred type: WeekDay.Value
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="nc">Sat</span> <span class="o">|</span> <span class="nc">Sun</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="s">&#34;working day&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="n">shouldBe</span> <span class="s">&#34;weekend&#34;</span>
</span></span></code></pre></div><p><strong>✅ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span><span class="k">:</span> <span class="kt">WeekDay</span> <span class="o">=</span> <span class="nc">Sun</span>  <span class="c1">// Default inferred type: WeekDay.Sun.type
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="nc">Sat</span> <span class="o">|</span> <span class="nc">Sun</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="s">&#34;working day&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="n">shouldBe</span> <span class="s">&#34;weekend&#34;</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span> <span class="k">=</span> <span class="nc">SUN</span>   <span class="c1">// Default inferred type: WeekDay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">result</span> <span class="k">=</span> <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="nc">SAT</span> <span class="o">|</span> <span class="nc">SUN</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="s">&#34;working day&#34;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="n">shouldBe</span> <span class="s">&#34;weekend&#34;</span>
</span></span></code></pre></div><h3 id="pattern-matching-compile-time-warning-about-exhaustive-pattern-matching">Pattern Matching: Compile time warning about <em>exhaustive pattern matching</em></h3>
<p><strong>⛔️ <code>scala.Enumeration</code></strong></p>
<p>This means that the compiler is happy to accept the code below at compile time, without issuing any warning, even though it <em>can</em> fail at runtime with a <code>scala.MatchError</code>.</p>
<p>Runtime errors can be mitigated by always adding a <code>case _</code> fallback to every pattern matching statement.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span> <span class="k">=</span> <span class="nc">Mon</span>   <span class="c1">// Default inferred type: WeekDay.Value
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// This code generates no warning!
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">a</span><span class="o">[</span><span class="kt">MatchError</span><span class="o">]</span> <span class="n">shouldBe</span> <span class="n">thrownBy</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nc">Sat</span> <span class="o">|</span> <span class="nc">Sun</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p><strong>✅ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span><span class="k">:</span> <span class="kt">WeekDay</span> <span class="o">=</span> <span class="nc">Mon</span>  <span class="c1">// Default inferred type: WeekDay.Sun.type
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// This code generates a warning:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn] scala-enums/src/test/scala/CaseObjectSpec.scala:48: match may not be exhaustive.
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn] It would fail on the following inputs: Fri, Mon, Thu, Tue, Wed
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn]       day match {
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn]       ^
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">[</span><span class="kt">MatchError</span><span class="o">]</span> <span class="n">shouldBe</span> <span class="n">thrownBy</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nc">Sat</span> <span class="o">|</span> <span class="nc">Sun</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">val</span> <span class="n">day</span> <span class="k">=</span> <span class="nc">MON</span>   <span class="c1">// Default inferred type: WeekDay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// This code generates a warning:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn] scala-enums/src/test/scala/JavaEnumSpec.scala:50: match may not be exhaustive.
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn] It would fail on the following inputs: FRI, MON, THU, TUE, WED
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn]       day match {
</span></span></span><span class="line"><span class="cl"><span class="cm">[warn]       ^
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">[</span><span class="kt">MatchError</span><span class="o">]</span> <span class="n">shouldBe</span> <span class="n">thrownBy</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">day</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="nc">SAT</span> <span class="o">|</span> <span class="nc">SUN</span> <span class="k">=&gt;</span> <span class="s">&#34;weekend&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p><strong>Serialization: Each enum item has an associated “name” value</strong></p>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;Mon&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;Sun&#34;</span>
</span></span></code></pre></div><p><strong>✅ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;Mon&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;Sun&#34;</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">MON</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;MON&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nc">SUN</span><span class="o">.</span><span class="n">toString</span> <span class="n">shouldBe</span> <span class="s">&#34;SUN&#34;</span>
</span></span></code></pre></div><h3 id="serialization-instantiate-an-enum-item-from-a-name-string">Serialization: Instantiate an enum item from a “name” <code>String</code></h3>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Foo&#34;</span><span class="o">).</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Mon&#34;</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Mon</span>
</span></span><span class="line"><span class="cl"><span class="n">the</span><span class="o">[</span><span class="kt">NoSuchElementException</span><span class="o">]</span> <span class="n">thrownBy</span> <span class="nc">WeekDay</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Oops&#34;</span><span class="o">)</span> <span class="n">should</span> <span class="n">have</span> <span class="n">message</span> <span class="s">&#34;No value found for &#39;Oops&#39;&#34;</span>
</span></span></code></pre></div><p><strong>⚠️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Foo&#34;</span><span class="o">).</span><span class="n">get</span><span class="o">.</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Bar&#34;</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">Some</span><span class="o">(</span><span class="nc">Bar</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">withName</span><span class="o">(</span><span class="s">&#34;Oops&#34;</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">None</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">CustomEnum</span><span class="o">.</span><span class="n">valueOf</span><span class="o">(</span><span class="s">&#34;FOO&#34;</span><span class="o">).</span><span class="n">custom</span> <span class="n">shouldBe</span> <span class="s">&#34;This is a foo&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nc">WeekDay</span><span class="o">.</span><span class="n">valueOf</span><span class="o">(</span><span class="s">&#34;MON&#34;</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="nc">MON</span>
</span></span><span class="line"><span class="cl"><span class="n">the</span><span class="o">[</span><span class="kt">IllegalArgumentException</span><span class="o">]</span> <span class="n">thrownBy</span> <span class="nc">WeekDay</span><span class="o">.</span><span class="n">valueOf</span><span class="o">(</span><span class="s">&#34;Oops&#34;</span><span class="o">)</span> <span class="n">should</span> <span class="n">have</span> <span class="n">message</span> <span class="s">&#34;No enum constant javaenum.WeekDay.Oops&#34;</span>
</span></span></code></pre></div><h3 id="types-items-are-instances-of-the-enumeration-not-separate-classes">Types: Items are instances of the enumeration, not separate classes</h3>
<p><strong>✅ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay.Value</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay.Value</span><span class="o">]</span>
</span></span></code></pre></div><p><strong>⛔️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">Mon</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="c1">// but, also...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nc">Mon</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay.Mon.</span><span class="k">type</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nc">Sun</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay.Sun.</span><span class="k">type</span><span class="o">]</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="nc">MON</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nc">SUN</span> <span class="n">shouldBe</span> <span class="n">a</span><span class="o">[</span><span class="kt">WeekDay</span><span class="o">]</span>
</span></span></code></pre></div><h3 id="types-has-distinct-type-after-type-erasure-ie-can-be-used-for-method-overloading">Types: Has distinct type after type erasure (i.e. can be used for method overloading)</h3>
<p><strong>⛔️ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm">[error] scala-enums/src/test/scala/ScalaEnumerationSpec.scala:74: double definition:
</span></span></span><span class="line"><span class="cl"><span class="cm">[error] def f(d: enumeration.CustomEnum.Value): String at line 73 and
</span></span></span><span class="line"><span class="cl"><span class="cm">[error] def f(d: enumeration.WeekDay.Value): String at line 74
</span></span></span><span class="line"><span class="cl"><span class="cm">[error] have same type after erasure: (d: Enumeration#Value)String
</span></span></span><span class="line"><span class="cl"><span class="cm">[error]   def f(d: enumeration.WeekDay.Value) = s&#34;week $d&#34;
</span></span></span><span class="line"><span class="cl"><span class="cm">[error]       ^
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="s">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">def f(d: enumeration.CustomEnum.Value) = s&#34;custom: $d&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">def f(d: enumeration.WeekDay.Value) = s&#34;week: $d&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">&#34;&#34;&#34;</span> <span class="n">shouldNot</span> <span class="n">typeCheck</span>
</span></span></code></pre></div><p><strong>✅ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">def</span> <span class="n">f</span><span class="o">(</span><span class="n">d</span><span class="k">:</span> <span class="kt">CustomEnum</span><span class="o">)</span> <span class="k">=</span> <span class="s">s&#34;custom: </span><span class="si">$d</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="n">f</span><span class="o">(</span><span class="n">d</span><span class="k">:</span> <span class="kt">WeekDay</span><span class="o">)</span> <span class="k">=</span> <span class="s">s&#34;week: </span><span class="si">$d</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">(</span><span class="nc">Foo</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="s">&#34;custom: Foo&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">(</span><span class="nc">Mon</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="s">&#34;week: Mon&#34;</span>
</span></span></code></pre></div><p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">def</span> <span class="n">f</span><span class="o">(</span><span class="n">d</span><span class="k">:</span> <span class="kt">CustomEnum</span><span class="o">)</span> <span class="k">=</span> <span class="s">s&#34;custom: </span><span class="si">$d</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="n">f</span><span class="o">(</span><span class="n">d</span><span class="k">:</span> <span class="kt">WeekDay</span><span class="o">)</span> <span class="k">=</span> <span class="s">s&#34;week: </span><span class="si">$d</span><span class="s">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">(</span><span class="nc">FOO</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="s">&#34;custom: FOO&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">f</span><span class="o">(</span><span class="nc">MON</span><span class="o">)</span> <span class="n">shouldBe</span> <span class="s">&#34;week: MON&#34;</span>
</span></span></code></pre></div><h3 id="interop-ease-of-use-in-mixed-scalajava-projects">Interop: Ease of use in mixed Scala/Java projects</h3>
<p><strong>⚠️ <code>scala.Enumeration</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// file: InteropScalaEnumeration.java</span><span class="w">
</span></span></span></code></pre></div><p>Not much relevant if your project is mainly Scala but if you need to access Scala <code>Enumeration</code>s from Java code it gets a bit too cumbersome.</p>
<ul>
<li>Cannot import the enumeration items directly (i.e. wildcard import). They must be qualified by their container class.</li>
<li>Hard to access field customizations, having to expose the internals (e.g. make <code>CustomEnumVal</code> public) to make them available to the Java code.</li>
<li>Calling syntax <code>WeekDay.Mon().id()</code> doesn’t look like normal Java <code>Enum</code>s <code>WeekDay.MON.ordinal</code>.</li>
<li>Mapping to native Java types (i.e. non-Scala ones) is not very straightforward.</li>
<li>Cannot be used in <code>switch-case</code> statements like normal Java <code>Enum</code>s.</li>
<li>Equally to Scala, only <code>Enumeration.Value</code> is available as a generic type for each enumeration item.</li>
</ul>
<p><strong>⛔️ <code>case object</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// file: InteropCaseObjects.java</span><span class="w">
</span></span></span></code></pre></div><p>Clearly a Scala only approach. It’s get completely unusable to try  accessing and using these type of constructs from Java.</p>
<ul>
<li>Mapping to native Java types (i.e. non-Scala ones) is not very straightforward.</li>
<li>Lots and lots of errors indicating it <code>Cannot find symbol</code> to the point of making it practically unusable.</li>
</ul>
<p><strong>✅ Java <code>Enum</code></strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="c1">// file: InteropJavaEnum.scala
</span></span></span></code></pre></div><p>Apart from the <em>slight</em> annoyance of having to define the enumerations in a separate <code>.java</code> file (instead on having them in place or inside the <code>.scala</code> file where it makes more sense), and the usual wrapping of Java code needed to contain the <code>null</code>s and <code>Exception</code>s with the more well behaved <code>Try</code> or <code>Option</code>, the Java <code>Enum</code> is fairly straightforward to use inside Scala code.</p>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Incêndio no Andanças: Os Números das Seguradoras</title>
      <link>https://hugo.ferreira.cc/andancas-seguros/</link>
      <pubDate>Sat, 13 Aug 2016 22:16:00 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/andancas-seguros/</guid>
      <description>Análise do impacto do incêndio no Andanças, seguradoras envolvidas e nacionalidade das matrículas.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/andancas-seguros/carros-queimados.jpg" length="440881" type="image/jpeg" />
      <content:encoded><![CDATA[<p><em><strong>Update 2016-08-14:</strong> Das 49 matrículas “não encontradas” apenas 7 continuam a não apresentar resultados. As restantes 42 matrículas distribuem-se pelas várias seguradoras de forma equivalente aos resultados anteriores, tendo aparecido uma nova seguradora “Popular Seguros”. O problema inicial deve ter sido uma falha informática temporária na <a href="http://www.asf.com.pt/NR/exeres/019EEB91-E357-4A7C-8BD2-B62293701692.htm">pesquisa do site da ASF</a>.</em></p>
<p><em><strong>Update 2016-08-13:</strong> No dia da <a href="http://www.asf.com.pt/NR/exeres/019EEB91-E357-4A7C-8BD2-B62293701692.htm">pesquisa no site da ASF</a> muitas das matrículas estavam a responder como “não encontrado”. Hoje essas mesmas matrículas já respondem com informação de seguros pelo que em breve irei actualizar esta informação com esses novos dados.</em></p>
<hr>
<p>Existem uma série de questões difíceis de responder sobre o incêndio no Andanças, dada a dimensão e falta de informação sobre o mesmo:</p>
<ul>
<li>Quantas seguradoras estão envolvidas?</li>
<li>Quantos veículos sinistrados estão afectos a cada seguradora?</li>
<li>Quem são as outras pessoas na minha seguradora?</li>
</ul>
<p>Responder a este tipo de questões tem sido uma das muitas dificuldades do grupo de pessoas prejudicadas pelo incêndio do Andanças (no qual, infelizmente, eu me incluo).</p>
<p>Juntando a informação <a href="https://postimg.org/gallery/33s2ekfdy/">publicada pela GNR no espaço do evento</a> (gentilmente fotografada pelo <a href="https://www.facebook.com/lucas.apitz">Lucas Apitz</a>) com os dados do <a href="http://www.asf.com.pt/NR/exeres/019EEB91-E357-4A7C-8BD2-B62293701692.htm">seguro associado a uma matricula</a> disponibilizados pela <a href="http://www.asf.com.pt/">ASF</a> (e uns pózinhos de programação à mistura) consegui ter a noção das várias seguradoras implicadas no incidente e quantos veículos têm segurados.</p>
<p>Como à data de publicação ainda não tinha recebido resposta da GNR nem encontrado online nenhuma listagem dos veículos em formato digital, podem existir alguns erros na transcrição das matrículas mas que não devem alterar muito os resultados.</p>
<p>Todos os <a href="https://docs.google.com/spreadsheets/d/1v4UKST2wDLQ-EJeYKpzJMfE0X8OAH1ajoVvwzW1tPe0/edit?usp=sharing">dados estão disponíveis nesta Google Sheet</a>: a lista das matrículas dos veículos afectados e a correspondente informação de seguros.</p>
<h2 id="seguradoras">Seguradoras</h2>
<p>Com <del datetime="2016-08-14T14:00:00Z">22</del> <strong>23 seguradoras</strong> envolvidas neste incidente, qualquer esforço de coordenação torna-se muito mais complicado, seja entre as próprias seguradoras, seja entre as pessoas sinistradas.</p>
<p>No entanto uma seguradora, a <strong>Liberty Seguros</strong>, destaca-se de todas pela sua <a href="Press-Liberty-Seguros-Festival-Andan%C3%A7as-2016-08-08.pdf">atitude solidária</a> de “assumir a reparação dos danos dos seus clientes mesmo que estes apenas tenham contratado apólices de responsabilidade civil contra danos a terceiros”.</p>
<p>Confesso que à primeira vista pensei que se tratasse de apenas mais uma manobra de marketing, com apenas uma mão cheia de veículos afetos a essa seguradora, mas olhando para a tabela abaixo percebe-se que <strong>outras seguradoras teriam também condições</strong> para oferecer essa benesse.</p>
<p><em>Nota: <a href="https://www.okteleseguros.pt/dados-da-empresa/575/">OK Teleseguros</a> aparece como <strong>Via Directa</strong></em><br>
<em>Nota: <a href="https://www.segurodirecto.pt/info-legal.html">Seguro Directo</a> aparece como <strong>Ageas</strong></em></p>
<p><img loading="lazy" src="seguradoras-table.png" alt="tabela das seguradoras mais afetadas"  />
</p>
<p><img loading="lazy" src="seguradoras-chart.png" alt="gráfico das seguradoras mais afetadas"  />
</p>
<h2 id="países">Países</h2>
<p>Isto não foi só um problema português. Embora dada a dimensão do incidente os veículos estrangeiros estejam em menor número, é de realçar que cerca de <strong>10% dos veículos</strong> não têm matrícula portuguesa, sendo na sua grande maioria espanhóis.</p>
<p>Se em Portugal já têm ocorrido vários problemas de coordenação entre as entidades responsáveis, seguradoras e sinistrados, e tendo em conta ainda a barreira da língua, decerto que para estas pessoas o passeio de férias a Portugal revelou-se um autêntico pesadelo. 🙁</p>
<p><img loading="lazy" src="paises-table.png" alt="tabela dos países das matrículas afetadas: ~90% Portuguesas e ~10% Estrangeiras"  />
</p>
<p><img loading="lazy" src="paises-chart.png" alt="gráfico circular dos países das matrículas afetadas: 402 Portuguesas e 45 Estrangeiras"  />
</p>
]]></content:encoded>
    </item>
    <item>
      <title>💭 UI/UX design artefacts</title>
      <link>https://hugo.ferreira.cc/design-artefacts/</link>
      <pubDate>Thu, 27 Mar 2014 22:16:32 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/design-artefacts/</guid>
      <description>Compare and contrast different design artefacts (sketch, wireframe, mockup, and prototype) in terms of their fidelity, speed, cost and use cases.</description>
        
        
        <enclosure url="https://hugo.ferreira.cc/design-artefacts/sketch-wireframe-mockup-prototype.png" length="1255198" type="image/png" />
      <content:encoded><![CDATA[<p>Because this seems to keep popping up in my discussions from time to time:</p>
<table>
<thead>
<tr>
<th>Artefacts</th>
<th>Fidelity</th>
<th>Speed</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sketch</td>
<td>➖➖ <em>very low</em></td>
<td>➕➕ <em>very fast</em></td>
<td>💲 <em>cheap</em></td>
</tr>
<tr>
<td>Wireframe</td>
<td>➖ <em>low</em></td>
<td>➕ <em>fast</em></td>
<td>💲💲 <em>low</em></td>
</tr>
<tr>
<td>Mockup</td>
<td>➕ <em>medium</em></td>
<td>➖ <em>slow</em></td>
<td>💲💲💲 <em>high</em></td>
</tr>
<tr>
<td>Prototype</td>
<td>➕➕ <em>high</em></td>
<td>➖➖ <em>very slow</em></td>
<td>💲💲💲💲 <em>expensive</em></td>
</tr>
</tbody>
</table>
<hr>
<p><strong>Sketch</strong> — pen &amp; paper rough drawings</p>
<ul>
<li>Quick brainstorm of <em>ideias</em></li>
<li>Easy communication of purpose</li>
</ul>
<p><strong>Wireframe</strong> — black &amp; grey representation</p>
<ul>
<li>Use: quick communication of <em>interactions</em></li>
<li>Documenting the interface;</li>
</ul>
<p><strong>Mockup</strong> — static coloured visualisation</p>
<ul>
<li>Gather rough feedback and buy-in from stakeholders</li>
</ul>
<p><strong>Prototype</strong> — real interactive implementation</p>
<ul>
<li>User testing in a scenario close to reality</li>
<li>Possibly reusable into the product</li>
</ul>
<hr>
<p>See also,</p>
<ul>
<li><a href="http://uxmovement.com/wireframes/why-its-important-to-sketch-before-you-wireframe/">Why It&rsquo;s Important to Sketch Before You Wireframe</a></li>
<li><a href="http://designmodo.com/wireframing-prototyping-mockuping/">Wireframing, Prototyping, Mockuping - What&rsquo;s the Difference?</a></li>
<li><a href="https://www.alphalogicinc.com/blog/sketch-vs-wireframe-vs-mockup-vs-prototype/">Wireframe vs Mockup vs Prototype - What&rsquo;s the Difference?</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>💭 Vodafone “Update” app for iPhone</title>
      <link>https://hugo.ferreira.cc/vodafone-app/</link>
      <pubDate>Mon, 04 Jan 2010 07:07:28 +0000</pubDate>
      <guid>https://hugo.ferreira.cc/vodafone-app/</guid>
      <description>A while back, Widgetlabs (makers of Vodafone&amp;rsquo;s Update app for iPhone) was kind enough to ask about my complaints regarding the Vodafone Update app.
Having setup version 2.0 of the app to connect to my Twitter, Facebook and LinkedIn accounts, here&amp;rsquo;s a quick list of my main impressions, in no particular order:
Problems
Poor timeline management, with several issues:
Entries getting frequently out of chronological order, with the most recent ones appended after 1 month old entries, for example.</description>
      <content:encoded><![CDATA[<p>A while back, <a href="http://www.widgetlabs.eu">Widgetlabs</a> (makers of <a href="http://www.vodafone-update.de/iPhone">Vodafone&rsquo;s <strong>Update</strong> app for iPhone</a>) was kind enough to <a href="http://twitter.com/Widgetlabs/status/6922819882">ask about my complaints</a> regarding the Vodafone <strong>Update</strong> app.</p>
<p>Having setup version 2.0 of the app to connect to my <a href="http://twitter.com/hugocf">Twitter</a>, <a href="http://www.facebook.com/hugocf">Facebook</a> and <a href="http://www.linkedin.com/in/hugocf">LinkedIn</a> accounts, here&rsquo;s a quick list of my main impressions, in no particular order:</p>
<p><strong>Problems</strong></p>
<ul>
<li>
<p>Poor timeline management, with several issues:</p>
<ul>
<li>
<p>Entries getting frequently out of chronological order, with the most recent ones appended after 1 month old entries, for example.</p>
</li>
<li>
<p>Getting thrown to the top of the timeline when returning from the details of an item, instead of staying where we left off.</p>
</li>
<li>
<p>Different update speeds per network give the impression that no updates exist for a certain period of time, only to have it &ldquo;magically&rdquo; appear after you&rsquo;ve already scrolled past that point.</p>
<p><em>These issues showed up more often when coming back to the timeline from the details of an old update, reached after scrolling back &ldquo;in time&rdquo; (e.g. to 1 month old entries).</em></p>
</li>
</ul>
</li>
<li>
<p>Date &amp; time formats do not follow the regional format settings. <em>(AM/PM? Please!)</em></p>
</li>
<li>
<p>On Facebook updates, content shared without a custom comment appear as <em>&ldquo;no text posted&rdquo;</em> making it impossible to discern from the timeline what it is about.</p>
</li>
</ul>
<p><strong>Annoyances</strong></p>
<ul>
<li>Can&rsquo;t go to the next/previous update when in details mode! Having to get back to the timeline only to check the next item is very cumbersome. <em>(not to mention when the problems with the timeline quick in, as mentioned above)</em></li>
<li>On Twitter, there is no easy way to see a user&rsquo;s mentions from the
user&rsquo;s profile. <em>(only option is to do a manual search?)</em></li>
<li>The app supports multiple networks but not multiple accounts for the same network?!? <em>(this is just bizarre and, in my opinion, shortsighted!)</em></li>
<li>We can only see the user&rsquo;s profile on Twitter?! What about the other networks?</li>
<li>On Facebook, updates from apps appear without identifying which &ldquo;friend&rdquo; posted them.</li>
</ul>
<p><strong>Improvements? Nice to have?</strong></p>
<ul>
<li>Add a way to see a user&rsquo;s favorites on Twitter.</li>
<li>Add the ability to hide app notices from the timeline on Facebook.</li>
<li>Twitter profile counts (followers, following, etc) should be clickable to see a detailed list.</li>
<li>Allow to flag/star/favorite directly from the timeline. <em>(relates to my personal usage, since I often &ldquo;flag for later&rdquo; to check back when I have more time)</em></li>
<li>When starting the app, go back to where the user left off. <em>(very useful for when incoming phone calls come in)</em></li>
</ul>
<p>These are only the main ones I&rsquo;ve noticed after a couple hours of using the app but bear in mind that with both Facebook and Linkedin having their own iPhone applications and Tweetie being the best-seller app for Twitter, the expectations for accessing these networks through an app are quite high!</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
