# refactor

Published articles for refactor.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## The Great Python Refactor of 2017 And Also 2018

DevFeed: [The Great Python Refactor of 2017 And Also 2018](<https://devfeed.tech/articles/the-great-python-refactor-of-2017-and-also-2018-27400.md>)

Original publisher: [Read original article](<http://engineering.khanacademy.org/posts/python-refactor-1.htm>)

Author: Khan Academy

Published: 2018-03-19T22:00:00Z

Content type: article

Language: en

Sources: [Khan Academy](<https://devfeed.tech/sources/khan-academy.md>)

Topics: [Python](<https://devfeed.tech/topics/python.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [Code](<https://devfeed.tech/topics/code.md>), [Development](<https://devfeed.tech/topics/development.md>), [Tool](<https://devfeed.tech/topics/tool.md>)

Tags: [2017](<https://devfeed.tech/tags/2017.md>), [blog-post](<https://devfeed.tech/tags/blog-post.md>), [code](<https://devfeed.tech/tags/code.md>), [dev](<https://devfeed.tech/tags/dev.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [infrastructure](<https://devfeed.tech/tags/infrastructure.md>), [news](<https://devfeed.tech/tags/news.md>), [python](<https://devfeed.tech/tags/python.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>)

### AI overview

This first article in a series describes Khan Academy's 2017-2018 Python refactoring effort. It explains how an overloaded codebase structure developed, the changes made to organize files and directories, and the difficulties of the work.

### Source excerpt

By Craig Silverstein Our codebase was a mess. One day, we decided to do something about it: namely, ... Read more

## Untangling our Python Code

DevFeed: [Untangling our Python Code](<https://devfeed.tech/articles/untangling-our-python-code-27401.md>)

Original publisher: [Read original article](<http://engineering.khanacademy.org/posts/python-refactor-3.htm>)

Author: Khan Academy

Published: 2018-04-16T22:00:00Z

Content type: tutorial

Language: en

Sources: [Khan Academy](<https://devfeed.tech/sources/khan-academy.md>)

Topics: [Python](<https://devfeed.tech/topics/python.md>), [Code](<https://devfeed.tech/topics/code.md>), [import](<https://devfeed.tech/topics/import.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [dependency](<https://devfeed.tech/tags/dependency.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [infrastructure](<https://devfeed.tech/tags/infrastructure.md>), [news](<https://devfeed.tech/tags/news.md>), [organization](<https://devfeed.tech/tags/organization.md>), [python](<https://devfeed.tech/tags/python.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [structure](<https://devfeed.tech/tags/structure.md>)

### AI overview

This article explains how Khan Academy addressed tangled dependencies in its Python codebase during its 2017 and 2018 refactoring work. It describes why dependency order matters, the problems caused by circular and poorly organized imports, and the use of package-based rules to guide code organization and detect problematic dependencies.

### Source excerpt

By Carter Bastian The previous posts about The Great Khan Academy Python Refactor of 2017 and Also 2018 ... Read more

## Refactoring Should NOT Touch Your Acceptance Tests

DevFeed: [Refactoring Should NOT Touch Your Acceptance Tests](<https://devfeed.tech/articles/refactoring-should-not-touch-your-acceptance-tests-26189.md>)

Original publisher: [Read original article](<https://journal.optivem.com/p/refactoring-should-not-touch-your-acceptance-tests>)

Author: Valentina Jemuović

Published: 2026-09-03T06:00:37Z

Content type: opinion

Language: en

Sources: [Optivem Journal](<https://devfeed.tech/sources/optivem-journal.md>)

Topics: [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [Pull Request](<https://devfeed.tech/topics/pull-request.md>), [test](<https://devfeed.tech/topics/test.md>)

Tags: [change](<https://devfeed.tech/tags/change.md>), [dsl](<https://devfeed.tech/tags/dsl.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [test](<https://devfeed.tech/tags/test.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

The article argues that a refactoring pull request should not change acceptance tests or their DSL, because doing so changes behavior rather than merely restructuring code.

### Source excerpt

A "refactor" PR that changes the acceptance test or the DSL isn't a refactor -- it's a behavioral change

## Nitpicking in code reviews wastes time

DevFeed: [Nitpicking in code reviews wastes time](<https://devfeed.tech/articles/nitpicking-in-code-reviews-wastes-time-38401.md>)

Original publisher: [Read original article](<https://blog.danlew.net/2026/09/01/nitpicking-in-code-reviews-wastes-time/>)

Author: Dan Lew

Published: 2026-09-01T13:00:13Z

Content type: opinion

Language: en

Sources: [Dan Lew Blog](<https://devfeed.tech/sources/dan-lew-blog.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [code productivity](<https://devfeed.tech/topics/code-productivity.md>), [Software Engineering](<https://devfeed.tech/topics/software-engineering.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [bugs](<https://devfeed.tech/tags/bugs.md>), [code](<https://devfeed.tech/tags/code.md>), [code-reviews](<https://devfeed.tech/tags/code-reviews.md>), [development](<https://devfeed.tech/tags/development.md>), [features](<https://devfeed.tech/tags/features.md>), [problems](<https://devfeed.tech/tags/problems.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [software-development](<https://devfeed.tech/tags/software-development.md>), [time](<https://devfeed.tech/tags/time.md>)

### AI overview

An opinion article argues that nitpicking minor issues in code reviews wastes time. Small problems usually have limited impact, may never cause trouble, and can often be fixed later, so review effort should prioritize major problems, bugs, and features.

### Source excerpt

I once wrote about how I've stopped nit-picking in code reviews, which improved the signal-to-noise ratio and helped everyone get along better. I'm back with a third reason to ditch the practice: nit-picking wastes time. By definition, nitpicks are about minor problems:

## Scheduling Claude Code for Nightly Repository Maintenance

DevFeed: [Scheduling Claude Code for Nightly Repository Maintenance](<https://devfeed.tech/articles/claude-code-can-maintain-your-repo-28977.md>)

Original publisher: [Read original article](<https://codingwithroby.substack.com/p/claude-code-can-maintain-your-repo>)

Author: Eric Roby

Published: 2026-07-28T12:03:08Z

Content type: tutorial

Language: en

Sources: [Eric Roby](<https://devfeed.tech/sources/eric-roby.md>)

Topics: [Claude Code](<https://devfeed.tech/topics/claude-code.md>), [Security](<https://devfeed.tech/topics/security.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [ci](<https://devfeed.tech/topics/ci.md>), [hooks](<https://devfeed.tech/topics/hooks.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [automated](<https://devfeed.tech/tags/automated.md>), [ci](<https://devfeed.tech/tags/ci.md>), [claude-code](<https://devfeed.tech/tags/claude-code.md>), [github-action](<https://devfeed.tech/tags/github-action.md>), [hooks](<https://devfeed.tech/tags/hooks.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [repo](<https://devfeed.tech/tags/repo.md>), [security](<https://devfeed.tech/tags/security.md>)

### AI overview

The article explains how to schedule Claude Code in headless mode for recurring repository maintenance. It recommends focused jobs for security sweeps, refactoring scans, and enhancement reviews, using structured JSON output and the --bare option for consistent scripted runs.

### Source excerpt

How to schedule headless runs for nightly security sweeps, refactor scans, and enhancement ideas

## Your Architecture Doesn't Rot Overnight

DevFeed: [Your Architecture Doesn't Rot Overnight](<https://devfeed.tech/articles/your-architecture-doesn-t-rot-overnight-26196.md>)

Original publisher: [Read original article](<https://journal.optivem.com/p/your-architecture-doesnt-rot-overnight>)

Author: Valentina Jemuović

Published: 2026-07-07T06:00:37Z

Content type: opinion

Language: en

Sources: [Optivem Journal](<https://devfeed.tech/sources/optivem-journal.md>)

Topics: [legacy](<https://devfeed.tech/topics/legacy.md>), [systems](<https://devfeed.tech/topics/systems.md>), [Software](<https://devfeed.tech/topics/software.md>), [Test-driven development](<https://devfeed.tech/topics/tdd.md>)

Tags: [architecture](<https://devfeed.tech/tags/architecture.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [code](<https://devfeed.tech/tags/code.md>), [dependency](<https://devfeed.tech/tags/dependency.md>), [legacy](<https://devfeed.tech/tags/legacy.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [requirements](<https://devfeed.tech/tags/requirements.md>)

### AI overview

The article explains how repeated convenience-driven decisions gradually weaken boundaries between business logic and infrastructure. It argues that architectural decay often remains hidden while the application works and tests pass, eventually making seemingly simple changes difficult to locate and implement.

### Source excerpt

As deadlines become tighter, convenience starts winning.

## TDD in Legacy Code - Maintainable Component Tests - Backend

DevFeed: [TDD in Legacy Code - Maintainable Component Tests - Backend](<https://devfeed.tech/articles/tdd-in-legacy-code-maintainable-component-tests-backend-26187.md>)

Original publisher: [Read original article](<https://journal.optivem.com/p/maintainable-component-tests-in-legacy-code-backend>)

Author: Valentina Jemuović

Published: 2026-07-02T06:02:41Z

Content type: tutorial

Language: en

Sources: [Optivem Journal](<https://devfeed.tech/sources/optivem-journal.md>)

Topics: [Back end](<https://devfeed.tech/topics/backend.md>), [Test-driven development](<https://devfeed.tech/topics/tdd.md>), [legacy](<https://devfeed.tech/topics/legacy.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [backend](<https://devfeed.tech/tags/backend.md>), [component](<https://devfeed.tech/tags/component.md>), [erp](<https://devfeed.tech/tags/erp.md>), [legacy](<https://devfeed.tech/tags/legacy.md>), [legacy-code](<https://devfeed.tech/tags/legacy-code.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [tdd](<https://devfeed.tech/tags/tdd.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

A tutorial on refactoring brittle backend component tests that are coupled to a backend API and ERP system, with the goal of making them more maintainable.

### Source excerpt

Many Backend Teams write unmaintainable Backend Component Tests - coupled to the Backend API and ERP. I'll show you how to refactor these brittle tests.

## The Way of TDD

DevFeed: [The Way of TDD](<https://devfeed.tech/articles/the-way-of-tdd-23867.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2026/03/the-way-of-tdd.html>)

Author: Google Testing Bloggers (noreply@blogger.com)

Published: 2026-03-10T12:24:00Z

Content type: article

Language: en

Sources: [Google Testing Blog](<https://devfeed.tech/sources/google-testing-blog.md>)

Topics: [Test-driven development](<https://devfeed.tech/topics/tdd.md>), [Test coverage](<https://devfeed.tech/topics/coverage.md>), [Development](<https://devfeed.tech/topics/development.md>), [Algorithm](<https://devfeed.tech/topics/algorithm.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [algorithm](<https://devfeed.tech/tags/algorithm.md>), [article](<https://devfeed.tech/tags/article.md>), [bartosz-papis](<https://devfeed.tech/tags/bartosz-papis.md>), [bugs](<https://devfeed.tech/tags/bugs.md>), [code](<https://devfeed.tech/tags/code.md>), [development](<https://devfeed.tech/tags/development.md>), [quality](<https://devfeed.tech/tags/quality.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [tdd](<https://devfeed.tech/tags/tdd.md>), [test](<https://devfeed.tech/tags/test.md>), [test-coverage](<https://devfeed.tech/tags/test-coverage.md>), [tests](<https://devfeed.tech/tags/tests.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

This article explains Test-Driven Development as a red-green-refactor cycle: write a failing test, make it pass with minimal production code, and then refactor. It describes reported benefits and limitations, and demonstrates the process by modifying a voting algorithm to support abstentions.

### Source excerpt

This article was adapted from a Google Tech on the Toilet (TotT) episode. You can download a printer-friendly version of this TotT episode and post it in your office. By Bartosz Papis Test-Driven Development (TDD) is the practice of working in a structured cycle where writing tests comes before writing production code. The process involves three steps, sometimes called the red-green-refactor cycle: Write a failing test Make the test pass by writing just enough production code Refactor the production code to meet your quality standards Research shows TDD has several benefits: it improves test coverage, reduces the number of bugs, increases confidence, and facilitates code reuse. This practice also helps reduce distractions and keep you in the flow. TDD also has its limitations and is not a silver bullet! See the Wikipedia article about TDD for a detailed explanation and references. Here is a short practical example. Assume you need to modify the following voting algorithm to support the option for voters to abstain: def outcome(ballots): if ballots.count(Vote.FOR) > len(ballots) / 2: return "Approved" return "Rejected" 1. We start by writing a failing test - as expected, the test doesn't even compile: def test_abstain_doesnt_count(self): self.assertEqual(outcome([Vote.FOR, Vote.FOR, Vote.AGAINST, Vote.ABSTAIN]), "Approved") 2. We fix the compilation error by including the missing enum option: class Vote(Enum): FOR = 1 AGAINST = 2 ABSTAIN = 3 Now that the test compiles, we fix the production code to get all tests passing: def outcome(ballots): if ballots.count(Vote.FOR) > (len(ballots) - ballots.count(Vote.ABSTAIN)) / 2: return "Approved" return "Rejected" 3. We now refactor the code to improve clarity, and complete an iteration of the TDD cycle: def outcome(ballots): counts = collections.Counter(ballots) return "Approved" if counts[Vote.FOR] > counts[Vote.AGAINST] else "Rejected" Learn more about TDD in the book Test Driven Development: By Example, by Kent Beck.

## The AI Multiplier: Where Developers Actually Get Leverage

DevFeed: [The AI Multiplier: Where Developers Actually Get Leverage](<https://devfeed.tech/articles/the-ai-multiplier-where-developers-actually-get-leverage-32378.md>)

Original publisher: [Read original article](<https://brianjenney.substack.com/p/the-ai-multiplier-where-developers>)

Author: Brian Jenney

Published: 2026-03-07T21:57:25Z

Content type: opinion

Language: en

Sources: [Brian Jenney](<https://devfeed.tech/sources/brian-jenney.md>)

Topics: [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [AI-assisted coding](<https://devfeed.tech/topics/ai-assisted-coding.md>), [coding assistant](<https://devfeed.tech/topics/coding-assistant.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Software](<https://devfeed.tech/topics/software.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [autocomplete](<https://devfeed.tech/tags/autocomplete.md>), [coding](<https://devfeed.tech/tags/coding.md>), [coding-assistant](<https://devfeed.tech/tags/coding-assistant.md>), [context](<https://devfeed.tech/tags/context.md>), [developers](<https://devfeed.tech/tags/developers.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

This commentary describes how software developers can gain leverage from AI through progressively more advanced usage. It outlines coding-assistant tasks such as generating functions, refactoring code, writing tests, and explaining errors, then discusses using AI as a planning partner to analyze systems, identify risks, and propose plans before code is written.

### Source excerpt

Last night I met up with Alex Lau, the author of Keep Calm, Code On, while he was in San Francisco.

## Fusaka Update - Transaction Gas Limit Cap arrives with EIP-7825

DevFeed: [Fusaka Update - Transaction Gas Limit Cap arrives with EIP-7825](<https://devfeed.tech/articles/fusaka-update-transaction-gas-limit-cap-arrives-with-eip-7825-17192.md>)

Original publisher: [Read original article](<https://blog.ethereum.org/en/2025/10/21/fusaka-gascap-update>)

Author: Toni Wahrstätter

Published: 2025-10-21T00:00:00Z

Content type: article

Language: en

Sources: [Ethereum Foundation Blog](<https://devfeed.tech/sources/ethereum-foundation-blog.md>)

Topics: [Ethereum](<https://devfeed.tech/topics/ethereum.md>), [Transactions](<https://devfeed.tech/topics/transactions.md>), [Deployment](<https://devfeed.tech/topics/deployment.md>), [systems](<https://devfeed.tech/topics/systems.md>)

Tags: [batch](<https://devfeed.tech/tags/batch.md>), [batching](<https://devfeed.tech/tags/batching.md>), [deployment](<https://devfeed.tech/tags/deployment.md>), [ethereum](<https://devfeed.tech/tags/ethereum.md>), [monitoring](<https://devfeed.tech/tags/monitoring.md>), [parallel](<https://devfeed.tech/tags/parallel.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [research-development](<https://devfeed.tech/tags/research-development.md>), [transactions](<https://devfeed.tech/tags/transactions.md>)

### AI overview

The Fusaka hard fork will introduce EIP-7825, capping gas per transaction at 2²⁴, approximately 16.78 million gas. The cap is already active on Holesky and Sepolia and will apply to Ethereum mainnet with Fusaka. It may affect very large transactions, batch operations, deployment scripts, transaction builders, and related infrastructure, while leaving the overall block gas limit and eth_call limits unchanged.

### Source excerpt

Starting with the upcoming Fusaka hard fork, EIP-7825 introduces a per-transaction gas limit cap of 2²⁴ (~= 16.78 million gas). This change is already live on Holesky and Sepolia, and will activate on mainnet with Fusaka. Developers and users who rely on very large transactions should verify that...

## Getting Into Flow State with Agentic Coding

DevFeed: [Getting Into Flow State with Agentic Coding](<https://devfeed.tech/articles/getting-into-flow-state-with-agentic-coding-25210.md>)

Original publisher: [Read original article](<https://kau.sh/blog/agentic-coding-flow-state/>)

Author: Kaushik Gopal

Published: 2025-07-23T07:15:47Z

Content type: tutorial

Language: en

Sources: [Kaushik Gopal's Site](<https://devfeed.tech/sources/kaushik-gopal-s-site.md>)

Topics: [agentic-coding](<https://devfeed.tech/topics/agentic-coding.md>), [Claude Code](<https://devfeed.tech/topics/claude-code.md>), [ai-coding](<https://devfeed.tech/topics/ai-coding.md>), [Development](<https://devfeed.tech/topics/development.md>), [Code](<https://devfeed.tech/topics/code.md>), [Pull Request](<https://devfeed.tech/topics/pull-request.md>)

Tags: [agentic-coding](<https://devfeed.tech/tags/agentic-coding.md>), [ai-coding](<https://devfeed.tech/tags/ai-coding.md>), [claude-code](<https://devfeed.tech/tags/claude-code.md>), [openai](<https://devfeed.tech/tags/openai.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [review](<https://devfeed.tech/tags/review.md>), [verify](<https://devfeed.tech/tags/verify.md>)

### AI overview

A developer documents a workflow for using Claude Code and other AI coding agents in production software development. The process emphasizes maintaining shared instructions, planning work explicitly, and organizing implementation into discrete pull requests so agents can resume tasks with sufficient context.

### Source excerpt

I recently found myself in a deep state of flow while coding -- the kind where time melts away and you gain real clarity about the software you're building. The difference this time: I was using Claude Code primarily. If my recent posts are any indication, I've been experimenting a lot with AI coding -- not just with toy side projects, but high-stakes production code for my day job. I have a flow that I think works pretty well. I'm documenting it here as a way to hone my own process and, hopefully, benefit others as well. set the stage plan with the agent (no really 🤮) spawn your agents verify and refactor the final review Skeptics vs cynics Many of my friends and colleagues are understandably skeptical about AI's role in development. That's ok. That's actually good. We should be skeptical of anything that's upending our field with such ferociousness. We just shouldn't be cynical.1 Step 0: Set the stage # You know what'll definitely get you out of the flow? Having to constantly repeat basic instructions to your agent. "This is an Android app that does X, using the Y architecture..." "When styling the front end web client, only use tailwind css v4..." "Use `make test` to run a single test; `make tests` to run the entire test suite..." "To build the app without running lint use `make`..." ... These are all very important instructions that you shouldn't have to repeat to your agent every single time. Invest a little upfront in your master ai instructions file. It makes a big difference and gets you up and coding quickly with any agent. trivial to get started with claude /init these days Of course, I also recommend consolidating your ai instructions to a single source of truth, so you're not locked in with any single vendor. Step 1: Plan with the Agent # Update: Checkout my post ExecPlans. I now use OpenAI's Aaron Friel ExecPlans approach for this. I won't lie. The idea of this step did not exactly spark joy for me. There are times where I plan my code out in a neat list, but rarel

## Tactical Coding Assistants

DevFeed: [Tactical Coding Assistants](<https://devfeed.tech/articles/tactical-coding-assistants-23725.md>)

Original publisher: [Read original article](<https://medium.com/booking-com-development/tactical-coding-assistants-9fee730fd734?source=rss----1c36c35f9c76---4>)

Author: Pieter Tolsma

Published: 2025-07-03T08:53:09Z

Content type: opinion

Language: en

Sources: [Booking.com Development - Medium](<https://devfeed.tech/sources/booking-com-development-medium.md>)

Topics: [Large Language Model](<https://devfeed.tech/topics/llm.md>), [Development](<https://devfeed.tech/topics/development.md>), [Software Engineering](<https://devfeed.tech/topics/software-engineering.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [Claude](<https://devfeed.tech/topics/claude.md>), [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [claude](<https://devfeed.tech/tags/claude.md>), [coding](<https://devfeed.tech/tags/coding.md>), [coding-assistant](<https://devfeed.tech/tags/coding-assistant.md>), [complexity](<https://devfeed.tech/tags/complexity.md>), [design](<https://devfeed.tech/tags/design.md>), [development](<https://devfeed.tech/tags/development.md>), [genai](<https://devfeed.tech/tags/genai.md>), [llm](<https://devfeed.tech/tags/llm.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [review](<https://devfeed.tech/tags/review.md>), [software-design](<https://devfeed.tech/tags/software-design.md>)

### AI overview

The article compares tactical and strategic programming and applies that distinction to coding assistants. Drawing on the author's experience, it argues that assistants such as Gemini 2.5 Pro and Claude 3.7 can implement clearly specified tasks effectively, but may produce excessive complexity, duplicated behavior, and difficult-to-maintain code when used without architectural review.

### Source excerpt

Over the past 15 months I have been actively working with LLM's in my job as a software engineer. I have had many moments where I thought singularity was here, but then almost immediately after I would see the agent fall flat on its face. I have become interested in figuring out when and why these new tools fail, in the hope that it can help me use these tools to their maximum potential while still keeping control over the quality of what I commit. In this short article, I want to expand on a recent observation. Generated using Gemini Imagen 4 In the book 'A Philosophy of Software Design' by John K. Ousterhout, a great analogy is made between two different modes of development: tactical and strategic programming. Tactical programming: this is a shortsighted approach focused on completing the immediate task as quickly as possible. Here, the primary goal is to make a feature or bug fix work in the most direct way. You can imagine what will happen if you have a team of engineers that only works like this: technical debt will pile up fast. Generated using Gemini Imagen 4 On the other side there is strategic programming: this involves a higher level of thinking. A strategic programmer is not finished when the feature is implemented. They take a step back and review the architecture, to see if any abstractions can be made. Does the current approach overcomplicate things? Can we refactor things? The focus here is on design, where the engineers main goal is to keep complexity at bay. These two analogies hooked onto what I thought about the current state of coding assistants. In my experience, some of the current (mid-2025) state of the art coding assistants (Gemini 2.5 pro, Claude 3.7) are extremely adept tactical programmers. Assuming you give them a clear description of what you need implemented, they will go ahead and do it for you (with quite a high success rate in my experience). We humans are limited by many things, such as the speed at which we can physically press k

## How To Refactor Legacy Code

DevFeed: [How To Refactor Legacy Code](<https://devfeed.tech/articles/how-to-refactor-legacy-code-26208.md>)

Original publisher: [Read original article](<https://craftbettersoftware.com/p/how-to-refactor-legacy-code>)

Author: Daniel Moka

Published: 2025-04-12T05:01:26Z

Content type: tutorial

Language: en

Sources: [Craft Better Software](<https://devfeed.tech/sources/craft-better-software.md>)

Topics: [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>), [Test coverage](<https://devfeed.tech/topics/coverage.md>), [Mocking](<https://devfeed.tech/topics/mocking.md>)

Tags: [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [legacy-code](<https://devfeed.tech/tags/legacy-code.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [testing](<https://devfeed.tech/tags/testing.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

A six-step strategy for refactoring legacy code by breaking dependencies, using characterization and other testing techniques, achieving test coverage, and then changing the code.

### Source excerpt

The art of making your code testable, testing it effectively, and refactoring it like a pro

## How to use generics to avoid duplications and make your code better

DevFeed: [How to use generics to avoid duplications and make your code better](<https://devfeed.tech/articles/how-to-use-generics-to-avoid-duplications-and-make-your-code-better-32291.md>)

Original publisher: [Read original article](<https://domenicoluciani.com/2025/04/11/how-to-use-generics-to-avoid-duplications-and-make-your-code-better.html>)

Author: Domenico Luciani

Published: 2025-04-10T22:00:00Z

Content type: tutorial

Language: en

Sources: [Domenico Luciani](<https://devfeed.tech/sources/domenico-luciani.md>)

Topics: [generics](<https://devfeed.tech/topics/generics.md>), [Go Language](<https://devfeed.tech/topics/go-language.md>), [interfaces](<https://devfeed.tech/topics/interfaces.md>), [JSON:API](<https://devfeed.tech/topics/json-api.md>), [factory function](<https://devfeed.tech/topics/factory-function.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [create](<https://devfeed.tech/tags/create.md>), [generics](<https://devfeed.tech/tags/generics.md>), [go](<https://devfeed.tech/tags/go.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [like](<https://devfeed.tech/tags/like.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

### AI overview

A Go tutorial explains how generics can reduce duplicated method implementations when multiple response structs must satisfy the same interfaces. It demonstrates applying a reusable generic response to JSON:API-formatted responses and adding a factory function for readability.

### Source excerpt

I recently worked on a project that had a lot of code duplication due to repeated implementations of the same interfaces. I quickly realized it was a great opportunity to refactor...

## Why Tinybird Rebuilt Its Frontend Instead of Patching It

DevFeed: [Why Tinybird Rebuilt Its Frontend Instead of Patching It](<https://devfeed.tech/articles/behind-the-scenes-of-tinybird-s-big-frontend-refactor-18698.md>)

Original publisher: [Read original article](<https://www.tinybird.co/blog/tinybird-frontend-refactor>)

Author: Rafa Moreno, Alasdair Brown

Published: 2024-07-19T00:00:00Z

Content type: article

Language: en

Sources: [Tinybird](<https://devfeed.tech/sources/tinybird.md>)

Topics: [Front end](<https://devfeed.tech/topics/frontend.md>), [Code](<https://devfeed.tech/topics/code.md>), [User experience (UX)](<https://devfeed.tech/topics/ux.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [engineering-excellence](<https://devfeed.tech/tags/engineering-excellence.md>), [frontend](<https://devfeed.tech/tags/frontend.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [ux](<https://devfeed.tech/tags/ux.md>)

### AI overview

Tinybird describes a complete frontend refactor, citing faster loads, better UX, and cleaner code as reasons for rebuilding instead of patching.

### Source excerpt

We refactored the Tinybird frontend completely. Faster loads, better UX, cleaner code. Here's why we rebuilt instead of patched.

## Campground Pull Request

DevFeed: [Campground Pull Request](<https://devfeed.tech/articles/campground-pull-request-25228.md>)

Original publisher: [Read original article](<https://kau.sh/blog/campground-pr/>)

Author: Kaushik Gopal

Published: 2024-07-06T22:52:31Z

Content type: opinion

Language: en

Sources: [Kaushik Gopal's Site](<https://devfeed.tech/sources/kaushik-gopal-s-site.md>)

Topics: [Pull Request](<https://devfeed.tech/topics/pull-request.md>), [Code review](<https://devfeed.tech/topics/code-review.md>), [Code quality](<https://devfeed.tech/topics/code-quality.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [cleanup](<https://devfeed.tech/tags/cleanup.md>), [code](<https://devfeed.tech/tags/code.md>), [code-quality](<https://devfeed.tech/tags/code-quality.md>), [merge](<https://devfeed.tech/tags/merge.md>), [pull-request](<https://devfeed.tech/tags/pull-request.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [review](<https://devfeed.tech/tags/review.md>), [reviews](<https://devfeed.tech/tags/reviews.md>), [team](<https://devfeed.tech/tags/team.md>)

### AI overview

The article proposes "Campground PRs": separate pull requests for refactoring and clarifying code before implementing a new feature. Because these changes should not alter functionality, they can improve estimates, simplify reviews, and gradually improve codebase quality.

### Source excerpt

Before diving into a new feature, I always tell my team to scout the parts of the codebase that will need to change. As we explore, refactor for clarity. These cleanup changes get their own pull request1 (PR) before we touch the new feature. This PR shouldn't change functionality, just tidy up the existing code. This gives us a few big wins: Better estimates: We can estimate the feature's timeline more accurately now that we have a much better sense of what's about to change. Smoother reviews: Campground PRs are quicker to review, since no functionality has changed. Importantly, you don't clutter your feature PR with refactors or distracting changes -- prompting the ire of code reviewers. Codebase quality: You gradually increase the code quality of your codebase -- especially the parts that won't get touched by your feature PR but could use the love. This is not a new concept , you've probably seen versions of it before: Boy Scout Rule: Leave your codebase cleaner than you found it. Broken Windows: Fix small issues before they proliferate through your code base become big. I haven't found a popular name for this specific concept, so I've started calling them "Campground PRs". Don't just leave the code better after your feature, do it before hand. Got a better name? Let me know! Or merge request (MR), for the Gitlab folks. ↩︎

## How Ownership and Impact Help Engineers Become Senior

DevFeed: [How Ownership and Impact Help Engineers Become Senior](<https://devfeed.tech/articles/quickly-become-a-senior-engineer-39998.md>)

Original publisher: [Read original article](<https://www.saiyangrowthletter.com/p/quickly-become-a-senior-engineer>)

Author: Tiger Abrodi

Published: 2024-05-14T05:56:49Z

Content type: opinion

Language: en

Sources: [Saiyan Growth Letter](<https://devfeed.tech/sources/saiyan-growth-letter.md>)

Topics: [Programming](<https://devfeed.tech/topics/programming.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [trust](<https://devfeed.tech/topics/trust.md>)

Tags: [communication](<https://devfeed.tech/tags/communication.md>), [developers](<https://devfeed.tech/tags/developers.md>), [ownership](<https://devfeed.tech/tags/ownership.md>), [productivity](<https://devfeed.tech/tags/productivity.md>), [programming](<https://devfeed.tech/tags/programming.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [team](<https://devfeed.tech/tags/team.md>), [trust](<https://devfeed.tech/tags/trust.md>)

### AI overview

This commentary argues that becoming a senior engineer depends mainly on ownership and impact, supported by technical ability, communication, reliability, and teamwork.

### Source excerpt

Two main ingredients: Ownership and Impact!

## Perils of duplicate finding

DevFeed: [Perils of duplicate finding](<https://devfeed.tech/articles/perils-of-duplicate-finding-20952.md>)

Original publisher: [Read original article](<https://jakewharton.com/perils-of-duplicate-finding/>)

Published: 2024-02-14T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

### AI overview

A Kotlin article examines several ways to find duplicated integers in a collection. It explains why collection subtraction and MutableList.removeAll produce unexpected results, then refactors toward approaches that correctly track previously seen values.

### Source excerpt

Given an array of integers ([1, 2, 3, 1, 3, 1]), find the elements which are duplicated. No, we're not interviewing. I'm trying to prevent a user from specifying a reserved value twice. Elsewhere in the file I already have duplicate detection for object tags. val dupes: Map<Int, List<Widget>> = widgets.groupBy(Widget::tag) .filterValues { it.size > 1 } I can do the same technique for the integer array with an identity function and grabbing the resulting keys. val dupes: Set<Int> = ints.groupBy { it } .filterValues { it.size > 1 } .keys This prints [1, 3]. So... done? Yes! But no, using the map seems wasteful, right? Attempt 1 My first attempt to avoid the map was to remove the set of integers from a list of them. This should result in a list of any duplicated elements. val dupes: List<Int> = ints.toList() - ints.toSet() No matter the content of ints, this will always print []. Why? The minus operator says that it "returns a list containing all elements of the original collection except the elements contained in the given elements collection". So it removes all occurrences of each element in the set from the list. This is some surprising behavior to hide behind an operator whose signature operates on an Iterable receiver and Collection argument. Attempt 2 Second attempt switches to MutableList.removeAll which takes a collection of elements. The MutableList.remove function only removes the first occurrence of an element, so this should remove the first occurrence of each element in the set. val dupes: List<Int> = ints.toMutableList() .apply { removeAll(ints.toSet()) } This once again prints []. But why? Kotlin made me a liar. MutableList.remove does indeed only remove the first occurrence of the element. MutableList.removeAll, however, removes all occurrences of each element in the supplied collection. That's quite the subtle asymmetry. There is no function for removing all occurrences of a single element. Nor a function to remove only the first occurrences of each elem

## Intermediate collection avoidance

DevFeed: [Intermediate collection avoidance](<https://devfeed.tech/articles/intermediate-collection-avoidance-20942.md>)

Original publisher: [Read original article](<https://jakewharton.com/intermediate-collection-avoidance/>)

Published: 2024-02-07T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [IntelliJ IDEA](<https://devfeed.tech/topics/intellij-idea.md>), [Code](<https://devfeed.tech/topics/code.md>), [Compose](<https://devfeed.tech/topics/compose.md>)

Tags: [benchmarks](<https://devfeed.tech/tags/benchmarks.md>), [compose](<https://devfeed.tech/tags/compose.md>), [intellij](<https://devfeed.tech/tags/intellij.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [memory](<https://devfeed.tech/tags/memory.md>), [performance](<https://devfeed.tech/tags/performance.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

### AI overview

This article explains how to avoid intermediate iterators and collections in Kotlin collection operations. It presents fused string joining, array initialization, and pre-sized list initialization as shorter, faster approaches that can reduce allocations, while noting that indexed access is important for performance and that these techniques are best suited to controlled internal usage.

### Source excerpt

Given a list of users, extract their names and join them into a comma-separated list. Kotlin's extension functions on collections make this trivial. users.map { it.name }.joinToString() Writing this in IntelliJ IDEA produces a "weak warning" offering advice. Call chain on collection type may be simplified An intention action will refactor the code for you to a more efficient form. users.joinToString() { it.name } Mapping the user to their name now occurs during construction of the joined string rather than as a discrete operation. The additional iterator and intermediate collection produced by the map is eliminated. This code is both shorter and faster, and the IDE helps you discover this superior form. Two similar fused operations that I like but which don't benefit from IDE advice are array and pre-sized list initialization with a lambda. If we wanted to create an array of our user's names, instead of doing users.map { it.name }.toTypedArray() we can use Array(users.size) { users[it].name } This again trades the intermediate iterator and collection within map for an indexed loop. Primitive array versions are also available. IntArray(users.size) { users[it].age } Arrays are not used too often. Mostly for memory-sensitive or performance-sensitive code, or when calling out to a Java API. Thankfully this lambda-accepting initializer is also available for pre-sized lists. MutableList(users.size) { users[it].name } Use this to initialize element default values, compute elements based on the index, or derive data from another source. In the case of deriving data, the source needs to support random access in order to actually result in a more efficient computation.1 If you use a list backed by an alternate structure (linked, persistent, etc.) performance will be abysmal. This technique works best for internal library usage and should not be used when you don't control the original list. Benchmark Score Error Units --------------------------------------------- ---------- -

## I still see LiveData - where are the Flows?

DevFeed: [I still see LiveData - where are the Flows?](<https://devfeed.tech/articles/i-still-see-livedata-where-are-the-flows-32059.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/i-still-see-livedata-where-are-the-flows/>)

Published: 2023-07-30T19:38:36Z

Content type: opinion

Language: en

Sources: [maiatoday](<https://devfeed.tech/sources/maiatoday.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Dependency injection](<https://devfeed.tech/topics/dependency-injection.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [flow](<https://devfeed.tech/tags/flow.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [live-data](<https://devfeed.tech/tags/live-data.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [network](<https://devfeed.tech/tags/network.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

The article argues that LiveData is appropriate for observing UI state but is a poor fit for repositories because it is tied to the Android lifecycle and always runs on the main thread. It recommends using Kotlin Flows, particularly in repositories, because they support configurable dispatchers, richer operators, and multiplatform projects.

### Source excerpt

Hammer and nail There is no doubt LiveData is an easy, lifecycle safe way to observe some state which needs to be displayed on the UI. It is just so easy to create and easy to update. It is easy to observe. I think that may be why people use it everywhere where they need a simple observation. This ok, no guilt, no harm .... for the UI layers .... but there are better solutions for domain and data layers. This is not the first time this topic has come up yet I still see Live Data in a repository offered as a good solution from time to time, in blog posts, samples and in books. I think it is a case of people think they only have a LiveData hammer. There are infact pitfalls if you use LiveData in a repository. I think it's an anti-pattern. But why not LiveData is lifecycle aware - do we need this in our repository? Repostitories are typically provided by dependency injection, they could be singletons and they don't need to know about the Android lifecycle. LiveData always runs on the main thread, you can't change this. This is not what we want in a repository. Repositories often work with different data sources which could involve network or disk access tasks. I would argue that you need to be able to run these kinds of tasks on the correct dispatcher if your libraries do not already do this. This is the deal breaker for me because you can cause jank in the UI if you do this incorrectly. LiveData does have some capabilities to combine and convert LiveData variables with MediatorLiveData but flows provide a wide variety of elegant operators to choose from. This is probably not a solid argument more a case of convenience. Lastly, one of the biggest reasons after the main thread argument, why I would advocate for converting all of the LiveData use to flows: flows are part of the Kotlin coroutines library. This means they run on any platform where Kotlin coroutines run. You can use them in a multiplatform project. Or to put it differently, if you use flows in your repository i

## Swampy Refactor: Converting Otto Bus to Flows

DevFeed: [Swampy Refactor: Converting Otto Bus to Flows](<https://devfeed.tech/articles/swampy-refactor-converting-otto-bus-to-flows-32080.md>)

Original publisher: [Read original article](<https://www.maiatoday.net/p/swampy-refactor-converting-otto-bus-to-flows/>)

Published: 2023-07-17T17:18:36Z

Content type: tutorial

Language: en

Sources: [maiatoday](<https://devfeed.tech/sources/maiatoday.md>)

Topics: [migration](<https://devfeed.tech/topics/migration.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [deprecated](<https://devfeed.tech/topics/deprecated.md>), [Code](<https://devfeed.tech/topics/code.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Git](<https://devfeed.tech/topics/git.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [flow](<https://devfeed.tech/tags/flow.md>), [git](<https://devfeed.tech/tags/git.md>), [migration](<https://devfeed.tech/tags/migration.md>), [otto-bus](<https://devfeed.tech/tags/otto-bus.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [swampy](<https://devfeed.tech/tags/swampy.md>)

### AI overview

This tutorial explains how to migrate an Android application from the deprecated Otto Bus event bus to Kotlin Flow. It presents an incremental, event-by-event process and notes that the work may require architectural refactoring, dependency-injection changes, and testing.

### Source excerpt

The story starts I was wandering around my day job's code base and I happened on a time capsule - a pristine Java Activity studded with semi-colons, a snapshot of how we built things in 2014. All the member variables started with m and there was plenty of logic to update the screen and dictate actions. Despite being old, it's still used every day by users. Why would I change it? The Bus disappears Well, it got its data from a subscription to the Otto Bus. Otto Bus was deprecated in 2016. A blog post suggested migrating to RxJava, but since our code base standard now involves coroutines, Flows, and in some cases, LiveData, I decided to remove deprecated libraries and complete the partial migrations we started some time ago. This blog post summarizes how to migrate from Otto Bus to Flow. I've also created a Git repo with a simplified example that uses Otto Bus, with a conversion to Flow in the commit history. Check out the otto-bus tag for the working Otto Bus version and the flow tag for the converted Flow version. I am sparing you the Java to Kotlin conversions. This toy app lets you tap on the 8 ball for a message. It uses Otto Bus to notify the 8 Ball that a new message is needed as well as when a new message is available. How to tackle the migration - step by step Here are the basic steps for this kind of migration: Pick one event Find All the producers of this event (hopefully, there is only one but don't count on it) Replace with compatible functionality. We'll look at how to choose compatible functionality in the next section. Things will be broken. Find all subscribers of this event by looking for @Subscribe annotations. Replace with a matching access mechanism. Things should work at this point. Test that everything that used this one event still works Repeat with the next event until there are no events left to migrate Remove the Otto bus and it's dependencies Celebrate! Of course this looks deceptively simple. As simple as it is to add otto bus to a code ba

## This Week at Zed Industries: #10

DevFeed: [This Week at Zed Industries: #10](<https://devfeed.tech/articles/this-week-at-zed-industries-10-13545.md>)

Original publisher: [Read original article](<https://zed.dev/blog/this-week-at-zed-10>)

Author: Julia Risley

Published: 2023-07-07T00:00:00Z

Content type: article

Language: en

Sources: [Zed Industries - Blog](<https://devfeed.tech/sources/zed-industries-blog.md>)

Topics: [ui](<https://devfeed.tech/topics/ui.md>), [Code](<https://devfeed.tech/topics/code.md>), [TypeScript](<https://devfeed.tech/topics/typescript.md>), [Rust](<https://devfeed.tech/topics/rust.md>), [bug](<https://devfeed.tech/topics/bug.md>), [Database](<https://devfeed.tech/topics/database.md>), [Network](<https://devfeed.tech/topics/network.md>), [macOS](<https://devfeed.tech/topics/macos.md>), [Vim](<https://devfeed.tech/topics/vim.md>)

Tags: [bug](<https://devfeed.tech/tags/bug.md>), [code](<https://devfeed.tech/tags/code.md>), [collaboration](<https://devfeed.tech/tags/collaboration.md>), [crash](<https://devfeed.tech/tags/crash.md>), [database](<https://devfeed.tech/tags/database.md>), [incremental](<https://devfeed.tech/tags/incremental.md>), [macos](<https://devfeed.tech/tags/macos.md>), [network](<https://devfeed.tech/tags/network.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [rust](<https://devfeed.tech/tags/rust.md>), [typescript](<https://devfeed.tech/tags/typescript.md>), [ui](<https://devfeed.tech/tags/ui.md>), [vim](<https://devfeed.tech/tags/vim.md>)

### AI overview

A weekly Zed development update covering collaboration UI and native calling, theme code work, assistant fixes, GPUI and Vim improvements, and a macOS crash fix for multiple instances competing for local database access.

### Source excerpt

A quiet week of rest and incremental improvement.

## I know Nothing in Kotlin

DevFeed: [I know Nothing in Kotlin](<https://devfeed.tech/articles/i-know-nothing-in-kotlin-23971.md>)

Original publisher: [Read original article](<https://medium.com/making-meetup/i-know-nothing-in-kotlin-392a85bcc3b4?source=rss----6981e268ba45---4>)

Author: Colin Lee

Published: 2022-09-16T15:32:41Z

Content type: tutorial

Language: en

Sources: [Making Meetup - Medium](<https://devfeed.tech/sources/making-meetup-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Exception](<https://devfeed.tech/topics/exception.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [Swift](<https://devfeed.tech/topics/swift.md>)

Tags: [coroutines](<https://devfeed.tech/tags/coroutines.md>), [dns](<https://devfeed.tech/tags/dns.md>), [exception](<https://devfeed.tech/tags/exception.md>), [exception-handling](<https://devfeed.tech/tags/exception-handling.md>), [ios](<https://devfeed.tech/tags/ios.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform-mobile](<https://devfeed.tech/tags/kotlin-multiplatform-mobile.md>), [network](<https://devfeed.tech/tags/network.md>), [nothing](<https://devfeed.tech/tags/nothing.md>), [refactor](<https://devfeed.tech/tags/refactor.md>), [swift](<https://devfeed.tech/tags/swift.md>), [timeout](<https://devfeed.tech/tags/timeout.md>)

### AI overview

This article explains Kotlin's Nothing type through a code-pairing example involving repository calls in a shared Kotlin Multiplatform Mobile module. It describes refactoring repeated exception handling, rethrowing CancellationExceptions for cooperative coroutine cancellation, and using Nothing for functions that always throw.

### Source excerpt

When the Greek philosopher Socrates professed that "I know only one thing -- that I know nothing," he wasn't exactly professing ignorance. It was an ancient formulation of the Dunning-Kruger effect. He had discovered that the more he learned, the wider the expanse of human knowledge seemed and the less that it seemed he knew. A fool, on the other hand, might believe that they're "not smart, but genius... and a very stable genius at that," and that they know "only the best words." In this sense, it's a good thing to know nothing. It's also true in Kotlin. During a recent code pairing session, I discovered that in Kotlin, there are numerous developers who have written code in the language for many years. And yet, they still don't know Nothing. Our pairing session became a big fuss about Nothing. We were working on some Repository code in our shared Kotlin Multiplatform Mobile (KMM) module of our Meetup for Organizers app. In this code, there was a repeated block at the end of every repository call to handle network, DNS, and timeout errors. We decided it would make sense to refactor this block into a function as we used it so often. The repeated block in question handled a catch block. It had to re-throw any CancellationExceptions to allow cooperative cancellation of coroutines. Then we had to wrap any other exception and re-throw it as a custom exception type so that we can easily tell iOS a complete list of all types we intend to throw in a @Throws declaration. This allows exception handling and avoids crashing when our functions are called by Swift code. In essence, this code block always threw an Exception. The pairing session became quite funny, like the Laurel and Hardy "Who's on First" comedy routine, but you could tell there was Nothing more frustrating, too. It went something like this: "Why am I getting this red text at the call site?" "The return type is incorrect because you always throw an exception. You need to return Nothing." "I already am returning nothi

## I Know Nothing in Kotlin

DevFeed: [I Know Nothing in Kotlin](<https://devfeed.tech/articles/i-know-nothing-in-kotlin-37554.md>)

Original publisher: [Read original article](<https://colintheshots.com/writing/i-know-nothing-in-kotlin/>)

Published: 2022-08-30T17:52:35Z

Content type: tutorial

Language: en

Sources: [Colin The Shots](<https://devfeed.tech/sources/colin-the-shots.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Exception](<https://devfeed.tech/topics/exception.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [kotlin multiplatform mobile](<https://devfeed.tech/topics/kotlin-multiplatform-mobile.md>)

Tags: [coroutines](<https://devfeed.tech/tags/coroutines.md>), [exception-handling](<https://devfeed.tech/tags/exception-handling.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform-mobile](<https://devfeed.tech/tags/kotlin-multiplatform-mobile.md>), [refactor](<https://devfeed.tech/tags/refactor.md>)

### AI overview

This developer article explains Kotlin's Nothing type through a refactoring example involving exception handling in a shared Kotlin Multiplatform Mobile repository. It distinguishes Nothing from Unit and describes using it when a function always throws, including when interoperating with Swift code and preserving coroutine cancellation.

### Source excerpt

When the Greek philosopher Socrates professed that "I know only one thing-- that I know nothing," he wasn't exactly professing ignorance. It was an ancient formulation of the Dunning-Kruger effect.

[Next page](<https://devfeed.tech/tags/refactor.md?cursor=WyIyMDIyLTA4LTMwVDE3OjUyOjM1KzAwOjAwIiwgImE1YjM1NGNjLTRiNDYtNDJlMC1iOTAzLTU2MzZjYzU1NWYyOSJd>)