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

ERROR: attempt to clone a non-affine global reference #709

Open
angeloocana opened this issue Sep 6, 2024 · 1 comment
Open

ERROR: attempt to clone a non-affine global reference #709

angeloocana opened this issue Sep 6, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@angeloocana
Copy link

Reproducing the behavior

I'm getting the error ERROR: attempt to clone a non-affine global reference. when I call a function to create a Map or List and then pass it to another function. Example:

empty = 0
white = 1
black = 2

def get_initial_board():
  return { 0: black, 1: white, 2: empty }

def get_empty_positions(board):
  # We don't even need to use the board variable, just passing it to this function raises the error
  return [2]

def get_possible_moves(board, pieces):
  fold pieces with pieces_with_possible_moves = []:
    case List/Cons:
      return pieces.tail(List/Cons((pieces.head, get_empty_positions(board)), pieces_with_possible_moves))
    case List/Nil:
      return pieces_with_possible_moves

def main():
  board = get_initial_board() # If I call any function to create the board I get the error
  # board = { 0: black, 1: white, 2: empty } # If I create the board here it works
  pieces = [0]
  possible_moves = get_possible_moves(board, pieces)
  return possible_moves

bend run test.bend -s gives this error:

ERROR: attempt to clone a non-affine global reference.

Errors:
Failed to parse result from HVM.

bend run-c test.bend -s works fine:

Result: [(0, [2])]
- ITRS: 369
- TIME: 0.00s
- MIPS: 0.16

System Settings

Example:

  • HVM: 2.0.22
  • Bend: 0.2.36
  • OS: Apple M2 Max, Sonoma 14.5

Additional context

No response

@developedby developedby added the bug Something isn't working label Sep 9, 2024
@developedby
Copy link
Member

get_initial_board gets passed as the argument board and then cloned inside get_possible_moves.

This is one of the cases where the heuristic for finding the problematic cases is too strict. This function has some duplications inside it, but not in its normalized form.

The function desugars to Map/set(Map/set(Map/set(Map/empty, 0, black), 1, white), 2, empty), and Map/set duplicates the key (0, 1 and 2 in this example). However, after normalizing, get_initial_board reduces to just an ADT value and not a function so the duplications are not a problem.

Unfortunately this check happens directly at runtime with no way of disabling it for your specific function. Ideally we'd have a type system that can assertain whether or not a value will have problematic duplications, but that's not planned for the immediate future.

For now, you can circumvent this issue by applying a dummy value to the function that forces its evaluation:

def get_initial_board(dummy):
  return { 0: black, 1: white, 2: empty }

...

def main():
  board = get_initial_board(*)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants