Navigation Menu

Skip to content
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

proposal: sync: Map LoadOrStore interpret functions for value #45414

Closed
pjebs opened this issue Apr 7, 2021 · 5 comments
Closed

proposal: sync: Map LoadOrStore interpret functions for value #45414

pjebs opened this issue Apr 7, 2021 · 5 comments

Comments

@pjebs
Copy link
Contributor

pjebs commented Apr 7, 2021

func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)

The proposal states:

  1. That LoadOrStore accept an optional argument that forces it to interpret value more intelligently.
  2. "More intelligently" is defined as: if value is of type FuncLit with a single return value, then if the key does not exist in the map, it calls value and stores the return value.

Depending on the ambit of Go1 compatibility promise, feel free to mark this as a Go2 proposal.

Alternatively, a new method can be added to Map that has this behaviour built-in.

@gopherbot gopherbot added this to the Proposal milestone Apr 7, 2021
@pjebs pjebs changed the title proposal: sync: map LoadOrStore interpret functions for value proposal: sync: Map LoadOrStore interpret functions for value Apr 7, 2021
@pjebs
Copy link
Contributor Author

pjebs commented Apr 7, 2021

Essentially an atomic version of:

	val, exists := map.Load(key)
	if !exists {
		val, _ = map.LoadOrStore(key, func())
	}
	
	
	... = val

@ianlancetaylor
Copy link
Contributor

CC @bcmills

We can't change the existing LoadOrStore method but we could in principle add a new method.

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Apr 7, 2021
@cespare
Copy link
Contributor

cespare commented Apr 7, 2021

@ianlancetaylor if I understand correctly the proposal is to add a special case where if value interface{} is a func() interface{} (say) then use it as a callback. Now that isn't backward compatible as-is, but if we added a new type type LoadFunc func() interface{} and only looked for values of that named type then it would be.

To me, overloading this API by shoehorning a callback into the value interface{} seems worse than adding a new method.

Either way, though, I think this has a sharp edge. The callback function cannot block any other Map method, including concurrent LoadOrStores (that would be antithetical to sync.Map). (To put it another way, it is not possible to implement that code snippet which includes a user-provided callback atomically without introducing unacceptable blocking.) It follows that the callbacks may be called multiple times concurrently. I think users may find that surprising.

@tmthrgd
Copy link
Contributor

tmthrgd commented Apr 7, 2021

This seems like a clear duplicate of the recently declined #44159.

@rsc
Copy link
Contributor

rsc commented Apr 7, 2021

Duplicate of #44159.

@rsc rsc closed this as completed Apr 7, 2021
@rsc rsc moved this from Incoming to Declined in Proposals (old) Apr 7, 2021
@golang golang locked and limited conversation to collaborators Apr 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

6 participants