On 8/16/05, Tim King <[EMAIL PROTECTED]> wrote:
> Ben Tilly wrote:
> >> I agree that using eval here is wrong. But I still
> >> don't see action at a distance.
> >
> > You can argue about whether it is action at a distance, but you
> > have tight coupling between the internals of make_generator
> > and the string passed into it that was generated from very far
> > away.
> 
> Correct. A function that uses eval() does so in its own context. I don't
> see what makes this a problem with eval(). Rather, it's a concern that
> affects the software design.

Well this thread started with someone looking for reasons not to use
eval.  Pointing out that certain ways of trying to use eval affect the
software design in negative ways is a good reason to not use eval in
some situations.

> >> The problem in this example is that make_generator doesn't make a
> >> generator.
> >
> > I know full well what the problem is.  And the result is that you
> > cannot consider using code generation for a situation like this.
> 
> Not if you want to make a generator as you have tried, no. My point was
> that this is not a problem with eval(); it's a problem with your
> proposed design.

You can place the blame wherever you want to.  But with a more
capable version of eval, you can make the proposed design work.

Of course since Perl doesn't *have* capable enough version of
eval, you can't make it work in Perl...

> I use eval() when I don't know what the code is until runtime, or to
> execute code generated in one place in a context generated from another.
> But I can't recall a case like the latter that wasn't also an instance
> of the former.

> >>   sub foo {
> >>     my $x = 7;
> >>     my $generator = sub{++$x};
> >>     print $generator->() for 1..5;
> >>   }
> >
> > But in general you're now
> > prevented from adding various kinds of syntactic sugar,
> > manipulating the passed in code before compiling it, etc.
> 
> If you really need to manipulate the code, you apply the syntactic sugar
> when generating the code string. Then you invoke eval() in whatever
> context the code should execute.

The problem is that the place where you'd like to centralize the
code manipulation, calling eval, catching errors etc is in one
place, and the code that you'd like to manipulate is in another.
You *can* achieve the desired flow of control, but the only way
that I can think of doing it in Perl is to require the caller to pass
in sub {eval(shift)} (which will do an eval in the caller's context).
That's an ugly construct to have to throw in when you were
trying to create syntactic sugar.

> Or alternatively, you can pass to the code-generator an evaluation
> context that the generated code will use. One might use a technique like
> this when using Perl as a scripting language within a Perl program, for
> example.

I suspect that you mean something like the sub {eval(shift)} that
I mentioned above.

> >> Note that $generator... is a true coroutine.
> >
> > It is not a coroutine.  It is a closure.
> 
> It is both a closure and a coroutine.

If it is a coroutine, then you should be able to return multiple times
and restart the call each time.  (Traditionally done with a yield
operator.)

I don't see that capability there...

Cheers,
Ben
 
_______________________________________________
Boston-pm mailing list
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to