reset password
Author Message
rabbott
Posts: 1649
Posted 20:00 Feb 25, 2018 |

Here's a function that may be useful when debugging NetLogo code.

to-report trace-as-reporter [before value after]
  if before != "" [show (word "before: " before)]
  if value != "" [show (word "will report: " value)]
  if after != "" [show (word "after: " after)]
  report value

end

This function can be used to see the value of agents, fields, globals, etc. before and after a reporter is executed. For example, suppose you have a global variable x and a function that increments and returns its square.

to-report increment-and-square-x
  set x x + 1
  report x * x
end

The following will show x before and after calling square-and-increment-x. It will also return the value that increment-and-square-x returns.

trace-as-reporter x increment-and-square-x x

Assuming the value of x is 1, this is how it looks from the command center.

observer> show trace-as-reporter x increment-and-square-x x
observer: "before: 1"
observer: "will report: 4"
observer: "after: 2"
observer: 4

trace-as-procedure will provide a similar service for procedures.

to trace-as-procedure [before value after]
  if before != "" [show (word "before: " before)]
  if after != "" [show (word "after: " after)]
end

Even though you want to trace a procedure, you must wrap the procedure in a reporter so that it can be passed to trace-as-procedure. For example, here's how you could trace tick. First write a reporter that wraps tick.

to-report tick-as-reporter
  tick
  report ""
end

Then

observer> trace-as-procedure ticks tick-as-reporter ticks
observer: "before: 0"
observer: "after: 1"

The value returned by tick-as-reporter is ignored since all we care about is executing tick.

An earlier version of this code was included in utils.nls. It has since been updated.

Last edited by rabbott at 20:05 Feb 25, 2018.
RobertKarapet
Posts: 20
Posted 20:03 Feb 25, 2018 |

Thanks. It is a pity there is no way to pass x by value. 

rabbott
Posts: 1649
Posted 20:08 Feb 25, 2018 |

It is passed by value.

RobertKarapet
Posts: 20
Posted 20:09 Feb 25, 2018 |

Reference I meant

rabbott
Posts: 1649
Posted 22:07 Feb 25, 2018 |

In some ways passing by value vs passing by reference is somewhat obsolete. Primitive values like numbers and Booleans are almost always passed by value: a copy of the primitive is sent to the subprogram. Agents and objects are generally passed by pointer. I'm sure you know this, but when you pass an agent or an object to a subprogram, a pointer (reference) to the object is passed. But the reference is a value. What gets passed is a copy of the pointer!

The original distinction was between passing by value and passing by name. Passing by name meant that something like the name of the local variable whose value is being passed is sent to the subprogram. The subprogram can then change the value in the passing program's local variable. That would happen even if the value being passed is a primitive. A reference to the local variable that holds that primitive value is passed.

In my opinion we often get too hung up on terminology. Doing so obscures what's really happening. As in the case of agents, a reference to the agent is passed. So the program has the ability to change the agent. But the agent itself doesn't change its identity.

In C a struct was often copied and passed, which is truly passing by value. The subprogram doesn't have a way to change the original version of the struct. Java doesn't have a way of doing that. All one can do in Java is pass a pointer to an object, not a copy of the object. Passing a pointer makes a lot more sense to me. One wants the object to retain its identity since other elements of the system may also refer to it.

Last edited by rabbott at 22:09 Feb 25, 2018.
RobertKarapet
Posts: 20
Posted 23:14 Feb 25, 2018 |

Thanks for your insights on the pointers. 

I have been debugging differently. I attached a video to this comment to demonstrate my way of debugging.

Attachments:
rabbott
Posts: 1649
Posted 09:02 Feb 26, 2018 |

Nice use of the output area.