-
Notifications
You must be signed in to change notification settings - Fork 3
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
Empty map can be assigned to #4
Comments
good catch. I believe this is due to the same resizing behavior that affects slices. From the README:
In theory, then, this behavior should be observed whenever inserting into a map causes it to resize. So it's more insidious than simply breaking on empty maps. There's probably some other field of the map that can be frozen to restore the desired behavior. But maps are annoying because their memory layout isn't nearly as stable as slices -- it changes in nearly every minor release. Worse, this code assumes that you're using the standard Go compiler (instead of, e.g. The best we can probably do is update the implementation for each new Go release, and guard the various implementations with build tags. Unfortunately I am rather busy right now so I'm not sure when I'll get around to it. |
Hey Luke,
Its no big thing and I can always get off my ass and do a pull if I really
need it.
I'm writing an immutable data store for Go and this is handy for testing
that certain code does not mutate data (immutable, in that there is a
contract not to mutate data, as I'm not using your library in the code).
I can see how this is always going to be a problem with each release.
Really, Go needs some version of a contract when a function receives a
variable that it will not be altered. I'm not a language designer to any
degree, can't say I like C++ overloaded const operator. Maybe something
like func (v $map[string]*int), where $ indicates that the map nor any of
its contained object cannot be changed by the function or
functions/goroutines it calls.
I've thought about some type of ast checker for this, but again, not a
compiler programmer so I'm not sure how nasty this would get. Seems doable
from the 5 second glance, but I've been around long enough to know that
"seems doable" ends up being a lot harder than thought.
Thanks for the quick reply Luke, appreciate it.
…--John
On Mon, Jul 3, 2017 at 12:24 PM, Luke Champine ***@***.***> wrote:
good catch. I believe this is due to the same resizing behavior that
affects slices. From the README:
Appending to a frozen slice will trigger a panic iff len(slice) <
cap(slice). This is because appending to a full slice will allocate new
memory.
In theory, then, this behavior should be observed whenever inserting into
a map causes it to resize. So it's more insidious than simply breaking on
empty maps.
There's probably some other field of the map that can be frozen to restore
the desired behavior. But maps are annoying because their memory layout
isn't nearly as stable as slices -- it changes in nearly every minor
release. Worse, this code assumes that you're using the standard Go
compiler (instead of, e.g. gccgo). The same issue affects my randmap
<https://github.com/lukechampine/randmap> package.
The best we can probably do is update the implementation for each new Go
release, and guard the various implementations with build tags.
Unfortunately I am rather busy right now so I'm not sure when I'll get
around to it.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#4 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABMMrmRR5jWs0y8fHpbDDkWfmxA7KijHks5sKUALgaJpZM4OMl29>
.
--
John Doak
www.obscuredworld.com
|
Ah, I'm glad to hear that someone found a real use for this package. And that it's being used properly (for testing only) rather than running in production code or something... There have been proposals to add a "const"-like keyword to Go, but they haven't gone anywhere. For example, there was a read-only slices proposal, but it was found to bifurcate the language APIs too much; see this response. As for static analysis, you can likely do a decent job, but not a perfect one. For example, whenever you use an interface: func writeData(w io.Writer, data []byte) {
w.Write(data)
} It's difficult (maybe impossible) for a static analysis tool to determine whether f, _ := os.Open("foo")
f.Write(data) The compiler knows that the Anyway, I think such a tool would be simple in theory. You just need a list of mutation syntaxes, like
Then the user could optionally modify btw, you may be interested in |
Looks like an empty map that is frozen does not get protection. You can alter it as much as you want.
Code showing incorrect behavior:
Code showing correct behavior:
The text was updated successfully, but these errors were encountered: