<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Osmar Petry</title><link>https://osmarpetry.dev/</link><description>Recent content on Osmar Petry</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 23 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://osmarpetry.dev/rss.xml" rel="self" type="application/rss+xml"/><item><title>JavaScript Modules and Bundlers</title><link>https://osmarpetry.dev/blog/javascript-modules-and-bundlers/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-modules-and-bundlers/</guid><description>&lt;p&gt;The goal here is to understand JavaScript module systems (IIFE, CommonJS, ESModules), how modern bundlers sit on top of them, and which build types to use for business apps and component libraries.&lt;/p&gt;&#10;&lt;p&gt;Module systems describe &lt;strong&gt;how code is organized and imported/exported&lt;/strong&gt; at the language level. Bundlers and build tools &lt;strong&gt;consume those modules&lt;/strong&gt; and produce optimized outputs for different environments (browser, Node, CDN, etc.).&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="part-1--module-systems"&gt;Part 1 — Module Systems&lt;/h2&gt;&#10;&lt;h3 id="iife-immediately-invoked-function-expression"&gt;IIFE (Immediately Invoked Function Expression)&lt;/h3&gt;&#10;&lt;p&gt;IIFEs are the classic pattern to create a private scope and avoid polluting &lt;code&gt;window&lt;/code&gt;, often combined with a single global namespace like &lt;code&gt;App&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>PixieShop Authentication Playbook — OIDC SSO Across Four Identity Providers</title><link>https://osmarpetry.dev/blog/sso-authentication-playbook/</link><pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/sso-authentication-playbook/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;&lt;strong&gt;Scenario.&lt;/strong&gt; PixieShop is a B2B SaaS that sells enchanted toys to retail partners. Every partner logs in through their own corporate identity provider — some use Okta, others use Microsoft Entra ID. We never see a password. FusionAuth sits in the middle as our OIDC identity broker, and Auth.js v5 handles the Next.js session on the frontend. This playbook is the single place where we document how the whole chain works, from RSA key creation to federated logout.&lt;/p&gt;</description></item><item><title>Backend Architectures — history, case studies &amp; dogfooding</title><link>https://osmarpetry.dev/blog/introduction-to-be-archtitectures/</link><pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/introduction-to-be-archtitectures/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Know the &lt;strong&gt;history&lt;/strong&gt; (monolith → services → serverless) to choose the &lt;strong&gt;right shape for now&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Use &lt;strong&gt;dogfooding&lt;/strong&gt; to turn internal capabilities into &lt;strong&gt;platforms&lt;/strong&gt; and eventually &lt;strong&gt;products&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Pair &lt;strong&gt;tech + finance&lt;/strong&gt; on every decision so architecture choices have a clear &lt;strong&gt;P&amp;amp;L story&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="case-studies-what-they-did--why-it-mattered"&gt;Case studies (what they did → why it mattered)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Amazon&lt;/strong&gt;: built infra &amp;amp; tooling for itself first (&lt;strong&gt;dogfood&lt;/strong&gt;) → later externalized as &lt;strong&gt;AWS&lt;/strong&gt; (new revenue, 2× monetization of the same effort).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Netflix&lt;/strong&gt;: &lt;strong&gt;hybrid&lt;/strong&gt; of microservices + serverless; serverless for bursty/edge workloads, services for core domains → &lt;strong&gt;speed + cost control&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Google&lt;/strong&gt;: evolved from large coordinated monoliths to &lt;strong&gt;microservices&lt;/strong&gt; as scale/teams grew → &lt;strong&gt;independent deploys&lt;/strong&gt; and &lt;strong&gt;targeted reliability&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Uber&lt;/strong&gt;: reused &lt;strong&gt;profile, payments, geo, notifications&lt;/strong&gt; to launch &lt;strong&gt;Eats&lt;/strong&gt; quickly → &lt;strong&gt;time-to-market&lt;/strong&gt; by reusing platform primitives.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="decision-heuristics-when-to-pick-what"&gt;Decision heuristics (when to pick what)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Monolith first&lt;/strong&gt; when the team is small, domain still moving, and you need &lt;strong&gt;velocity&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Split by domain&lt;/strong&gt; (bounded contexts) when teams block each other and deploys become risky.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Serverless&lt;/strong&gt; for event-driven, spiky, or edge tasks where &lt;strong&gt;operational burden&lt;/strong&gt; must be minimal.&lt;/li&gt;&#10;&lt;li&gt;Always design for &lt;strong&gt;observability&lt;/strong&gt; (logs/metrics/traces) and &lt;strong&gt;clear failure domains&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="dogfooding--productization-loop"&gt;Dogfooding → productization loop&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt; the capability you need (internal API/service).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Harden&lt;/strong&gt; with SLOs, docs, dashboards.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reuse&lt;/strong&gt; across 2–3 internal products (prove generality).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Abstract&lt;/strong&gt; contracts (versioning, quotas, cost model).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Externalize&lt;/strong&gt; (SDKs, billing, support) when economics are clear.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;strong&gt;Two-sided payoff:&lt;/strong&gt; internal reuse lowers &lt;strong&gt;cost/time&lt;/strong&gt;, externalization creates &lt;strong&gt;revenue&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Web Accessibility V3 — Topics cheat-sheet &amp; decision guide</title><link>https://osmarpetry.dev/blog/web-accessibility/</link><pubDate>Mon, 01 Sep 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/web-accessibility/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Course map covers &lt;strong&gt;Screen Readers&lt;/strong&gt;, &lt;strong&gt;Accessible HTML&lt;/strong&gt;, &lt;strong&gt;ARIA&lt;/strong&gt;, &lt;strong&gt;Focus Management&lt;/strong&gt;, and &lt;strong&gt;Visual Considerations&lt;/strong&gt;, plus &lt;strong&gt;Debugging &amp;amp; team process&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Aim: ship &lt;strong&gt;perceivable, operable, understandable, robust&lt;/strong&gt; experiences (POUR) with practical exercises and team-ready debugging habits.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="topics--what-to-do-at-a-glance"&gt;Topics → what to do (at a glance)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Screen Readers:&lt;/strong&gt; learn how they work, enable them, write solid &lt;strong&gt;alt text&lt;/strong&gt;, and test.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Accessible HTML:&lt;/strong&gt; prefer &lt;strong&gt;semantic elements&lt;/strong&gt; and set &lt;strong&gt;document language&lt;/strong&gt;; fix invalid markup.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ARIA:&lt;/strong&gt; add only when semantics aren’t enough; know &lt;strong&gt;roles, states, properties&lt;/strong&gt;, &lt;strong&gt;names/descriptions&lt;/strong&gt;, and &lt;strong&gt;live regions&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Focus Management:&lt;/strong&gt; full keyboard support, &lt;strong&gt;skip links&lt;/strong&gt;, logical &lt;strong&gt;Tab&lt;/strong&gt; order, avoid &lt;strong&gt;focus traps&lt;/strong&gt;, and review shortcuts.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Visual:&lt;/strong&gt; check &lt;strong&gt;color contrast&lt;/strong&gt;, &lt;strong&gt;reflow/zoom&lt;/strong&gt;, &lt;strong&gt;reduced motion&lt;/strong&gt;, and &lt;strong&gt;prefers-color-scheme&lt;/strong&gt;; connect performance with accessibility.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Debugging:&lt;/strong&gt; use linters/devtools, improve team workflows, go &lt;strong&gt;beyond compliance&lt;/strong&gt;, and practice with hands-on exercises.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="decision-heuristics"&gt;Decision heuristics&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Semantics first → ARIA last.&lt;/strong&gt; If a native element already communicates role/state, &lt;strong&gt;don’t add ARIA&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Keyboard is the truth.&lt;/strong&gt; If it’s not operable with keyboard and visible focus, it’s not accessible.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Name, role, value:&lt;/strong&gt; can a screen reader expose them correctly? If not, fix semantics, labels, or ARIA.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Respect user prefs:&lt;/strong&gt; &lt;code&gt;prefers-reduced-motion&lt;/code&gt;, &lt;code&gt;prefers-color-scheme&lt;/code&gt;, and zoom/reflow without loss.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="team-workflow"&gt;Team workflow&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Set standards&lt;/strong&gt; (WCAG targets, browser/AT matrix).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Lint &amp;amp; test early&lt;/strong&gt; (HTML validity, axe, devtools).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Exercise mindset:&lt;/strong&gt; practice with screen readers and keyboard on real UI (modals, forms, navigation).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Go beyond checklists:&lt;/strong&gt; optimize usability for assistive technology users, not just box-ticking.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="dev-checklist"&gt;Dev checklist&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Landmark structure (&lt;code&gt;header&lt;/code&gt;, &lt;code&gt;nav&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;aside&lt;/code&gt;, &lt;code&gt;footer&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Page language (&lt;code&gt;&amp;lt;html lang&amp;gt;&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Forms: &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; + programmatic names; error text announced.&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Interactive controls are &lt;strong&gt;native&lt;/strong&gt; or fully re-created (role, keyboard, focus, ARIA).&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Focus order and &lt;strong&gt;visible&lt;/strong&gt; focus style.&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Contrast meets WCAG; no information by color alone.&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Motion: provide a &lt;strong&gt;reduced motion&lt;/strong&gt; path; avoid parallax autoplay by default.&lt;/li&gt;&#10;&lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Respect zoom/reflow at 200–400% without horizontal scroll.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Web Accessibility — All Topics (Frontend Masters companion site)&lt;/strong&gt;: &lt;a href="https://web-accessibility-v3.vercel.app/topics" target="_blank" rel="noreferrer"&gt;https://web-accessibility-v3.vercel.app/topics&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;GitHub repo&lt;/strong&gt;: &lt;a href="https://github.com/marcysutton/frontend-masters-web-accessibility-v3" target="_blank" rel="noreferrer"&gt;https://github.com/marcysutton/frontend-masters-web-accessibility-v3&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[react-forwardRef|Forwarding Ref]]&lt;/li&gt;&#10;&lt;li&gt;[[svg-are-the-best|SVG are the Best]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>XState — model UI behavior correctly and make it testable</title><link>https://osmarpetry.dev/blog/xstate-model-ui-bahavior/</link><pubDate>Sat, 12 Jul 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/xstate-model-ui-bahavior/</guid><description>&lt;h2 id="the-problem-were-solving"&gt;The problem we&amp;rsquo;re solving&lt;/h2&gt;&#10;&lt;p&gt;Imagine you join a company that runs an e-commerce platform. Product asks you to build a &lt;strong&gt;search page&lt;/strong&gt; — the kind of page every user hits dozens of times a day. It sounds simple: a text input, a button, show results.&lt;/p&gt;&#10;&lt;p&gt;But then reality kicks in. The page has to handle empty queries, network failures, slow connections, retries, and race conditions where a user submits a second search before the first one finishes. A junior developer might reach for a handful of &lt;code&gt;useState&lt;/code&gt; calls — &lt;code&gt;isLoading&lt;/code&gt;, &lt;code&gt;hasError&lt;/code&gt;, &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;submitted&lt;/code&gt; — and suddenly you&amp;rsquo;re juggling four booleans that produce sixteen possible combinations. Most of those combinations are impossible, but nothing in the code prevents them. A loading spinner stays visible after an error. A success message flashes before the data arrives. Bugs creep in not because the developer made a logic error, but because the &lt;strong&gt;model itself was never defined&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Domain-Driven, Data-Oriented Design (DDDOD)</title><link>https://osmarpetry.dev/blog/dddod/</link><pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/dddod/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy adapts Domain-Driven Design principles to Go by emphasising data flow and simplicity. DDDOD keeps the focus on reliable data transformations while preserving idiomatic Go patterns.&lt;/p&gt;&#10;&lt;h2 id="why-not-pure-ddd"&gt;Why not pure DDD?&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Traditional DDD can introduce excessive abstraction and ceremony in Go projects.&lt;/li&gt;&#10;&lt;li&gt;Too many layers and interfaces obscure intent, reducing maintainability.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="core-pillars"&gt;Core pillars&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Data-oriented design&lt;/strong&gt;: prioritise data models and their transformations; ensure data can cross layers safely.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Validation &amp;amp; trust&lt;/strong&gt;: embed validation logic early; fail fast to maintain integrity.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Structured layers&lt;/strong&gt;: app → business → storage; each layer defines clear contracts and side-effects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Domain isolation&lt;/strong&gt;: separate bounded contexts to prevent accidental coupling and cascading failures.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="implementation-tips"&gt;Implementation tips&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Use packages to reflect domains (&lt;code&gt;internal/user&lt;/code&gt;, &lt;code&gt;internal/auth&lt;/code&gt;); avoid grab-bag packages like &lt;code&gt;common&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Expose only necessary APIs; keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Guard entry points with validation and logging to catch anomalies early.&lt;/li&gt;&#10;&lt;li&gt;Leverage functional options or constructors to initialize services with dependencies explicitly.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bill Kennedy, “Domain-Driven, Data-Oriented Design” talk and articles (Ardan Labs).&lt;/li&gt;&#10;&lt;li&gt;Ardan Labs Service repository as a starter kit: &lt;a href="https://github.com/ardanlabs/service" target="_blank" rel="noreferrer"&gt;https://github.com/ardanlabs/service&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[ddd|Domain-Driven Design: Tackling Complexity in the Heart of Software]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Gophers 2025 — Event Report</title><link>https://osmarpetry.dev/blog/gophers-2025-event/</link><pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/gophers-2025-event/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;Gophers 2025 brought the Go community together in Anita Garibaldi, Santa Catarina, for two full days of talks, panels, and hands-on workshops. Sessions ranged from organizational culture and dependency-injection strategies to Kubernetes tuning, automation, game development with Ebiten, and end-to-end observability. This report consolidates every note found in the &lt;code&gt;Gophers 2025/&lt;/code&gt; directory into a single English-language document. It follows the event chronologically and highlights technical takeaways, workshop content, a real-world case study, and concrete action items.&lt;/p&gt;</description></item><item><title>Go Serialization Options</title><link>https://osmarpetry.dev/blog/go-serialization-options/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/go-serialization-options/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Go types can expose custom wire formats through &lt;code&gt;encoding/json&lt;/code&gt; and related packages. The main choices are &lt;code&gt;MarshalText&lt;/code&gt; / &lt;code&gt;UnmarshalText&lt;/code&gt;, &lt;code&gt;MarshalJSON&lt;/code&gt; / &lt;code&gt;UnmarshalJSON&lt;/code&gt;, or explicit helper functions. Each option trades off convenience, control, and complexity.&lt;/p&gt;&#10;&lt;h2 id="1-marshaltext--unmarshaltext"&gt;1. &lt;code&gt;MarshalText&lt;/code&gt; / &lt;code&gt;UnmarshalText&lt;/code&gt;&lt;/h2&gt;&#10;&lt;p&gt;Implements &lt;code&gt;encoding.TextMarshaler&lt;/code&gt; and &lt;code&gt;encoding.TextUnmarshaler&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;This converts values to plain text. JSON, XML, and other encoders automatically use it when a custom JSON marshaler is absent.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MarshalText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nb"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;UnmarshalText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2-marshaljson--unmarshaljson"&gt;2. &lt;code&gt;MarshalJSON&lt;/code&gt; / &lt;code&gt;UnmarshalJSON&lt;/code&gt;&lt;/h2&gt;&#10;&lt;p&gt;Implements &lt;code&gt;json.Marshaler&lt;/code&gt; and &lt;code&gt;json.Unmarshaler&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Package Oriented Design</title><link>https://osmarpetry.dev/blog/pod-go/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/pod-go/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy’s Package Oriented Design (POD) emphasises starting and ending architectural decisions at the package level. Each package should provide a focused solution for a domain problem to keep code composable, testable, and maintainable.&lt;/p&gt;&#10;&lt;h2 id="definition"&gt;Definition&lt;/h2&gt;&#10;&lt;p&gt;POD identifies where each package belongs and the design rules it follows. Packages act as the building blocks of Go applications, supporting composition and isolation.&lt;/p&gt;&#10;&lt;h2 id="guiding-philosophy"&gt;Guiding philosophy&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Purpose over storage:&lt;/strong&gt; packages should provide behaviour, not just hold utilities.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Encapsulation:&lt;/strong&gt; expose only necessary APIs and hide implementation details.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Portability:&lt;/strong&gt; a consistent package structure makes discussion and reuse easier across projects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Layering:&lt;/strong&gt; organise code into purposeful layers, such as &lt;code&gt;kit&lt;/code&gt;, &lt;code&gt;application&lt;/code&gt;, and &lt;code&gt;service&lt;/code&gt;, with explicit interaction rules.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="benefits"&gt;Benefits&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Modularity:&lt;/strong&gt; domain-specific packages reduce unwanted coupling.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintainability:&lt;/strong&gt; clear responsibilities make testing and refactoring easier.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; well-defined package boundaries support growth in complexity and team size.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="package-responsibilities"&gt;Package responsibilities&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Live in one place per domain, such as &lt;code&gt;internal/user&lt;/code&gt; or &lt;code&gt;internal/platform&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Provide a specific solution and avoid generic buckets like &lt;code&gt;common&lt;/code&gt; or &lt;code&gt;util&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Export only the API needed by consumers and keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Name files to reflect behaviour so callers understand what the package delivers.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="layering-cheat-sheet"&gt;Layering cheat-sheet&lt;/h2&gt;&#10;&lt;h3 id="kit"&gt;&lt;code&gt;kit&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Shared libraries with zero dependency on application packages.&lt;/p&gt;</description></item><item><title>Conway’s Law — origins, literature, and team design</title><link>https://osmarpetry.dev/blog/conways-law-birth-1968/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/conways-law-birth-1968/</guid><description>&lt;h2 id="reference-stack"&gt;Reference stack&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Melvin Conway, “How Do Committees Invent?” (1968).&lt;/li&gt;&#10;&lt;li&gt;Thoughtworks, “Applying Conway’s Law to Improve Your Software Development.”&lt;/li&gt;&#10;&lt;li&gt;M. Soldani et al., “A Decade of Conway’s Law: A Literature Review 2003–2012” (IEEE).&lt;/li&gt;&#10;&lt;li&gt;Video summary: &lt;a href="https://youtu.be/SWrlFod8t5g" target="_blank" rel="noreferrer"&gt;https://youtu.be/SWrlFod8t5g&lt;/a&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="essence-of-the-law"&gt;Essence of the law&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;“Any organization that designs a system will produce a design whose structure is a copy of the organization’s communication structure.”&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Architecture mirrors team communication pathways; siloed teams create siloed modules, joined at fragile seams.&lt;/li&gt;&#10;&lt;li&gt;“Monolithic teams do not build microservices”—system modularity depends on cross-team autonomy and shared vocabulary.&lt;/li&gt;&#10;&lt;li&gt;Neglecting communication design results in accidental system design, rather than deliberate architecture.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="historical-context--popularization"&gt;Historical context &amp;amp; popularization&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Conway observed the phenomenon across software, military, and governmental projects in the 1960s.&lt;/li&gt;&#10;&lt;li&gt;Frederick Brooks amplified the idea in &lt;em&gt;The Mythical Man-Month&lt;/em&gt;, cementing “Conway’s Law” in software folklore.&lt;/li&gt;&#10;&lt;li&gt;Later research confirms that org charts and interface diagrams often align, sometimes unintentionally.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="key-takeaways-from-the-literature-review"&gt;Key takeaways from the literature review&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Larger organizations introduce communication friction, leading to complex, tightly coupled systems.&lt;/li&gt;&#10;&lt;li&gt;Parkinson’s Law: management layers tend to expand, exacerbating coordination overhead.&lt;/li&gt;&#10;&lt;li&gt;Small, autonomous teams (“two-pizza teams”) correlate with cleaner, more modular architecture.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="review-questions"&gt;Review questions&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;How does organizational structure influence the resulting system design?&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Systems reflect the communication patterns of their creators; poor cross-team collaboration manifests as brittle interfaces.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;ol start="2"&gt;&#10;&lt;li&gt;How does company size impact system complexity?&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;As organizations grow, coordination paths lengthen, producing sprawling systems with integration pain; keeping teams small mitigates the effect.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="practical-implications"&gt;Practical implications&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Design teams around the architecture you want (the “inverse Conway maneuver”): align squads to bounded contexts before writing code.&lt;/li&gt;&#10;&lt;li&gt;Optimize for communication density: co-locate domains, create shared rituals, and collapse unnecessary hierarchy.&lt;/li&gt;&#10;&lt;li&gt;When introducing API gateways or platform teams, ensure their communication network matches the required integrations.&lt;/li&gt;&#10;&lt;li&gt;Regularly map org structures to architecture diagrams; adjust teams when misalignment appears.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="next-actions"&gt;Next actions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Compare current team topology with service/module boundaries; plan reorg if misalignment exists.&lt;/li&gt;&#10;&lt;li&gt;Share the original essay and Thoughtworks article with engineering leadership to ground discussions in historical context.&lt;/li&gt;&#10;&lt;li&gt;Incorporate Conway’s Law checkpoints into architecture reviews (e.g., “Does a team own each interface?”).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Decision-Making Traits of Great Software Engineers</title><link>https://osmarpetry.dev/blog/software-engineer-decisions-2015/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/software-engineer-decisions-2015/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Based on 59 interviews with senior Microsoft engineers (Meyer, Zimmermann, Fritz, ICSE 2015). Identifies 53 characteristics grouped into personal qualities, decision-making, team impact, and product impact. Focus here is on decision-making skills that differentiate top engineers.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Deep knowledge of organisational context (people, priorities, constraints).&lt;/li&gt;&#10;&lt;li&gt;Ability to switch between big-picture vision and low-level details.&lt;/li&gt;&#10;&lt;li&gt;Balancing short-term deliverables with long-term maintainability.&lt;/li&gt;&#10;&lt;li&gt;Evaluating risks and trade-offs before committing to technical choices.&lt;/li&gt;&#10;&lt;li&gt;Creating shared context: ensuring stakeholders understand constraints.&lt;/li&gt;&#10;&lt;li&gt;Fostering psychological safety so teammates surface concerns early.&lt;/li&gt;&#10;&lt;li&gt;Anticipating future needs; keeping options open for future change.&lt;/li&gt;&#10;&lt;li&gt;Honesty and transparency in communicating limitations or unknowns.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aligns with soft-skill emphasis: empathy, collaboration, cultural awareness.&lt;/li&gt;&#10;&lt;li&gt;Supports literature on leadership, team coordination, and human factors in project success.&lt;/li&gt;&#10;&lt;li&gt;Critiques traditional curricula (ACM/IEEE) for insufficient real-world detail.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to cultivate these 53 traits under tight deadlines?&lt;/li&gt;&#10;&lt;li&gt;Which traits matter most in startups vs large enterprises?&lt;/li&gt;&#10;&lt;li&gt;How to measure and reward decision-making soft skills in performance reviews?&lt;/li&gt;&#10;&lt;li&gt;How much does organisational context enable or limit development of these traits?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Excellence extends beyond technical mastery; requires self-development, empathy, systems thinking, and collaboration.&lt;/li&gt;&#10;&lt;li&gt;Leaders must build psychologically safe environments to encourage healthy decision-making.&lt;/li&gt;&#10;&lt;li&gt;Curriculum reform should focus on practical, context-aware training.&lt;/li&gt;&#10;&lt;li&gt;Use findings to guide career development and performance evaluation discussions.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Meyer, A. N., Zimmermann, T., &amp;amp; Fritz, T. (2015). &lt;em&gt;What Makes a Great Software Engineer?&lt;/em&gt; ICSE Proceedings. &lt;a href="https://www.researchgate.net/.../What-Makes-a-Great-Software-Engineer.pdf" target="_blank" rel="noreferrer"&gt;https://www.researchgate.net/&amp;hellip;/What-Makes-a-Great-Software-Engineer.pdf&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Design by Contract (DbC)</title><link>https://osmarpetry.dev/blog/dbc/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/dbc/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Bertrand Meyer introduced Design by Contract (DbC) to formalise expectations between software components. Contracts specify obligations and benefits for clients and suppliers via preconditions, postconditions, and invariants, enabling safer, more maintainable systems.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Contracts&lt;/strong&gt;: Define preconditions (caller responsibilities), postconditions (supplier guarantees), invariants (state consistency).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Runtime checks&lt;/strong&gt;: Contracts can be enforced during development/testing to catch violations early.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Contracts serve as precise specs and executable documentation.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt;: Components hide implementation details while exposing contractual behaviour.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reuse &amp;amp; reliability&lt;/strong&gt;: DbC encourages reusable components with clear expectations.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Basis for Eiffel language features; influences modern assertion frameworks.&lt;/li&gt;&#10;&lt;li&gt;Complements unit testing and TDD by clarifying expected behaviour.&lt;/li&gt;&#10;&lt;li&gt;Aligns with API design best practices and microservice contracts.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to balance DbC runtime checks with performance constraints?&lt;/li&gt;&#10;&lt;li&gt;How to integrate DbC in languages without native support?&lt;/li&gt;&#10;&lt;li&gt;When should contracts be relaxed or extended as systems evolve?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Contracts clarify team communication and reduce misunderstandings.&lt;/li&gt;&#10;&lt;li&gt;Useful for critical systems where correctness outweighs overhead.&lt;/li&gt;&#10;&lt;li&gt;Combining DbC with automated tests and CI improves confidence in deployments.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Meyer, B. (1992). &lt;em&gt;Applying &amp;ldquo;Design by Contract&amp;rdquo;&lt;/em&gt;. Computer, 25(10), 40-51.&lt;/li&gt;&#10;&lt;li&gt;Official Eiffel documentation on DbC.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[design-patterns|Design Pattern]]&lt;/li&gt;&#10;&lt;li&gt;[[ddd|Domain-Driven Design: Tackling Complexity in the Heart of Software]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Modularization Criteria — Parnas 1972</title><link>https://osmarpetry.dev/blog/parnas-modularization-1972/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/parnas-modularization-1972/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;David L. Parnas (1972) proposed information hiding as the primary criterion for modular design, using the KWIC (Key Word In Context) system to compare traditional flow-based modularization vs encapsulating design decisions. His approach yields systems that are easier to modify, maintain, and evolve.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Traditional modularization (aligned with processing steps) leads to high coupling and brittle systems.&lt;/li&gt;&#10;&lt;li&gt;Information hiding: modules encapsulate design decisions (data structures, algorithms, storage formats).&lt;/li&gt;&#10;&lt;li&gt;KWIC case study: conventional design (5 modules aligned with processing sequence) vs information-hiding design (4 modules for storage, circular shift generation, sorting, output).&lt;/li&gt;&#10;&lt;li&gt;Benefits: localized changes, clear responsibilities, replaceable internals without breaking clients.&lt;/li&gt;&#10;&lt;li&gt;Trade-off: potential performance overhead due to inter-module communication; can be mitigated via inlining and efficient call mechanisms.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Precursor to object-oriented encapsulation and modern modular design.&lt;/li&gt;&#10;&lt;li&gt;Supports microservices and DDD bounded context thinking.&lt;/li&gt;&#10;&lt;li&gt;Relates to clean architecture and low coupling principles.&lt;/li&gt;&#10;&lt;li&gt;Anticipates interface contracts in modern API design.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to apply information hiding in fast-paced agile projects?&lt;/li&gt;&#10;&lt;li&gt;Which metrics can quantify effective information hiding?&lt;/li&gt;&#10;&lt;li&gt;How to balance encapsulation with performance in real-time systems?&lt;/li&gt;&#10;&lt;li&gt;Applicability to distributed architectures?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Encapsulating design decisions prevents leakage of implementation details across layers.&lt;/li&gt;&#10;&lt;li&gt;KWIC example illustrates how storage strategies can remain swappable with proper abstraction.&lt;/li&gt;&#10;&lt;li&gt;Critique of flow-based modularization still relevant for ETL/data pipeline architectures.&lt;/li&gt;&#10;&lt;li&gt;Stable interfaces support DevOps pipelines and isolate testing concerns.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Parnas, D. L. (1972). &lt;em&gt;On the Criteria To Be Used in Decomposing Systems into Modules&lt;/em&gt;. Communications of the ACM, 15(12), 1053-1058.&lt;/li&gt;&#10;&lt;li&gt;Modern commentary: &lt;a href="https://www.refact0r.dev/blog/module-criteria" target="_blank" rel="noreferrer"&gt;https://www.refact0r.dev/blog/module-criteria&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>No Silver Bullet — Essence &amp; Accidents</title><link>https://osmarpetry.dev/blog/no-silver-bullet-1986/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/no-silver-bullet-1986/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Frederick P. Brooks Jr. (1986) argues there’s no single “silver bullet” that will provide an order-of-magnitude productivity boost in software engineering. Distinguishes &lt;strong&gt;essential&lt;/strong&gt; difficulties (intrinsic to software) from &lt;strong&gt;accidental&lt;/strong&gt; difficulties (tooling, implementation). Technological advances continue to chip away at accidental issues, but inherent complexity remains.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Essence vs accidents&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Essential: inherent complexity, changing requirements, invisibility, costly change.&lt;/li&gt;&#10;&lt;li&gt;Accidental: tooling limitations (manual compilation, lack of IDEs) that technology can mitigate.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Central thesis&lt;/strong&gt;: innovations (OO, AI, higher-level languages) alone won’t deliver 10x productivity across the board.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Potential breakthroughs&lt;/strong&gt;: rapid prototyping, incremental development, empowering great designers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Critique of techno-optimism&lt;/strong&gt;: automating accidental tasks doesn’t fix mis-specified requirements or poor communication.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Relates to discussions on technical debt (unmanaged accidental complexity).&lt;/li&gt;&#10;&lt;li&gt;Anticipates agile principles (short iterations, prototyping).&lt;/li&gt;&#10;&lt;li&gt;Aligns with critiques of low-code/no-code as silver bullets.&lt;/li&gt;&#10;&lt;li&gt;Connects to cognitive complexity in distributed systems.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Where do modern frameworks (React, Kubernetes) fall in essence vs accidents?&lt;/li&gt;&#10;&lt;li&gt;Does generative AI (Copilot) confirm or challenge Brooks’ predictions?&lt;/li&gt;&#10;&lt;li&gt;Has cloud computing reduced essential complexity or just moved it around?&lt;/li&gt;&#10;&lt;li&gt;Do DORA metrics (deployment frequency, etc.) mostly track accidental difficulties?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Essential/accidental distinction explains why microservices fix operational issues but add systemic complexity.&lt;/li&gt;&#10;&lt;li&gt;Emphasising “great designers” foreshadows Site Reliability Engineering and other multiplier roles.&lt;/li&gt;&#10;&lt;li&gt;Invisibility still critical in distributed architectures; justifies heavy investment in observability.&lt;/li&gt;&#10;&lt;li&gt;Incremental evolution (“UNIX philosophy”) continues to beat grand revolutions.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Essential difficulties: complexity, conformity, invisibility, cost of change.&lt;/li&gt;&#10;&lt;li&gt;Accidental wins: high-level languages, IDEs, CI/CD automation.&lt;/li&gt;&#10;&lt;li&gt;Suggested strategies: buy vs build, rapid prototyping, nurture expert designers.&lt;/li&gt;&#10;&lt;li&gt;Predictions validated: OOP aided encapsulation but didn’t eliminate logic bugs; open source helped with accidental costs, not conflicting requirements.&lt;/li&gt;&#10;&lt;li&gt;Quote: “Complexity is the soul of software; there is no silver bullet.”&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Brooks, F. P. Jr. (1986). &lt;em&gt;No Silver Bullet: Essence and Accidents of Software Engineering&lt;/em&gt;. (Link: &lt;a href="http://www.cs.unc.edu/techreports/86-020.pdf" target="_blank" rel="noreferrer"&gt;http://www.cs.unc.edu/techreports/86-020.pdf&lt;/a&gt;)&lt;/li&gt;&#10;&lt;li&gt;Additional commentary and analyses (ACM DL, Wikipedia, etc.).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;li&gt;[[software-aging-1994|Software Aging]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Software Aging</title><link>https://osmarpetry.dev/blog/software-aging-1994/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/software-aging-1994/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;David L. Parnas likens software aging to biological aging: over time, software becomes harder to maintain, less efficient, and more failure-prone. Maturity in software engineering requires prioritizing long-term health over first releases. Preventive practices can slow aging but cannot eliminate it.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Software aging is inevitable but manageable through disciplined engineering.&lt;/li&gt;&#10;&lt;li&gt;Two main accelerants:&lt;/li&gt;&#10;&lt;li&gt;Inability to update software as business needs change.&lt;/li&gt;&#10;&lt;li&gt;Accumulation of ignorance due to team turnover and poor documentation.&lt;/li&gt;&#10;&lt;li&gt;Aging costs: lost competitiveness, increased defects, degraded performance, higher maintenance effort.&lt;/li&gt;&#10;&lt;li&gt;Preventive “medicine”: design for change, thorough documentation, frequent code reviews.&lt;/li&gt;&#10;&lt;li&gt;Critiques the focus on initial releases and lack of systematic engineering practices.&lt;/li&gt;&#10;&lt;li&gt;Documentation is essential despite agile tendencies to downplay it.&lt;/li&gt;&#10;&lt;li&gt;Suggests planning for software “retirement” as part of lifecycle management.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Links to discussions of technical debt and legacy systems.&lt;/li&gt;&#10;&lt;li&gt;Resonates with sustainability narratives and maintaining long-lived open source projects.&lt;/li&gt;&#10;&lt;li&gt;Contrasts with agile manifesto statements about documentation.&lt;/li&gt;&#10;&lt;li&gt;Aligns with DevOps practices emphasizing observability and continuous improvement.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to objectively measure software aging across domains?&lt;/li&gt;&#10;&lt;li&gt;Which documentation practices balance agility with sustainable knowledge?&lt;/li&gt;&#10;&lt;li&gt;How to adapt recommendations for small teams or short-lived projects?&lt;/li&gt;&#10;&lt;li&gt;Differences in aging patterns between proprietary and open source software?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aging metaphor helps analyze system trajectories, especially with high team turnover.&lt;/li&gt;&#10;&lt;li&gt;Highlights challenges seen in both public and private IT projects lacking systematic processes.&lt;/li&gt;&#10;&lt;li&gt;“Retirement plan” concept is valuable for interviewing IT managers.&lt;/li&gt;&#10;&lt;li&gt;Reinforces importance of documentation and review in case studies.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aging compared to humans: inevitable but mitigable via prevention and care.&lt;/li&gt;&#10;&lt;li&gt;Focus should shift to system health over first release success.&lt;/li&gt;&#10;&lt;li&gt;Aging factors recorded from various talks (timestamps included in original note).&lt;/li&gt;&#10;&lt;li&gt;Emphasis on design for change, documentation, code reviews.&lt;/li&gt;&#10;&lt;li&gt;Recognize when software becomes unreliable; apply re-modularization and documentation retrofits.&lt;/li&gt;&#10;&lt;li&gt;Plan for end-of-support lifecycle as part of responsible engineering.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Parnas, D. L. (1994). &lt;em&gt;Software Aging&lt;/em&gt;. Proceedings of ICSE 16.&lt;/li&gt;&#10;&lt;li&gt;Article PDF: &lt;a href="http://www.inf.ed.ac.uk/teaching/courses/seoc/2004_2005/resources/bullet11.pdf" target="_blank" rel="noreferrer"&gt;http://www.inf.ed.ac.uk/teaching/courses/seoc/2004_2005/resources/bullet11.pdf&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Talk: &lt;a href="https://youtu.be/fe8Mp1YOjQI" target="_blank" rel="noreferrer"&gt;https://youtu.be/fe8Mp1YOjQI&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[conways-law-birth-1968|Conway’s Law — origins, literature, and team design]]&lt;/li&gt;&#10;&lt;li&gt;[[DbC|Design by Contract]]&lt;/li&gt;&#10;&lt;li&gt;[[no-silver-bullet-1986|No Silver Bullet — Essence &amp;amp; Accidents]]&lt;/li&gt;&#10;&lt;li&gt;[[parnas-modularization-1972|Modularization Criteria — Parnas 1972]]&lt;/li&gt;&#10;&lt;li&gt;[[shape-up-2020|Shape Up: Stop Running in Circles and Ship Work that Matters]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>TDD Effects on Quality and Productivity</title><link>https://osmarpetry.dev/blog/tdd-systematic-review-2016/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/tdd-systematic-review-2016/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Systematic review of 27 empirical studies (1999–2014) on Test-Driven Development (TDD). Evaluates internal code quality, external product quality, and productivity. Findings: TDD generally improves cohesion and reduces coupling; external quality gains are observed in 88% of cases; productivity results vary, showing improvements in academic settings but a decrease in industrial environments.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Internal quality:&lt;/strong&gt; Improves in 76% of evaluated cases, showing lower coupling, reduced cyclomatic complexity, and higher cohesion (often measured via CK Metrics).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;External quality:&lt;/strong&gt; Positive impact in 88% of the scenarios, with significant defect reduction in critical systems.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Productivity:&lt;/strong&gt; Mixed outcomes. Academic environments reported speed gains, while industrial settings reported a productivity dip.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Moderators:&lt;/strong&gt; Prior unit testing experience and continuous integration adoption amplify benefits.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; Selection bias, uncontrolled environmental variables, self-reported productivity metrics.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Aligns with Clean Code principles and CK metrics usage.&lt;/li&gt;&#10;&lt;li&gt;Supports discussions on technical debt in agile processes.&lt;/li&gt;&#10;&lt;li&gt;Contrasts with test-last approaches in rapid prototyping.&lt;/li&gt;&#10;&lt;li&gt;Relates to research on developer psychology and TDD adoption.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to tailor TDD for volatile requirements?&lt;/li&gt;&#10;&lt;li&gt;What is the maintenance cost of large test suites over time?&lt;/li&gt;&#10;&lt;li&gt;Are metrics like branch coverage sufficient to gauge TDD effectiveness?&lt;/li&gt;&#10;&lt;li&gt;How does TDD coexist with generative AI in testing workflows?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;TDD excels for complex business logic; less so for simple CRUD modules.&lt;/li&gt;&#10;&lt;li&gt;CK metrics help quantify internal quality gains.&lt;/li&gt;&#10;&lt;li&gt;Variability explains why some companies abandon TDD after superficial adoption.&lt;/li&gt;&#10;&lt;li&gt;Integrating TDD with BDD could boost external quality.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Methodology:&lt;/strong&gt; PRISMA-based review of 27 empirical studies.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Variables:&lt;/strong&gt; Internal quality (CBO, LCOM, WMC, RFC), external quality (defects, MTBF, user satisfaction), productivity (delivery speed, cognitive effort).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Results:&lt;/strong&gt; 76% of cases showed increased internal quality (coupling reduction, ~20% cohesion increase, lower cyclomatic complexity); 88% showed increased external quality (defect reduction); proficiency reached after initial productivity dip, mostly observed in academic scenarios.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limitations:&lt;/strong&gt; Many studies lacked controls for prior testing expertise; productivity data often self-reported; publication bias toward positive outcomes.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="example-in-go"&gt;Example in Go&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;testing&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestCPFRejectsAllZero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;00000000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;All-zero CPF should be invalid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TestCPFValidKnownValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;52998224725&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Valid CPF was rejected&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Simplified logic for example&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bissi, W., Seca Neto, A. G. S., &amp;amp; Emer, M. C. F. P. (2016). The effects of test driven development on internal quality, external quality and productivity: A systematic review. &lt;em&gt;Information and Software Technology&lt;/em&gt;. &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/S0950584916300222" target="_blank" rel="noreferrer"&gt;https://www.sciencedirect.com/science/article/abs/pii/S0950584916300222&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Additional supporting documents (ResearchGate, CK Metrics literature).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Gophers Workshop — Deploy-First Go Architecture. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Gophers Workshop — Deploy-First Go Architecture&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Design &amp;amp;amp; Analysis of Algorithms — Course Overview. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Design &amp;amp; Analysis of Algorithms — Course Overview&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Assembly Study Plan. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Assembly Study Plan&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="post-inline-link" href="https://osmarpetry.dev/blog/bdd/"&gt;BDD&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Code Smells and Maintainability. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Code Smells and Maintainability&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;span&#10; class="post-inline-link--missing"&#10; aria-label="Enterprise UI Development — Testing, Standards, and Ego Control. Page does not exist."&#10; title="Page does not exist."&#10; data-tooltip-message="Page does not exist."&#10; &gt;Enterprise UI Development — Testing, Standards, and Ego Control&lt;/span&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a class="post-inline-link" href="https://osmarpetry.dev/blog/testing-concepts-notes/"&gt;Testing Concepts Notes&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Teach Yourself Programming in Ten Years</title><link>https://osmarpetry.dev/blog/teach-yourself-programming-ten-years-2001/</link><pubDate>Tue, 15 Apr 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/teach-yourself-programming-ten-years-2001/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;&#10;&lt;p&gt;Peter Norvig critiques promises of learning programming in weeks. Drawing on research in chess, music, and sports, he argues true mastery requires about ten years of deliberate practice—progressive challenges, feedback, and continual improvement. There are no shortcuts: success comes from sustained effort and critical self-analysis.&lt;/p&gt;&#10;&lt;h2 id="key-points"&gt;Key points&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Questions the abundance of “Learn X in 24 Hours/21 Days” books.&lt;/li&gt;&#10;&lt;li&gt;Excellence in any complex field typically demands ~10 years of deliberate practice (citing K. Anders Ericsson’s work).&lt;/li&gt;&#10;&lt;li&gt;Historical examples (Mozart, Beatles) show their peak came only after years of intense practice.&lt;/li&gt;&#10;&lt;li&gt;No magical formulas; commitment to long-term learning is essential.&lt;/li&gt;&#10;&lt;li&gt;Practical advice: explore multiple languages, seek challenges, learn from peers, blend theory with real projects.&lt;/li&gt;&#10;&lt;li&gt;Books alone are insufficient; hands-on experience is irreplaceable.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="connections"&gt;Connections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Ties to deliberate practice theory and Malcolm Gladwell’s “10,000 hours” popularisation.&lt;/li&gt;&#10;&lt;li&gt;Informs discussions on computing education and depth vs superficial knowledge.&lt;/li&gt;&#10;&lt;li&gt;Supports lifelong learning and career development perspectives in tech.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="questions"&gt;Questions&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;How to balance theory and deliberate practice?&lt;/li&gt;&#10;&lt;li&gt;Does the “ten-year” model apply uniformly across computing domains?&lt;/li&gt;&#10;&lt;li&gt;How to maintain motivation through multi-year learning journeys?&lt;/li&gt;&#10;&lt;li&gt;Which strategies accelerate progress without sacrificing depth?&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="personal-reflections"&gt;Personal reflections&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Reinforces patience and persistence when building programming expertise.&lt;/li&gt;&#10;&lt;li&gt;Relevant to today’s culture of immediacy—reminds us depth takes time.&lt;/li&gt;&#10;&lt;li&gt;Agrees that combining study, deliberate practice, and real projects yields steady growth.&lt;/li&gt;&#10;&lt;li&gt;Encourages valuing the learning process rather than chasing quick wins.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="detailed-notes"&gt;Detailed notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Abundance of quick-learning resources doesn’t reflect real mastery requirements.&lt;/li&gt;&#10;&lt;li&gt;Deliberate practice: constant challenge, error analysis, improvement.&lt;/li&gt;&#10;&lt;li&gt;Role of mentors, community, and diverse language exposure.&lt;/li&gt;&#10;&lt;li&gt;Suggested languages: Python, Scheme, JavaScript, Alice, Squeak, Blockly (depending on learner profile).&lt;/li&gt;&#10;&lt;li&gt;“Ten years” is illustrative; the key is sustained, deliberate work.&lt;/li&gt;&#10;&lt;li&gt;Original essay: &lt;a href="https://norvig.com/21-days.html" target="_blank" rel="noreferrer"&gt;https://norvig.com/21-days.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>JavaScript Sets, Maps, and Hashing</title><link>https://osmarpetry.dev/blog/javascript-set-map-hash/</link><pubDate>Sun, 09 Feb 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-set-map-hash/</guid><description>&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Notes captured on 2025-02-09 during Deveficiente algorithms study.&lt;/li&gt;&#10;&lt;li&gt;Set = unique values with O(1) add/remove; Map = key-value store with O(1) lookups.&lt;/li&gt;&#10;&lt;li&gt;Hashing is reference-based for objects; custom equality needs manual hashing/serialization.&lt;/li&gt;&#10;&lt;li&gt;Useful for caching and deduplication; V8 resolves collisions with internal linked lists/trees.&lt;/li&gt;&#10;&lt;li&gt;C# exposes &lt;code&gt;GetHashCode&lt;/code&gt;; in JS you must implement equivalent behaviour explicitly.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="sets"&gt;Sets&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Store unique values; duplicates are ignored.&lt;/li&gt;&#10;&lt;li&gt;Backed by hash tables in engines like V8.&lt;/li&gt;&#10;&lt;li&gt;Typical operations (&lt;code&gt;add&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, &lt;code&gt;has&lt;/code&gt;) run in O(1) on average.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="maps"&gt;Maps&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Store key-value pairs; keys can be any data type.&lt;/li&gt;&#10;&lt;li&gt;Also implemented with hashing for O(1) lookups.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#39;object&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hashing-behaviour"&gt;Hashing behaviour&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Objects/arrays are compared by reference. Two objects with identical structure are not equal unless they share the same reference.&lt;/li&gt;&#10;&lt;li&gt;For custom hash keys (similar to C# &lt;code&gt;GetHashCode&lt;/code&gt;), stringify values or build hashing utilities.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;hashObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;test&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hashObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cached&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cache-patterns"&gt;Cache patterns&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetchFromSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="internal-details-v8"&gt;Internal details (V8)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Hash collisions handled via linked lists or adaptive structures (e.g., small arrays, balanced trees).&lt;/li&gt;&#10;&lt;li&gt;Sparse arrays may convert to hash tables internally for memory efficiency.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="set-vs-map-recap"&gt;Set vs Map recap&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Set&lt;/strong&gt;: unique values.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Map&lt;/strong&gt;: key-value pairs, versatile for caching, memoization.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;MDN: &lt;a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Set" target="_blank" rel="noreferrer"&gt;Set&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map" target="_blank" rel="noreferrer"&gt;Map&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;V8 blog on hash tables and inline caching.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[javascript-closures-and-curries|Closures and Curries]]&lt;/li&gt;&#10;&lt;li&gt;[[react-forwardRef|Forwarding Ref]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ADR — Architecture Decision Records</title><link>https://osmarpetry.dev/blog/adr/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/adr/</guid><description>&lt;p&gt;ADRs (Architecture Decision Records) are essential documents in software engineering that capture important architectural choices and the context behind them. In an Obsidian vault, ADRs integrate naturally into project documentation.&lt;/p&gt;&#10;&lt;h2 id="why-use-adrs"&gt;Why use ADRs?&lt;/h2&gt;&#10;&lt;p&gt;In long-running projects — such as framework migrations or service changes in Go or Java — decisions change constantly. Without recording &lt;em&gt;why&lt;/em&gt; a tool was chosen over another, the team (or even yourself) may forget the reasoning months later, losing the context that justified the choice.&lt;/p&gt;</description></item><item><title>Agile Software Development</title><link>https://osmarpetry.dev/blog/agile/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/agile/</guid><description>&lt;p&gt;Agile is a set of values and principles for software development that emphasizes flexibility, collaboration, and iterative delivery. Rather than following a rigid plan, Agile teams adapt to changing requirements and deliver working software frequently.&lt;/p&gt;&#10;&lt;h2 id="what-is-agile"&gt;What is Agile?&lt;/h2&gt;&#10;&lt;p&gt;Agile is not a single methodology but rather a philosophy that encompasses various frameworks and practices. The core idea is to break down large projects into smaller, manageable pieces that can be delivered incrementally.&lt;/p&gt;</description></item><item><title>Behavior-Driven Development (BDD)</title><link>https://osmarpetry.dev/blog/bdd/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/bdd/</guid><description>&lt;h2 id="what-is-bdd"&gt;What Is BDD&lt;/h2&gt;&#10;&lt;p&gt;BDD bridges the gap between business stakeholders and developers by expressing requirements as executable specifications. Instead of writing tests after the fact, you describe the &lt;strong&gt;expected behavior&lt;/strong&gt; of the system in plain language, then automate those descriptions.&lt;/p&gt;&#10;&lt;p&gt;The core loop: &lt;strong&gt;Discovery&lt;/strong&gt; (what should the system do?) → &lt;strong&gt;Formulation&lt;/strong&gt; (write it in Gherkin) → &lt;strong&gt;Automation&lt;/strong&gt; (implement step definitions).&lt;/p&gt;&#10;&lt;h2 id="bdd-vs-tdd"&gt;BDD vs TDD&lt;/h2&gt;&#10;&lt;p&gt;TDD focuses on unit-level correctness (&amp;ldquo;does this function return the right value?&amp;rdquo;). BDD focuses on system-level behavior (&amp;ldquo;does this feature work from the user&amp;rsquo;s perspective?&amp;rdquo;). In practice they complement each other — use TDD for internal logic, BDD for acceptance and integration tests.&lt;/p&gt;</description></item><item><title>Closures and Curries</title><link>https://osmarpetry.dev/blog/javascript-closures-and-curries/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-closures-and-curries/</guid><description>&lt;p&gt;Closures and currying are both important concepts in JavaScript, especially for functional programming.&lt;/p&gt;&#10;&lt;h2 id="closure"&gt;Closure&lt;/h2&gt;&#10;&lt;p&gt;A closure is a function that has access to its outer scope even after the outer function has returned. It &amp;ldquo;closes over&amp;rdquo; its outer scope, hence the name. Here&amp;rsquo;s an example:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;outerFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;innerFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;outerFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;add5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 8&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the above example, &lt;code&gt;**innerFunction**&lt;/code&gt; has access to &lt;code&gt;**x**&lt;/code&gt; even after &lt;code&gt;**outerFunction**&lt;/code&gt; has returned. This allows us to keep state across multiple invocations of the inner function.&#10;We can use closures to store a function with a first parameter, you can see an example here:&#10;&lt;a href="https://paper-attachments.dropbox.com/s_7A088D71FB9B829C04A17241E13BE66493C6164E2DA798BD85C153CC4FEC5AE3_1566590561542_Screenshot&amp;#43;from&amp;#43;2019-08-23&amp;#43;17-02-30.png" target="_blank" rel="noreferrer"&gt;&lt;img src="https://paper-attachments.dropbox.com/s_7A088D71FB9B829C04A17241E13BE66493C6164E2DA798BD85C153CC4FEC5AE3_1566590561542_Screenshot+from+2019-08-23+17-02-30.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Design Patterns</title><link>https://osmarpetry.dev/blog/design-patterns/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/design-patterns/</guid><description>&lt;h2 id="presentation-intent"&gt;Presentation Intent&lt;/h2&gt;&#10;&lt;p&gt;Prepare the presentation with a clear script of intentions.&lt;/p&gt;&#10;&lt;p&gt;Explain how to read the book and how, by recognizing similar patterns, you create connections between them and discover different perspectives on the same problem. In some cases, this leads to other ways—or better ways—to apply a different pattern.&lt;/p&gt;&#10;&lt;p&gt;Another pattern can sometimes feel very similar to the one you are reading. The point is to think beyond the current chapter and compare intent, structure, and trade-offs.&lt;/p&gt;</description></item><item><title>Domain-Driven Design: Tackling Complexity in the Heart of Software</title><link>https://osmarpetry.dev/blog/ddd/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/ddd/</guid><description>&lt;p&gt;Domain-Driven Design (DDD) is a software design approach that focuses on modeling complex systems based on the real-world domains or concepts they represent. The aim is to tackle complexity in the heart of software by aligning the development process with the business domain, using a common language, and creating models that capture the behavior and relationships of the system. DDD emphasizes the importance of designing software around the concepts and processes of the business domain, rather than just technical implementation. It encourages communication and collaboration between the development team and business stakeholders, and promotes the use of models as the primary driver for design decisions. The end result is a software solution that better reflects the needs and requirements of the business domain, and is more maintainable, scalable and adaptable over time.&lt;/p&gt;</description></item><item><title>Mapped Types and Generics</title><link>https://osmarpetry.dev/blog/typescript-mapped-types-and-generics/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/typescript-mapped-types-and-generics/</guid><description>&lt;p&gt;Mapped types and generics are two of TypeScript&amp;rsquo;s most powerful tools for writing reusable, type-safe utilities without duplicating type definitions.&lt;/p&gt;&#10;&lt;p&gt;A &lt;strong&gt;generic&lt;/strong&gt; lets you write a function or type that works over &lt;em&gt;any&lt;/em&gt; type while still preserving type information — think of it as a type-level parameter. A &lt;strong&gt;mapped type&lt;/strong&gt; iterates over the keys of an existing type and transforms each one, letting you derive new types mechanically from existing shapes rather than rewriting them by hand.&lt;/p&gt;</description></item><item><title>Optimizing React with Memoization</title><link>https://osmarpetry.dev/blog/react-optimizing-with-memoization/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/react-optimizing-with-memoization/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;It’s important to understand the component lifecycle and when to re-render. Some tips to optimize React include:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Use useMemo or memo to memoize expensive calculations or component render.&lt;/li&gt;&#10;&lt;li&gt;Use useCallback to memoize callback functions.&lt;/li&gt;&#10;&lt;li&gt;Use React.PureComponent instead of React.Component for pure components.&lt;/li&gt;&#10;&lt;li&gt;Use shouldComponentUpdate lifecycle method to avoid unnecessary re-renders.&lt;/li&gt;&#10;&lt;li&gt;Avoid using the state for non-essential data that does not affect the render.&lt;/li&gt;&#10;&lt;li&gt;Avoid using too many inline functions and use memoized callback functions instead.&#10;It is important to note that the most important aspect of optimization is to understand the performance bottlenecks in your application and address them accordingly.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="usememo"&gt;useMemo&lt;/h2&gt;&#10;&lt;p&gt;This is a hook that is used to memoize a component&amp;rsquo;s expensive calculations. It helps to reduce the number of re-renders by only recalculating the value when one of its dependencies has changed. It takes two arguments, the first being a calculation function and the second being an array of dependencies. If the dependencies change, the calculation function will be re-executed, otherwise, the previously calculated value is returned, example:&lt;/p&gt;</description></item><item><title>Prototype</title><link>https://osmarpetry.dev/blog/javascript-prototype/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-prototype/</guid><description>&lt;p&gt;Every object in JavaScript has an internal link to another object called its &lt;strong&gt;prototype&lt;/strong&gt;. When you access a property that doesn&amp;rsquo;t exist on an object, the engine walks up this chain — prototype by prototype — until it finds the property or reaches &lt;code&gt;null&lt;/code&gt;. This is the &lt;strong&gt;prototype chain&lt;/strong&gt;, and it is the mechanism behind all inheritance in JavaScript.&lt;/p&gt;&#10;&lt;p&gt;Understanding prototypes is essential because &lt;code&gt;class&lt;/code&gt; syntax in ES6 is just syntactic sugar over this system. Under the hood, &lt;code&gt;extends&lt;/code&gt; sets up the same prototype chain. Knowing the raw model helps debug unexpected property lookups, &lt;code&gt;instanceof&lt;/code&gt; checks, and performance issues around deep prototype chains.&lt;/p&gt;</description></item><item><title>React ForwardRef</title><link>https://osmarpetry.dev/blog/react-forwardref/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/react-forwardref/</guid><description>&lt;p&gt;By default, React does not let a parent component access the DOM node of a child component. &lt;code&gt;forwardRef&lt;/code&gt; breaks that boundary explicitly — the child opts in to exposing its DOM node (or instance) to whoever holds the ref.&lt;/p&gt;&#10;&lt;p&gt;The typical need is imperative control from a parent: focusing an input inside a design-system &lt;code&gt;&amp;lt;Input&amp;gt;&lt;/code&gt; wrapper, scrolling a &lt;code&gt;&amp;lt;List&amp;gt;&lt;/code&gt; to a specific row, or triggering animations on a child element. Without &lt;code&gt;forwardRef&lt;/code&gt;, the parent would need to own the DOM directly, which defeats the purpose of encapsulation.&lt;/p&gt;</description></item><item><title>React.Suspense</title><link>https://osmarpetry.dev/blog/react-suspense/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/react-suspense/</guid><description>&lt;p&gt;&lt;code&gt;React.Suspense&lt;/code&gt; is a boundary component that lets you declaratively specify a fallback UI while its children are &amp;ldquo;suspended&amp;rdquo; — waiting for code to load or, in frameworks like Next.js/Remix, for async data to resolve. It decouples the loading concern from the component that needs the data, keeping each piece focused on its own responsibility.&lt;/p&gt;&#10;&lt;h2 id="why-use-suspense"&gt;Why use Suspense&lt;/h2&gt;&#10;&lt;p&gt;Suspense lets you declaratively handle loading states for code-splitting and async data (with frameworks that support it). It improves first-load performance and keeps your UI logic focused on states that matter.&lt;/p&gt;</description></item><item><title>Recursion</title><link>https://osmarpetry.dev/blog/javascript-recursion/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-recursion/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;countDownFrom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;countDownFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;countDownFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Should output&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 10&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 9&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 8&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;function call themselves - Screenshot from &lt;a href="https://www.youtube.com/@funfunfunction" target="_blank" rel="noreferrer"&gt;Fun Fun Function&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;animals&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mammals&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;animals&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cats&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mammals&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dogs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mammals&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;chihuahua&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dogs&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;labrador&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dogs&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;persian&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cats&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;siamese&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cats&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;];&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;makeTree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;categories&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;makeTree(categories, null) - Screenshot from &lt;a href="https://www.youtube.com/@funfunfunction" target="_blank" rel="noreferrer"&gt;Fun Fun Function&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;Recursion is a technique in programming where a function calls itself repeatedly until a specific condition is met. This allows solving complex problems by breaking them down into smaller, easier to solve sub-problems.&lt;/p&gt;</description></item><item><title>Shape Up: Stop Running in Circles and Ship Work that Matters</title><link>https://osmarpetry.dev/blog/shape-up-2020/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/shape-up-2020/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;In December 2020 I read several books and papers: &lt;strong&gt;The Mythical Man-Month&lt;/strong&gt;, &lt;strong&gt;Design by Contract&lt;/strong&gt;, &lt;strong&gt;Programming with Abstract Data Types&lt;/strong&gt;, &lt;strong&gt;Shape Up&lt;/strong&gt;, and &lt;strong&gt;Domain-Driven Design&lt;/strong&gt;. Their ideas map directly to problems and solutions I encountered building apps in recent years.&#10;The largest recurring gap in real projects is the &lt;strong&gt;beginning&lt;/strong&gt;—how we &lt;strong&gt;shape&lt;/strong&gt; and refine the work—more than the middle or the end. &lt;strong&gt;Shape Up&lt;/strong&gt; gives a concrete way to close that gap in modern teams.&lt;/p&gt;</description></item><item><title>SVG Are the Best</title><link>https://osmarpetry.dev/blog/svg-are-the-best/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/svg-are-the-best/</guid><description>&lt;p&gt;SVG and icon fonts can solve similar problems, especially for icons. However, icon fonts must be downloaded correctly and mapped to the expected glyphs. When that fails, users may see empty squares or broken characters. SVG does not have that problem because the graphic itself is rendered directly.&lt;/p&gt;&#10;&lt;h2 id="svg-vs-font-icons"&gt;SVG vs. Font Icons&lt;/h2&gt;&#10;&lt;p&gt;Both approaches can be used for icons, but SVG is usually the better choice.&lt;/p&gt;&#10;&lt;h3 id="why-svg-is-better"&gt;Why SVG is better&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;It does not depend on a font being loaded correctly&lt;/li&gt;&#10;&lt;li&gt;It can be styled and animated with CSS&lt;/li&gt;&#10;&lt;li&gt;It scales well across screen sizes&lt;/li&gt;&#10;&lt;li&gt;It works well for diagrams, illustrations, and UI icons&lt;/li&gt;&#10;&lt;li&gt;It supports filters and visual effects&lt;/li&gt;&#10;&lt;li&gt;It is accessible when used correctly&lt;/li&gt;&#10;&lt;li&gt;It exists as structured markup in the DOM&lt;/li&gt;&#10;&lt;li&gt;It is code, so it can be versioned, reviewed, and edited easily&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="svg-benefits"&gt;SVG Benefits&lt;/h2&gt;&#10;&lt;h3 id="1-interactive-and-stylable-with-css"&gt;1. Interactive and stylable with CSS&lt;/h3&gt;&#10;&lt;p&gt;SVG elements can be targeted directly with CSS. You can change properties such as &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;stroke&lt;/code&gt;, &lt;code&gt;opacity&lt;/code&gt;, &lt;code&gt;transform&lt;/code&gt;, and more.&lt;/p&gt;</description></item><item><title>TensorFlow</title><link>https://osmarpetry.dev/blog/tensorflow/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/tensorflow/</guid><description>&lt;p&gt;Imagine you work at an online clothing store. Every day, thousands of product photos arrive and someone needs to tag each one: is it a t-shirt? A sneaker? A bag? Doing this by hand is painfully slow, so you decide to teach a computer to do it for you. That&amp;rsquo;s exactly the kind of problem &lt;strong&gt;Fashion MNIST&lt;/strong&gt; was designed to solve — and it&amp;rsquo;s a perfect first project to understand how neural networks learn to see.&lt;/p&gt;</description></item><item><title>This Object Inside Call, Apply and Bind</title><link>https://osmarpetry.dev/blog/javascript-this-object-inside-call-apply-and-bind/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/javascript-this-object-inside-call-apply-and-bind/</guid><description>&lt;p&gt;JavaScript has four rules that determine what &lt;code&gt;this&lt;/code&gt; refers to inside a function: implicit binding, explicit binding (&lt;code&gt;.call&lt;/code&gt;, &lt;code&gt;.apply&lt;/code&gt;, &lt;code&gt;.bind&lt;/code&gt;), &lt;code&gt;new&lt;/code&gt; binding, and window binding. Understanding these rules is essential because &lt;code&gt;this&lt;/code&gt; behaves differently depending on how and where a function is called — not where it is defined.&lt;/p&gt;&#10;&lt;p&gt;At &lt;strong&gt;AutoLot&lt;/strong&gt;, the car dealership platform, the team kept running into bugs where &lt;code&gt;this&lt;/code&gt; was &lt;code&gt;undefined&lt;/code&gt; or pointed to &lt;code&gt;window&lt;/code&gt; instead of the expected object. Once they mapped each scenario to one of the four binding rules, those bugs disappeared.&lt;/p&gt;</description></item><item><title>Typescript Overwrite Types</title><link>https://osmarpetry.dev/blog/typescript-overwrite-types/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/typescript-overwrite-types/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;This is a simple example of how to overwrite types from a library. When you do not want to use &lt;code&gt;Pick&lt;/code&gt; or &lt;code&gt;Omit&lt;/code&gt;, this strategy can be a good option.&lt;/p&gt;&#10;&lt;h2 id="example"&gt;Example&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@maas-components/button&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The content of the button.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;children?&lt;/span&gt;: &lt;span class="kt"&gt;React.ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The color of the component. It supports those theme colors&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * that make sense for this component.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;inherit&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;primary&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;secondary&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;danger&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;success&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * If `true`, the button will be disabled.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;disabled?&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * If `true`, no elevation is used.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;disableElevation?&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * If `true`, the keyboard focus ripple will be disabled.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;disableFocusRipple?&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Element placed after the children.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;endIcon?&lt;/span&gt;: &lt;span class="kt"&gt;React.ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * If `true`, the button will take up the full width of its container.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;fullWidth?&lt;/span&gt;: &lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The URL to link to when the button is clicked.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * If defined, an `a` element will be used as the root node.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;href?&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The size of the button.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * `small` is equivalent to the dense button styling.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;small&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;medium&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;large&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Element placed before the children.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;startIcon?&lt;/span&gt;: &lt;span class="kt"&gt;React.ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The variant to use.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;outlined&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;contained&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * Can be set to circle, square, or omitted.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;circle&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;square&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cm"&gt;/**&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; * The styles in className.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt; */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;className?&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;type&lt;/span&gt;&lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;submit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;onClick?&lt;/span&gt;: &lt;span class="kt"&gt;React.MouseEventHandler&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// eslint-disable-next-line react/prefer-stateless-function&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;: &lt;span class="kt"&gt;React.FC&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[typescript-mapped-types-and-generics|Mapped Types and Generics]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>useRef</title><link>https://osmarpetry.dev/blog/react-useref/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/react-useref/</guid><description>&lt;p&gt;&lt;code&gt;useRef&lt;/code&gt; gives you a mutable container — &lt;code&gt;{ current: value }&lt;/code&gt; — that persists for the full lifetime of the component without triggering re-renders when changed. This makes it the right tool for two distinct jobs: holding a reference to a DOM node for imperative operations, and storing any mutable value that your component needs to remember across renders but that should &lt;em&gt;not&lt;/em&gt; drive the UI.&lt;/p&gt;&#10;&lt;p&gt;The key mental model: &lt;code&gt;useState&lt;/code&gt; is for values that should be &lt;em&gt;shown&lt;/em&gt;; &lt;code&gt;useRef&lt;/code&gt; is for values that should be &lt;em&gt;remembered&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>Master’s Article Summaries</title><link>https://osmarpetry.dev/blog/masters-article-summaries/</link><pubDate>Wed, 04 Sep 2024 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/masters-article-summaries/</guid><description>&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Replay attacks remain the easiest ASV spoofing vector; DL-RAD, autoencoders + Siamese networks, and CQCC features significantly improve detection.&lt;/li&gt;&#10;&lt;li&gt;ASVspoof 2021 pushes detection into real-world, noisy settings requiring domain generalisation.&lt;/li&gt;&#10;&lt;li&gt;Remote sensing (NEON/NIST) mirrors the need for multi-source data fusion—hyperspectral, LiDAR, RGB—for ecological insights.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="spied-articles"&gt;SPIED articles&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Ren et al. — Replay attack detection via loudspeaker distortion (DL-RAD).&lt;/li&gt;&#10;&lt;li&gt;ASVspoof 2021 — Spoofed/deepfake speech detection in the wild.&lt;/li&gt;&#10;&lt;li&gt;NIST DSE — Plant identification with airborne remote sensing.&lt;/li&gt;&#10;&lt;li&gt;Adiban et al. — Autoencoder + Siamese countermeasures on ASVspoof 2019.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="context"&gt;Context&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Consolidated notes from 4 September 2024 research sprint.&lt;/li&gt;&#10;&lt;li&gt;Focus: voice authentication security (spoofing/deepfake) and ecological remote sensing.&lt;/li&gt;&#10;&lt;li&gt;Supporting docs: ZIP archive with slides/text; online share for extended summaries.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="1-replay-attack-detection-based-on-distortion-by-loudspeaker"&gt;1. Replay Attack Detection Based on Distortion by Loudspeaker&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt;: Ren et al., &lt;em&gt;Multimedia Tools and Applications&lt;/em&gt;, 2019. DOI: 10.1007/s11042-018-6834-3.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: DL-RAD detects replay attacks by analysing loudspeaker-induced distortions (low-frequency attenuation, harmonic energy).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Highlights&lt;/strong&gt;: Harmonic Energy Ratio, Low Spectral Variance. Achieves &amp;gt;98% detection accuracy.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Application&lt;/strong&gt;: voice authentication systems (mobile, banking). Focus on dependable feature extraction.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: Consider how speaker hardware signatures can serve as anti-spoof signals.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="2-asvspoof-2021-deepfake-speech-detection-in-the-wild"&gt;2. ASVspoof 2021: Deepfake Speech Detection in the Wild&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt;: ASVspoof 2021 challenge; TASLP 2023 paper (DOI: 10.1109/TASLP.2023.3285283).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Evaluates spoofed/deepfake detection in noisy, uncontrolled environments; introduces large-scale dataset.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Highlights&lt;/strong&gt;: Variance across capture devices, environmental noise; combination of spectrogram analysis and deep models.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Application&lt;/strong&gt;: deploy robust detectors for real-world ASV systems, banking, call centers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: emphasises the need for adaptive models and domain generalization.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="3-nist-dse-plant-identification-with-remote-sensing"&gt;3. NIST DSE Plant Identification with Remote Sensing&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt;: NIST publication on airborne remote sensing data challenge.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Integrates hyperspectral, LiDAR, RGB data to segment tree crowns, align field data, classify species.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Highlights&lt;/strong&gt;: data fusion, scaling ecological monitoring, addressing heterogeneous resolutions.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Application&lt;/strong&gt;: environmental monitoring, conservation, precision agriculture.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: parallels with multi-modal data integration in other domains (e.g., security sensors).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="4-replay-spoofing-countermeasure-using-autoencoder--siamese-networks-asvspoof-2019"&gt;4. Replay Spoofing Countermeasure Using Autoencoder &amp;amp; Siamese Networks (ASVspoof 2019)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Source&lt;/strong&gt;: Adiban et al., &lt;em&gt;Computer Speech &amp;amp; Language&lt;/em&gt;, 2020. DOI: 10.1016/j.csl.2020.101105.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Combines autoencoders (denoising) with Siamese networks (similarity) to detect replay attacks.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Highlights&lt;/strong&gt;: CQCC features, improved EER by 10.73%, t-DCF drop of 0.2344.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Application&lt;/strong&gt;: mobile authentication, payment systems, secure access.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: underscores the power of hybrid feature + metric-learning approaches.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="supporting-docs"&gt;Supporting Docs&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Comparative notes across TXT/PPTX/Google Docs for detailed methodology.&lt;/li&gt;&#10;&lt;li&gt;Extended definitions (CQCC, EER, t-DCF) stored in local dictionary.&lt;/li&gt;&#10;&lt;li&gt;Presentations (March 25) outline challenge evolutions and future work.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="next-steps"&gt;Next steps&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Investigate combined defenses against multi-modal spoofing (synthetic + replay).&lt;/li&gt;&#10;&lt;li&gt;Explore edge deployment viability for real-time detection.&lt;/li&gt;&#10;&lt;li&gt;Compare ecological data pipelines with security workflows for cross-domain insights.&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Testing Concepts Notes</title><link>https://osmarpetry.dev/blog/testing-concepts-notes/</link><pubDate>Fri, 15 Jan 2021 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/testing-concepts-notes/</guid><description>&lt;h2 id="bdd"&gt;&lt;strong&gt;BDD&lt;/strong&gt;&lt;/h2&gt;&#10;&lt;p&gt;BDD (Behavior Driven Development) is a method of testing where you use &amp;ldquo;Given&amp;rdquo; for the scenario, &amp;ldquo;When&amp;rdquo; for the environment of the action, and &amp;ldquo;Then&amp;rdquo; for the action.&lt;/p&gt;&#10;&lt;p&gt;Imagine &lt;strong&gt;AutoLot&lt;/strong&gt;, a car dealership chain building an online vehicle marketplace. A product manager, a developer, and a QA engineer sit together and write this scenario in plain English:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Given a customer browsing the SUV category&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;When the customer clicks &amp;#34;Schedule Test Drive&amp;#34; on a 2024 Honda CR-V&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Then the test drive request should appear as &amp;#34;pending&amp;#34; in the customer&amp;#39;s dashboard&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is BDD in practice — the three roles agree on the expected behavior before any code is written. The npm package &lt;code&gt;jest-cucumber&lt;/code&gt; lets you map these Gherkin-style scenarios directly to Jest tests.&lt;/p&gt;</description></item><item><title>Testing Library vs Enzyme</title><link>https://osmarpetry.dev/blog/testing-library-vs-enzyme/</link><pubDate>Fri, 15 Jan 2021 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/testing-library-vs-enzyme/</guid><description>&lt;h2 id="introduction"&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/h2&gt;&#10;&lt;p&gt;Testing Library is built around a simple philosophy: the more your tests resemble the way your software is used, the more confidence they can give you. Its three core principles are: tests only break when your app breaks (not when implementation details change), you interact with your app the same way as your users, and built-in selectors find elements the way users do to help you write inclusive code.&lt;/p&gt;</description></item><item><title/><link>https://osmarpetry.dev/resume/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/resume/</guid><description>&lt;h1 id="osmar-petry"&gt;Osmar Petry&lt;/h1&gt;&#10;&lt;h2 id="senior-software-engineer"&gt;Senior Software Engineer&lt;/h2&gt;&#10;&lt;ul class="resume-contact"&gt;&#10; &lt;li&gt;&lt;a href="https://maps.app.goo.gl/Tmg8GqmeqPFwAiLw6" target="_blank" rel="noreferrer"&gt;Luxembourg, LU&lt;/a&gt;&lt;/li&gt;&#10; &lt;li&gt;&lt;a href="tel:+352691375313" target="_blank" rel="noreferrer"&gt;+352 691 375 313&lt;/a&gt;&lt;/li&gt;&#10; &lt;li&gt;&lt;a href="mailto:osmarpetry@gmail.com" target="_blank" rel="noreferrer"&gt;osmarpetry@gmail.com&lt;/a&gt;&lt;/li&gt;&#10; &lt;li&gt;&lt;a href="https://osmarpetry.dev" target="_blank" rel="noreferrer"&gt;osmarpetry.dev&lt;/a&gt;&lt;/li&gt;&#10; &lt;li&gt;&lt;a href="https://github.com/osmarpetry" target="_blank" rel="noreferrer"&gt;github.com/osmarpetry&lt;/a&gt;&lt;/li&gt;&#10; &lt;li&gt;&lt;a href="https://linkedin.com/in/osmarpetry" target="_blank" rel="noreferrer"&gt;linkedin.com/in/osmarpetry&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Luxembourgish-Brazilian Senior Software Engineer with 10+ years building and scaling web and mobile products across EU and US distributed teams. Full-stack delivery across TypeScript and Python: product interfaces in React, Vue and Next.js, backend services with Node.js, FastAPI and Temporal, and the testing, CI/CD and observability practices that keep them reliable in production.&lt;/p&gt;&#10;&lt;h2 id="core-skills"&gt;Core Skills&lt;/h2&gt;&#10;&lt;p&gt;TypeScript, JavaScript, Python, React, Next.js, Vue, Nuxt, Node.js, FastAPI, Pydantic, Temporal, REST APIs, PostgreSQL, Supabase, GraphQL, RAG, Pinecone, Observability, Distributed Tracing, Unit Testing, Jest, Testing Library, Cypress, Playwright, CI/CD, Development and Build Tools, Redux, Storybook, React Native, AWS, GCP, Firebase, Drizzle ORM, Micro Frontends, HTML, CSS, Java&lt;/p&gt;</description></item><item><title>breadcrumb</title><link>https://osmarpetry.dev/styleguide/breadcrumb/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/breadcrumb/</guid><description/></item><item><title>company-logos</title><link>https://osmarpetry.dev/styleguide/company-logos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/company-logos/</guid><description>&lt;p&gt;The whole strip, as it appears on the home page.&lt;/p&gt;</description></item><item><title>hero</title><link>https://osmarpetry.dev/styleguide/hero/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/hero/</guid><description/></item><item><title>navbar</title><link>https://osmarpetry.dev/styleguide/navbar/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/navbar/</guid><description>&lt;p&gt;Takes no arguments; the links come from [[menus.main]] in hugo.toml.&lt;/p&gt;</description></item><item><title>post-card</title><link>https://osmarpetry.dev/styleguide/post-card/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/post-card/</guid><description/></item><item><title>post-row</title><link>https://osmarpetry.dev/styleguide/post-row/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/post-row/</guid><description/></item><item><title>posts-filter</title><link>https://osmarpetry.dev/styleguide/posts-filter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/posts-filter/</guid><description>&lt;p&gt;Each chip is a link to a tag page, so the filter needs no JavaScript.&lt;/p&gt;</description></item><item><title>project-card</title><link>https://osmarpetry.dev/styleguide/project-card/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/project-card/</guid><description/></item><item><title>project-row</title><link>https://osmarpetry.dev/styleguide/project-row/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/project-row/</guid><description/></item><item><title>Projects.</title><link>https://osmarpetry.dev/projects/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/projects/</guid><description>&lt;p&gt;Selected builds, experiments, and technical assessments across product, frontend, backend, and AI work.&lt;/p&gt;</description></item><item><title>prose</title><link>https://osmarpetry.dev/styleguide/prose/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/prose/</guid><description>&lt;p&gt;Obsidian wikilinks resolve here. A missing target renders as a marker instead of a dead link.&lt;/p&gt;</description></item><item><title>section-heading</title><link>https://osmarpetry.dev/styleguide/section-heading/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/section-heading/</guid><description/></item><item><title>slide-card</title><link>https://osmarpetry.dev/styleguide/slide-card/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/slide-card/</guid><description/></item><item><title>slide-row</title><link>https://osmarpetry.dev/styleguide/slide-row/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/slide-row/</guid><description/></item><item><title>Slides.</title><link>https://osmarpetry.dev/slides/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/slides/</guid><description>&lt;p&gt;Presentation decks from talks, workshops, and university seminars I have given.&lt;/p&gt;</description></item><item><title>tier-section</title><link>https://osmarpetry.dev/styleguide/tier-section/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/styleguide/tier-section/</guid><description>&lt;p&gt;Composes project cards, the text-only list and the CTA. Used by the home preview and the projects page.&lt;/p&gt;</description></item></channel></rss>