Skip to content

feat: add tap function #350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

nusohiro
Copy link
Contributor

@nusohiro nusohiro commented Feb 3, 2025

Summary

This PR adds the tap function.
The function executes a given function with a provided value, allowing for side effects or mutations, and then returns the original value.

Related issue, if any:

N/A

For any code change,

  • Related documentation has been updated, if needed
  • Related tests have been added or updated, if needed
  • Related benchmarks have been added or updated, if needed
  • Release notes in next-minor.md or next-major.md have been added, if needed

Does this PR introduce a breaking change?

No

Bundle impact

Status File Size 1
A src/function/tap.ts 48

Footnotes

  1. Function size includes the import dependencies of the function.

@nusohiro nusohiro requested a review from aleclarson as a code owner February 3, 2025 14:30
@radashi-bot
Copy link

Benchmark Results

Name Current
tap: executing a side-effect function on a single object 4,969,352.6 ops/sec ±0.11%
tap: executing a side-effect function on a large array 122,173.96 ops/sec ±0.6%
tap: executing a side-effect function on deeply nested objects 2,536,163.32 ops/sec ±0.1%

Performance regressions of 30% or more should be investigated, unless they were anticipated. Smaller regressions may be due to normal variability, as we don't use dedicated CI infrastructure.

@aleclarson
Copy link
Member

Hey @nusohiro, thanks for the PR! I appreciate you helping out. 👍

Of all the utility libraries I track, only 1 has this tap function (https://github.com/antfu/utils/blob/main/src/function.ts#L29). I'm not exactly sure what its utility is. It seems like syntax sugar? The one use case I could think of is for logging an expression without having to move the code into a variable declaration first. Did you have other use cases in mind?

@nusohiro
Copy link
Contributor Author

nusohiro commented Feb 4, 2025

@aleclarson
Thanks for your response and for reviewing the PR! I really appreciate it.

You’re right that tap is often used for logging, but another use case is avoiding explicit let variable declarations.
Instead of declaring a variable first and then modifying it, tap allows you to initialize and modify an object in a single expression.

For example, without tap:

let obj = { a: 1 };
if (someCondition) {
  obj.a += 1;
} else {
  obj.a -= 1;
}

With tap:

const obj = _.tap({ a: 1 }, (o) => {
  if (somecondition) {
    o.a += 1;
  } else {
    o.a -= 1;
  }
});

@aleclarson aleclarson added new feature This PR adds a new function or extends an existing one awaiting more feedback Wait on this until more people comment. labels Feb 4, 2025
@aleclarson
Copy link
Member

Hey @nusohiro 👋

I've thought about it some more, and I don't think tap is a good fit for Radashi. It's easy enough to implement on your own (if desired), and the goal of "less variables" feels like the kind of over-optimization that Radashi tries to avoid on principle.

I really do appreciate your suggestions. I look forward to any future contributions you make! 🤝

@aleclarson aleclarson added open library This PR should be listed in the Open Library won't merge A rejected proposal. and removed new feature This PR adds a new function or extends an existing one awaiting more feedback Wait on this until more people comment. labels Apr 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
open library This PR should be listed in the Open Library won't merge A rejected proposal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants