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

[Macros] Unique VM Id for ref objects and NimNode #131

Closed
mratsim opened this issue Feb 16, 2019 · 3 comments
Closed

[Macros] Unique VM Id for ref objects and NimNode #131

mratsim opened this issue Feb 16, 2019 · 3 comments
Labels

Comments

@mratsim
Copy link
Collaborator

mratsim commented Feb 16, 2019

I'm quite often in need of an unique identifier in macros to use NimNodes and other ref types in Tables and HashSets.

Looking into the implementation of == for ref types (mEqRef magic), it seems like they have a rkNodeAddr that could serve this purpose.

The current alternative is to have a compile time Id with a scheme similar to this.

type
  MyRef = ref object
    value: int

    # Cannot use when nimvm for object fields
    id: int

# 1. First, show that at compile-time ref objects are still considered different
static:
  let x = MyRef(value: 0, id: 0)
  let y = MyRef(value: 0, id: 0)
  let z = y

  assert x != y
  assert x != z
  assert y == z

# 2. Now the workaround needed at compile-time to store them in HashSet/HashTables
import random, hashes

var myRefRng {.compileTime.} = initRand(0x42)

proc newRef(value: int): MyRef =
  new result
  result.value = value

  when nimvm:
    result.id = myRefRng.rand(high(int))
  else: # Necessary otherwise illegal context
    discard

proc hash(x: MyRef): Hash =
  when nimvm:
    Hash(x.id)
  else:
    cast[Hash](x)
@Araq
Copy link
Member

Araq commented Feb 17, 2019

I think reference semantics are pretty bad and the hash should capture the structure of the tree. Nodes do not have an identity, they can be copied.

@mratsim
Copy link
Collaborator Author

mratsim commented Feb 18, 2019

Currently I use = in macros when I want shallow copies and copyNimTree when I want deep copy.

In my case I want ref semantics because I want to use my type at both compile-time and runtime, having different semantics would be harder to maintain.

Furthermore I'm using this to implement my own AST and reference semantics are easier to work with for scoping:

block:
  let a{.compileTime.} = newRef(10)

block:
  let a{.compileTime.} = newRef(10)

^ The a are not the same.

@github-actions
Copy link

github-actions bot commented Jun 3, 2023

This RFC is stale because it has been open for 1095 days with no activity. Contribute a fix or comment on the issue, or it will be closed in 7 days.

@github-actions github-actions bot added the Stale label Jun 3, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants