modelop / hadrian

Implementations of the Portable Format for Analytics (PFA)
Apache License 2.0
130 stars 49 forks source link

Incorrect Scoping Behavior in "set" Special Form #43

Open nrpeterson opened 7 years ago

nrpeterson commented 7 years ago

My understanding from the documentation is that all assignments in a "set" special form should be done in a copy of the scope -- that is, if one assignment updates a counter, and another USES the counter, then the second one should be seeing the value of the counter from before the update.

However, in Hadrian, that doesn't seem to be the case. For instance, take the following (silly) example:

{
  "input": "int",
  "output": "double",
  "action": [
    {"let": {"i": 0, "total": 0.0}},
    {
      "while": {"<": ["i", "input"]},
      "do": [
        {
          "set": {
            "total": {
              "do": [
                {"log": ["i"]},
                {"+": ["total", {"m.pi": []}]}
              ]
            },
            "i": {"+": ["i", 1]},
          }
        }
      ]
    },
    "total"
  ]
}

If I run this in the web UI at dmg.org, I get the following:

[LOG] 1
3.141592653589793
[LOG] 1
[LOG] 2
6.283185307179586
[LOG] 1
[LOG] 2
[LOG] 3
9.42477796076938

We should, of course, be seeing 0, then 01, then 012.

Interestingly, if I switch the order of the two updates in the JSON document, it seems to switch the order of the updates: I see 0, 01, 012 for that.

Obviously, this is a contrived example; but, I'm having the same problem in a much more important case (looping through a couple of arrays, acting on their indices and updating them simultaneously) in the most recent build I've pulled from github.