# Arham Jain

Published articles for Arham Jain.

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

## Simplify Your Code: Functional Core, Imperative Shell

DevFeed: [Simplify Your Code: Functional Core, Imperative Shell](<https://devfeed.tech/articles/simplify-your-code-functional-core-imperative-shell-23865.md>)

Original publisher: [Read original article](<http://testing.googleblog.com/2025/10/simplify-your-code-functional-core.html>)

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

Published: 2025-10-20T13:53:00Z

Content type: tutorial

Language: en

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

Topics: [Code](<https://devfeed.tech/topics/code.md>), [IO](<https://devfeed.tech/topics/io.md>)

Tags: [arham-jain](<https://devfeed.tech/tags/arham-jain.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [code](<https://devfeed.tech/tags/code.md>), [database](<https://devfeed.tech/tags/database.md>), [email](<https://devfeed.tech/tags/email.md>), [function](<https://devfeed.tech/tags/function.md>), [functional](<https://devfeed.tech/tags/functional.md>), [map](<https://devfeed.tech/tags/map.md>), [mutation](<https://devfeed.tech/tags/mutation.md>), [network](<https://devfeed.tech/tags/network.md>), [state](<https://devfeed.tech/tags/state.md>), [test](<https://devfeed.tech/tags/test.md>), [tott](<https://devfeed.tech/tags/tott.md>)

### AI overview

This tutorial explains the functional core, imperative shell pattern: keep pure, testable business logic separate from side effects such as database calls, network requests, email delivery, and external state mutation. It demonstrates the pattern by refactoring expiration-notification code.

### 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 Arham Jain Is your code a tangled mess of business logic and side effects? Mixing database calls, network requests, and other external interactions directly with your core logic can lead to code that's difficult to test, reuse, and understand. Instead, consider writing a functional core that's called from an imperative shell. Separating your code into functional cores and imperative shells makes it more testable, maintainable, and adaptable. The core logic can be tested in isolation, and the imperative shell can be swapped out or modified as needed. Here's some messy example code that mixes logic and side effects to send expiration notification emails to users: // Bad: Logic and side effects are mixed function sendUserExpiryEmail(): void { for (const user of db.getUsers()) { if (user.subscriptionEndDate > Date.now()) continue; if (user.isFreeTrial) continue; email.send(user.email, "Your account has expired " + user.name + "."); } } A functional core should contain pure, testable business logic, which is free of side effects (such as I/O or external state mutation). It operates only on the data it is given. An imperative shell is responsible for side effects, like database calls and sending emails. It uses the functions in your functional core to perform the business logic. Rewriting the above code to follow the functional core / imperative shell pattern might look like: Functional core function getExpiredUsers(users: User[], cutoff: Date): User[] { return users.filter(user => user.subscriptionEndDate <= cutoff && !user.isFreeTrial); } function generateExpiryEmails(users: User[]): Array<[string, string]> { return users.map(user => ([user.email, "Your account has expired " + user.name + "."]) ); } Imperative shell email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), Date.now()))); No