Skip to content

Clarify docs and examples for fetch/4 #404

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

Conversation

SergioInToronto
Copy link

@SergioInToronto SergioInToronto commented Mar 25, 2025

fetch/4

  • Explain behaviour where only 1 instance of lazy evaluation can run simultaneously
  • Shorten explanation where possible
  • Progressive complexity - explain the simplest usage first, adding complexity as the reader keeps reading.

Copy link
Contributor

@HansGlimmerfors HansGlimmerfors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good initiative to improve the documentation, but maybe some minor tweaks should still be made? :)
(Note: I just happened to have a look at the open PR and had some comments, whitfin should review this for it to be merged)

lib/cachex.ex Outdated
Comment on lines 569 to 571
Cachex will store any value `fallback` returns. If you want more
control, return a Tuple like `{:commit, value}` or `{:ignore, value}`.
Passing `:ignore` instructs Cachex to not store the value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this is less clear than the original documentation. First saying "Cachex will store any value fallback returns" and then saying "Passing :ignore instructs Cachex to not store the value" are a bit contradictory.
The original documentation instead explained the function of :commit and :ignore, before saying that the fallback is :commit if none is provided.

Copy link
Author

@SergioInToronto SergioInToronto Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - I've addressed the contradictory statement. But I didn't change it back entirely. Let me know if this sounds better or if I should still revert the whole thing.

lib/cachex.ex Outdated
If a fallback function has an arity of 1, the requested entry key
will be passed through to allow for contextual computation. If a
function has an arity of 0, it will be executed without arguments.
`fallback` optionally receives `key` as an argument.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`fallback` optionally receives `key` as an argument.
The arity of `fallback` can be either 0 or 1. If the arity is 1, then the requested key will be passed as an argument to `fallback`.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. IMHO my sentence communicates the same information in fewer words, and the examples make this clear too.
  2. It's more elixir-y to talk about "arity". I think Elixir is fantastic but I don't like requiring new developers understand all the jargon before they can write useful Elixir code. There's no need to mention arity here - optional arguments is understood regardless if the reader is an expert or new to Elixir.

Comment on lines +584 to 587
iex> Cachex.fetch(:my_cache, "key", fn -> "value" end)
{ :commit, "value" }
iex> Cachex.fetch(:my_cache, "key", fn -> "value" end)
{ :ok, "value" }
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted show the return values in these two cases. I was surprised at first usage that :commit and :ok cases both exist.

@whitfin
Copy link
Owner

whitfin commented Mar 25, 2025

Hi @SergioInToronto and @HansGlimmerfors! Thanks for taking the time here.

I might be missing something, but I'm not really sure I understand how these changes are an improvement.

Explain behaviour where only 1 instance of lazy evaluation can run simultaneously

I don't think this needs to be covered in a function signature, it already has a dedicated area in documentation. Duplicating the explanation (but with significantly less detail) is an unnecessary extra maintenance burden.

Shorten explanation where possible

Cutting information only to make text smaller doesn't feel necessary to me. For example consider this:

As of Cachex v3.6, you can also provide a third element in a :commit
Tuple, to allow passthrough of options from within your fallback. The
options supported in this list match the options you can provide to a
call of Cachex.put/4. An example is the :expire option to set an
expiration from directly inside your fallback.

Which was replaced with:

You may provide a third element in a :commit Tuple, to specify options the
same as you would in put/4.

  1. The original documentation provides an example option, the most popular option, so that people likely don't even have to check what is supported.
  2. The original documentation states compatibility; it is clear that Cachex v3.5 does not support this.
  3. The word passthrough is important, because it means that the options are processed by put/4 specifically, rather than duplicated and handled by fetch/4.

Progressive complexity - explain the simplest usage first, adding complexity as the reader keeps reading.

I am fairly sure it is already written in this way. The only change I see that relates to this is:

Normally Cache stores the value returned by fallback.

The original documentation specifically points to :commit and :ignore first to push people to using those - there is an eventuality that the assumption of value = {:commit, value} will likely be phased out. It's inherited from earlier Cachex versions.

In general I'm leaning towards closing this PR without a merge. I could be convinced, particularly if @HansGlimmerfors wants to give their thoughts (in general), but as of right now I do not see the changes here as an improvement.

@HansGlimmerfors
Copy link
Contributor

In general I'm leaning towards closing this PR without a merge. I could be convinced, particularly if @HansGlimmerfors wants to give their thoughts (in general), but as of right now I do not see the changes here as an improvement.

I think @SergioInToronto's desire to help improve the documentation is great to see (but personally I prefer the original documentation). I would agree with @whitfin that these changes don't provide a strict improvement, so I think closing the PR could be the right way to go.

@SergioInToronto
Copy link
Author

SergioInToronto commented Mar 25, 2025

Thanks for the feedback both! I'll try to convince you my PR is an improvement. I opened it after my own experience (and confusion) using Cachex.

First, I started building a mechanism exactly like Cachex.Services.Courier because I didn't know fetch/4 would handle it for me. Maybe there's documentation elsewhere but I didn't find it. I almost implemented it myself and missed such a great feature! I think adding 1 sentence about it would help people.

Cutting information only to make text smaller doesn't feel necessary to me.

Shorter without cutting information is my goal. Let me fix any mistakes.

An example is the :expire option to set an expiration from directly inside your fallback.

That's a good point - I've added it back. I will say I found the code example more helpful than explaining in words. Maybe the example with :expire should come sooner. But both is good too.

The original documentation specifically points to :commit and :ignore first to push people to using those - there is an eventuality that the assumption of value = {:commit, value} will likely be phased out. It's inherited from earlier Cachex versions.

Fair enough, I didn't know it was deprecated. I was explaining the simple usage first, but since it's discouraged I'll swap them.

As of Cachex v3.6, ...

I agree it's clear, but the documentation is already versioned. IMHO there's no need to mention specific versions this way.

image

I've pushed changes to address your feedback. I hope it's OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants