Environments

PS in making the above-mentioned changes, I noticed (remembered?) that the way tag spaces are returned from environments is weirdly all-or-nothing. If I’m understanding it correctly, all changes to the tag space in an environment are lost when you leave it, unless you execute return_tagspace, in which case they are all retained (or maybe just those after or before the call? not sure about that).

If anybody is looking at how environments and tags interact (and/or wants to try an idea we’ve discussed, of automatically wrapping tag-retrieved code in environments), then you should definitely take a closer look at this and maybe consider alternatives.

2 Likes

Looking into implementing map/filter for the code and exec stacks in Push, and I believe that environments will be necessary in doing so. After doing some initial experimentation, I wonder: would there be any benefit to flushing the stacks after creating a new environment? It seems like it might be beneficial to have a truly empty environment when creating a new one. Or perhaps not, since it wouldn’t follow with the idea of a “local scope” for Push. What are everyone’s thoughts?

2 Likes

I’ve never actually used environments in Push, so feel free to ignore all of this. My sense, though, is that environments are kind of like a function call. In most programming languages data comes in to a function call via arguments, and leaves via return values (or pointers or globals if you’re in an ickier part of the world).

In that context, I would expect a new environment to have a clean set of stacks, which it can then populate at will, using information passed in arguments as necessary.

In theory the arguments could be on stacks, but I think this is probably Not A Good Idea; the fact that @thelmuth, et al, moved to primarily having input registers instead of inputs on stacks is a sign of this. Inputs on stacks is fragile and hard to work with if there are lots of arguments that you process in a non-linear way.

The trick, though, is then figuring out how to evolve the number/type of arguments and how they’ll be made available to the new environment. Lots of people have gotten stuck on that part of the problem in related systems, and I don’t have any great ideas there, I’m afraid.

2 Likes

The idea we had in mind, I think, is that arguments would be passed in via stacks, in part because the implementation for this is just leave all of the stacks as they are, and because the numbers and types of arguments that code executed in an environment get is just whatever they want.

So it’s a function call that has access to all data in the calling environment, and returns just what it explicitly says to return with return_* and return_*_pop instructions.

Since that seemed both flexible and easy, it’s what we did. That said, I don’t think that anybody has any idea whether it’s actually a good design!

Another option is to always flush the stacks when entering an environment, and to rely on tags to bring in arguments. This would still allow the number and types of “arguments” that are actually used to evolve.

Note that that last suggestion probably interacts with (open?) issues regarding how tagspaces are processed when returning from environments… I haven’t looked back at that part of this thread to figure that out.

With respect to your larger goals, @jscacco, did you know that there’s already a code_map instruction? It’s uncommented and I don’t know if it’s documented anywhere, so maybe not! :blush: Also, maybe it doesn’t do what you want. And I don’t think we have or maybe have ever had a code_filter, which sounds like a nice idea to me.

1 Like

Funnily enough, I didn’t know that code_map was already implemented! However, @thelmuth and I discussed creating a map/filter that utilizes new environments so that the existing stacks would not need to get involved in keeping track of the process. The idea being that keeping track of the mapping and such within the base environment could lead to unintended manipulation of the program.

This is following some changes I made in my own fork over the past few weeks: I implemented an :index stack that is used by iterative instructions as well as those that input/output a number. I am not sure what effect this has had on the general effectiveness of the system, as I am currently waiting on test results from the HPC.

So, I think I will attempt to recreate code_map, as well as add exec_map that utilizes environments. I think that, in order to do this, I might want to change the way the return stack works and perhaps implement it in the system as a whole. I’ll keep you updated!

3 Likes

I see lots of good ideas here, and without any good intuition as to what would be friendliest to evolution, I’d suggest an empirical comparison might be useful.

  1. Use environments as-is, with full stacks copied.
  2. Flush stacks when entering an environment.

If 2, then there are further options for passing arguments:

  1. Keep the tagspace, so that it could be used for passing arguments.
  2. Use registers in some way like the automatic in1, in2, etc. instructions. I could imagine this being the easiest option for implementing something like map/filter, since the element of the list under consideration could be the value passed to the register.
  3. Maybe we need a stack like the return stack, except opposite: an argument stack. Its instructions would move items from other stacks to the argument stack, which would then be pushed onto the appropriate (flushed) stacks when a new environment is started. This option sounds potentially the most general, but also maybe the most complex to code, and maybe the hardest for evolution to use.

Anyway, I would certainly be interested in seeing experimental comparisons between two or more of these!

2 Likes

Does anyone recall if Push environments have been described in any publications (aside from this thread :slight_smile:)?

2 Likes

Not to my knowledge. I don’t think we’ve used them in any experiments that were published. I can think of a few instances of where we’ve used them in conjunction with other things (tags, @jscacco’s map/filter instructions), but I don’t know that we’ve even done a vanilla “does adding environment instructions help” experiment.

1 Like

@aks has also done some experiments in conjunction with tags… and we just discussed some other ideas that I’ll move to another thread (since this one is in Orientation).