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

instant seems to have no effect when wrapped around definitions #2270

Closed
byorgey opened this issue Jan 5, 2025 · 1 comment · Fixed by #2271
Closed

instant seems to have no effect when wrapped around definitions #2270

byorgey opened this issue Jan 5, 2025 · 1 comment · Fixed by #2271
Labels
Bug The observed behaviour is incorrect or unexpected.

Comments

@byorgey
Copy link
Member

byorgey commented Jan 5, 2025

Describe the bug
instant, when wrapped around a term that includes some expensive defs, seems to have no effect.

To Reproduce
In the below scenario, the judge does an expensive computation (naive fib 10), then places a rock. The base robot just executes move; grab. Since the entire judge program is wrapped in instant, this ought to work: the entire judge program including the expensive computation and the place command should all execute in a single tick, placing the rock in time for the base to grab it. However, the base crashes with a "nothing here to grab" error, and the rock shows up later.

version: 1
name: Instant wrapped defs
description: |
  `instant` should work when wrapped around definitions
creative: false
objectives:
  - goal:
      - Grab the rock
    condition: |
      as base { has "rock" }
robots:
  - name: base
    dir: east
    devices:
      - logger
      - treads
      - grabber
  - name: judge
    dir: east
    system: true
    program: |
      instant (
      def fib : Int -> Int = \n.
        if (n <= 1) {n} {fib (n-1) + fib (n-2)}
      end

      def x = fib 10 end

      create "rock"; place "rock"
      )
solution: |
  move; grab
known: [rock]
world:
  dsl: |
    {grass}
  palette:
    'B': [grass, null, base]
    'j': [grass, null, judge]
  upperleft: [0, 0]
  map: |
    Bj

Additional context
Ran into this while preparing #2260. See the discussion here: #2260 (comment)

@byorgey byorgey added the Bug The observed behaviour is incorrect or unexpected. label Jan 5, 2025
@byorgey
Copy link
Member Author

byorgey commented Jan 6, 2025

Ohhhh, I understand why this happens: it's because Swarm is a strict language, so the argument to instant is evaluated first, before passing it to instant! In this case, evaluating the argument includes evaluating the values of the definitions.

So this is not exactly a bug, but it is confusing, and we might want to consider special-casing it somehow...

mergify bot pushed a commit that referenced this issue Jan 6, 2025
…#2271)

Since Swarm is strict, the way an application `instant c` works is as follows:

1. Evaluate the LHS `instant` to a value (immediately succeeds since it is just a constant)
2. Evaluate the RHS `c` to a value
3. Perform the function application `instant c`, by atomically executing the command represented by `c`

Usually, step (2) succeeds almost instantly as well.  For example if `c` is something like `move; move; turn right; move` then it just instantly turns into a command value.  However, `c` could be something like `def x = (expensive pure expression) end; other stuff` in which case evaluating `c` will cause the definition of `x` to be (expensively) evaluated.

This PR rectifies the situation by ensuring that not only are `instant`/`atomic` *executed* atomically, but also their argument is *evaluated* atomically.  Fixes #2270.
@mergify mergify bot closed this as completed in #2271 Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug The observed behaviour is incorrect or unexpected.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant