Re: Change in semantics for some control flow operations

Jeremy Tregunna <[email protected]> Fri, 09 Dec 2011 16:58:06 -0600
Newsgroups gmane.comp.lang.io
Message-ID <[email protected]>
From all three versions, there's no difference from a user point of view. It doesn't change existing code, except in the case where they depend on values leaking out of the foreach() which as I said earlier, I believe is a bug anyway.

#1 doesn't clear any values, values persist after foreach() exits. I should have probably implemented a version which sets a value inside the body instead to demonstrate. Easy enough to do, change the three test lines to say: x := 1000000 instead, then after each try and print x :)

#2 Creates a context, performs the message in that context, and throws the context away when the foreach() exits, thus not polluting the callers locals.

#3 Does the same as #2, except it creates a block dynamically instead, then explicitly calls it; which means, on each iteration of the loop, we create a new locals. Conceptually, I like this the best, but the penalty is higher than I'd like. As such, #2 is the method I'd go about using to implement these changes.

On 2011-12-09, at 4:54 PM, edwakev wrote:

> 
> 
> Is there any difference between #1 and #2 from a user's point of view or is this strictly a question of implementation?
> 
> i.e. it looks like #1 basically clears the locals on every iteration, while #2 keeps them around in case the user declared a local in the loop he can use it on the next iteration. Is that right?
> 
> What will the syntax be for setting slots in the outer scope from within the loop?
> 
> Kevin
> 
> P.S. Yahoo's giving me a "Your email was not delivered due to a suspected guidelines violation." so I'm posting using the web form. Maybe it's just me. I'm not a spammer! Honest! :-)
> 
> --- In [email protected], Jeremy Tregunna <jeremy.tregunna@...> wrote:
> >
> > So... no input? Should I assume that this means there's no objection to this, or either implementation strategy?
> > 
> > Regards,
> > 
> > Jeremy Tregunna
> > 
> > On 2011-12-08, at 8:43 AM, Jeremy Tregunna wrote:
> > 
> > > 
> > > I want to propose a change in direction for the standard library foreach(), select(), and friends methods. I'll supply code, don't worry about that.
> > > 
> > > Right now, how we go about doing things is once we're iterating, we set values in the calling context directly. This has obvious problems worse than shadowing, i.e., overwriting values we want and persisting after the foreach() has finished. Now at present, anyone hit by this problem will have renamed their identifiers when they got bad results, but this is rather confusing. Additionally, why should we leak these values?
> > > 
> > > I'm proposing one of two solutions I think are a better fit:
> > > 
> > > 1. Set up a block with the argument name(s) we want to set, the body we want to evaluate, and the proper scope to capture (the sender). Call that inside our main loop.
> > > 2. Create a separate isolated context outside the loop, set our value(s) in it inside the loop, ask our body to doInContext with that context and the sender. This has a slight advantage performance wise in that we only create one context, as opposed to creating N locals with the block worst case (or recycling N locals depending on our environment).
> > > 
> > > Now, this does have the negative use in that it breaks operational semantics of these methods at present if a user depends on this behaviour, but I'm ok with that; I'd consider that behaviour broken anyway.
> > > 
> > > I think this should be done to all the standard library objects that support these types of constructs. Take some of the surprise out of using them.
> > > 
> > > Regards,
> > > 
> > > Jeremy Tregunna
> > > 
> > > 
> > > 
> > > 
> > >
> >
> 
> 

Regards,

Jeremy Tregunna