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

Map key becomes "valid/existing" after value lookup #247

Closed
luauser32167 opened this issue Dec 10, 2022 · 3 comments
Closed

Map key becomes "valid/existing" after value lookup #247

luauser32167 opened this issue Dec 10, 2022 · 3 comments
Labels
duplicate This issue or pull request already exists question How to use the language

Comments

@luauser32167
Copy link
Contributor

fn main() {
  m := map[int]str{};
  printf("%d\n", int(validkey(m, 69105))); // not valid
  var s: str = m[69105];
  printf("%d\n", int(validkey(m, 69105))); // but now valid
}
@vtereshkov
Copy link
Owner

vtereshkov commented Dec 10, 2022

@luauser32167 This is the intended behavior, similar to that of std::map in C++. It is discussed in detail in #170

@vtereshkov vtereshkov closed this as not planned Won't fix, can't repro, duplicate, stale Dec 10, 2022
@vtereshkov vtereshkov added duplicate This issue or pull request already exists question How to use the language labels Dec 10, 2022
@luauser32167
Copy link
Contributor Author

luauser32167 commented Dec 10, 2022

This is a bit surprising...
@vtereshkov have you considered the approach that 'stb/ds.h' uses for its hashmaps? It has a setter function which sets the "default value" for the hashmap. When a key is used for lookup with the function 'hmget', and it isn't found, the value of the default item is returned.

Basically it has the following semantics:

  m1 := map[int]str;
  printf("%s\n", m1[69105]); // "" (empty string, because the default value is zero initialized)
  mapsetdefault(m1, "leaves");
  printf("%s\n", m1[69105]); // "leaves"
  printf("%s\n", repr(m1)); // { } (no keys)

  type Point = struct { x, y: int };
  m2 := map[str]Point;
  m2["origin"].x = 10; // sets the default value's 'x' field to 10 (because the key "origin" was not found)
  printf("%s\n", repr(m2)); // { } (no keys)
  m2["origin"] = Point{10, 20};
  printf("%s\n", repr(m2)); // { "origin": Point{x: 10, y: 20} } (now has 1 key called "origin")
  printf("%d\n", mapgetdefalut(m2).x); // the default value's 'x' field is still 10

@vtereshkov
Copy link
Owner

vtereshkov commented Dec 10, 2022

@luauser32167 The following is even more surprising for me than having m2["origin"] initialized on first access:

m2["origin"].x = 10; // sets the default value's 'x' field to 10 (because the key "origin" was not found)
printf("%s\n", repr(m2)); // { } (no keys)

Assigning m2["origin"].x = 10 is a clear indication that I want m2["origin"] to exist. But m2 is still empty. That's weird.

Here is what C++ is doing: https://www.onlinegdb.com/_2_bEnIeRK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists question How to use the language
Projects
None yet
Development

No branches or pull requests

2 participants