inexorabletash / jslogo

Logo in JavaScript
https://calormen.com/jslogo
Other
368 stars 146 forks source link

Proposed process system #75

Open ianb opened 8 years ago

ianb commented 8 years ago

A proposal on processes:

Then there's a design question about scoping. It also relates some to how processes are launched. For instance, let's imagine FOREVER always launches a process (like in MicroWorlds), then you can imagine this:

Then if you call SQUARES 100 the routine would immediately return while launching that process. But in this case the routine needs to be closed over the local variable :SIZE. (Or closed over the value of :SIZE? E.g., if you add MAKE "SIZE 50 after the FOREVER would it affect the square sizes?)

So I can't quite decide if the process should get the scopes when it was launched (a copy of the list), or maybe a copy of the scopes? And would it create a new scope? You might imagine:

to squares
  make "size 100
  forever [square :size wait 100]
  onkey "up [make "size :size + 10]
  onkey "down [make "size :size - 10]
end

Should they all be running in the same scope? Presumably the ONKEY handlers would run in their own process as well...? This makes me think the new processes should get the exact list of scopes when the process is started, not copies, nor should they add new local scopes. Though maybe how MAKE works (as opposed to LOCAL/LOCALMAKE) makes this less concerning.

For the processes to bind to the local scope, we need some sort of turn-list-into-a-callback routine. For instance ONKEY here would have to call that, because probably the handlers would only be invoked after SQUARES returned. (FOREVER doesn't encounter this because it would start to call its argument before SQUARES is allowed to continue.) Ah, the problems of not having explicit lambdas or lexical scope...

Then there's the separate question of "objects", such as multiple turtles. I would suggest these also exist in the main interpreter, as global named resources. The process however would have a property for the "active" turtle.

I think processes should have a name (like P1, P2, etc), some aliases (like [square :size wait 100] – this is how MicroWorlds addresses naming, which gives a predictable way to get to a process if you don't capture the name), and a reason. The thing that launched the process would also assign the reason, which would be a description – probably the way the process was invoked, maybe we could use some private interpreter knowledge to improve the description further.