On 10/30/06, Bob Rogers <[EMAIL PROTECTED]> wrote:
>    From: "Ben Tilly" <[EMAIL PROTECTED]>
>    Date: Mon, 30 Oct 2006 00:00:54 -0800
>
> I'll be brief(er); my hands are beginning to hurt.

I'm sorry that you have carpal tunnel like symptoms. :-(

Random tip.  If your hands hurt and you drive a standard, drive an
automatic instead.  A stick shift is hard on your tendons.

>    On 10/29/06, Bob Rogers <[EMAIL PROTECTED]> wrote:
>    >
>    > I don't follow.  That reliable destruction happens when all pointers to
>    > $arg are destroyed; tail-calling bar would also destroy them when bar
>    > returned, though in the opposite order (bar's reference last instead of
>    > foo's reference last).  In other words, it doesn't matter whether foo or
>    > bar destroys the value, as long as it's the last reference.
>    >
>    >    It's true that ReleaseAction can call its actions prematurely in the
>    > event of a tailcall, depending on where the object reference is kept,
>    > but that's a separate issue.
>
>    That's not just a separate issue, that's the whole issue.  Perl has
>    precise semantics for when DESTROY is called . . .
>
> The perlobj page (5.8.1) says the following:
>
>        Destructors
>
>        When the last reference to an object goes away, the object is
>        automatically destroyed.  (This may even be after you exit, if
>        you've stored references in global variables.) . . .
>
> This is precise in the sense of being well-defined, but not in the sense
> of nailing the "when" down as tightly as you seem to expect.  In
> particular, the attached use of ReleaseAction confirms that tail-merging
> does affect when a destructor is called.  But both behaviors (before bar
> is called and after it returns) seem legitimate in light of what the doc
> says.  Which implies that tail-merging despite the "my" variable would
> be legitimate, if Perl ever did tail-merging.

I said the semantics were precise, not precisely documented. :-)

When it comes to corner cases, Perl's behaviour is defined by the
implementation, and the Perl maintainers are very careful to not
accidentally change that.  In this case there is even a core module
that depends on the exact semantics remaining the same.  Therefore,
documented or not, this behaviour is very unlikely to change in Perl
5.  And were I worried, I'd submit some test cases to be sure it
didn't change by accident.

>    > I've done this on occasion, but it's pretty ugly, and the benefit is
>    > slim; I usually don't bother.  If you do
>    >
>    >     my $foo = sub {
>    >         ...
>    >     };
>    >
>    > you will find that $foo is not even in its own scope.  And those names
>    > don't show up in backtraces, so the sub is still anonymous as far as the
>    > rest of Perl is concerned.
>
>    Write that as:
>
>        my $foo;
>        $foo = sub {
>            ...
>        };
>
> Which is only slightly uglier, IMHO, but adding more mutually-recursive
> functions makes it worse . . .

Well you could write y combinators instead. :-)

(Except that you can't properly do so in Perl because you need to use
assignment to process arguments and put them in lexical scope.  Which
loses sight of the fact that one of the points of y combinators is to
not have any assignments.)

>    Believe me, I've gone down this path, taken a look at the finished
> code, and then wished I hadn't.

Not to mention the minor issue that this approach leaks memory. :-(

>    As for giving names to anonymous functions in backtraces,
>    http://search.cpan.org/~xmath/Sub-Name-0.02/lib/Sub/Name.pm may assist
>    you. :-)
>
> Now *that* is useful; thank you.

You're welcome.

[...]
>    My memory said that continuations in Ruby worked this way, but I just
>    double-checked and they don't restore global variables.  That seems to
>    have been a misunderstanding on my part . . .
>
>    I'm aware that there are multiple ways to implement continuations.
>    But to answer your question, I'm not deeply familiar with the runtime
>    internals of any of these languages.
>
> So . . . have you *used* explicit (exit) continuations in any of these
> languages?  At the start of this thread, you made an assertion about the
> difficulty of debugging code that uses (exit) continuations.  Was this
> just a theoretical position?

I have used explicit continuations, but not in anything more than test
code.  Therefore my position is mostly theoretical.  However there is
no shortage of people who HAVE used explicit continuations whose
position matches my own.

[...]
>    I think we're talking past each other again.
>
>    You've just described how to implement continuations using closures.
>    However the effect is that within Scheme, you write normal code and
>    exit continuations are available.
>
> Yes, I have described (albeit with much hand-waving) how to implement a
> Scheme compiler, providing full Scheme continuations with only closures.
> Isn't that what you were "failing to see"?

No, that is not what I was failing to see.  What I was failing to see
is something that you've admitted isn't possible with closures.  Which
is to take an existing callback library in a language with
continuations and do the kinds of things with it that you can do with
continuations.

I wasn't asking how one would implement a language with continuations
starting in a language with closures.  If I really wanted to know that
then I'd just re-read SCIP more closely.

>    To use the technique within CL or Perl you'd have to first rewrite
>    all of your existing code in an usual style, and then you'd have
>    something that works like an exit continuation, but only for your
>    rewritten code.
>
> Or write a macro that rewrites it for you.  But, yes, you'd have to
> treat all other code as primitives.  It would probably be easier just to
> write in Scheme directly.  ;-}

Which was my point.  I agree that if you code very carefully you can
achieve the same effects as continuations without having them.  Alan
Turing demonstrated that to my satisfaction.  But when you have
continuations you can achieve those effects without having to have all
of the code you write explicitly trying to cooperate.

>    (Doing it in Perl would waste tons of stack space, but that is
>    neither here nor there.)
>
> Only if you (or your macro/preprocessor) didn't "goto $continuation".

At least in some versions of Perl that leaked memory.  I don't think
it does any more, but it is still slow.

>    > Sorry; I didn't explain that part because I didn't think it was
>    > pertinent.  "(def has-parts-mixin)" in the formal parameter list of a
>    > defmethod means that the variable "def" is bound to an object of class
>    > "has-parts-mixin".  Since the second formal "continuation" is a symbol,
>    > it is not specialized, and may be of any type (recall that CL uses
>    > multiple dispatch).
>
>    I've never programmed CL.  I have read a couple of books about it.
>    I've never tried to understand CLOS.
>
>    I was badly misreading the code.  I thought that def was a function or
>    macro of some sort, and therefore (def has-parts-mixin) was being
>    expanded into something that was interpolated into the function
>    signature.
>
> That's an unfortunate terminology clash; "def" is short for "definition"
> in the application domain, and has nothing to do with Lisp per se.
> FWIW, macros are never expanded in lambda lists (unless, of course, they
> are in expressions that initialize defaulted optional variables).

That's the difference between playing with a language and really using
it.  As I've said, I've never been a Lisp programmer.  (I only started
programming as the easiest job to find with a math background.)
Therefore while I know the basics of Lisp, there is a lot I miss.

>    Now that I have that straight, I think that the first
>    method is similar (modulo the complexities of CLOS) to:
>
>        sub map_parts {
>            my ($def, $continuation) = @_;
>            for my $part ($def->def_parts()) {
>                $continuation->($part);
>            }
>        }
>
> Correct.  (And the complexities of CLOS don't apply here, because only
> the first arguments are specialized, so they behave like ordinary
> single-dispatch methods in Perl 5.)

Good to know.

>    And the other to:
>
>        sub map_extent_parts {
>            my ($has_parts_mixin, $x1, $y1, $x2, $y2, $continuation) = @_;
>            for my $part ($def->def_parts()) {
>                if ($part->bbox_overlaps_extent($x1, $y1, $x2, $y2)) {
>                    $continuation->($part);
>                }
>            }
>        }
>
> Correct, except that you are missing the $def parameter.

Oops.

>    In that case, the name $continuation seems misleading to me.
>    Certainly it would give me the wrong expectations.  (In fact it
>    did...)
>
> I'm sorry that I was not as clear as I should have been that I was
> illustrating another use of the term.

Well you're demonstrating that you're used to using the term in a
different way.  It isn't a usage that I am planning to pick up any
time soon...

[...]
>    Still, even if I accept the fact that there is a population somewhere
>    that uses continuation in a very different sense, I think I'm being
>    reasonable to say that when most people speak about a language having
>    continuations, they do not mean something that acts similarly to
>    closures.  (Even if they are just closures under the hood.)
>
> But, as mentioned above, acting "similarly to closures" doesn't rule
> much out . . .
>
>    Still, I take your point.  I was trying to broaden the discussion to
> other uses of "continuation," but wasn't sufficiently explicit about it.
> And it didn't help that we were also simultaneously discussing the other
> "hard core" meanings of "continuation."

No, it did not.

>    > I would say "can lead to problems" or "may lead to confusing code."  So
>    > can the other powerful language features I've encountered, but I often
>    > find uses for them -- in code that (IMO) seems no more confusing than
>    > necessary.
>
>    We all claim that features are only misused by others. :-P
>
>    Still I think we're saying the same thing.  Continuations are very
>    powerful, and can lead to confusion.  (And not just confusion over
>    what the definition of a continuation is!)  We're just in disagreement
>    about whether that trade-off is a net win.
>
> Good; perhaps we should leave it at that, then, and give the other
> Mongers a rest.

OK.

>    > Complicated algorithms tend to be hard to debug no matter how they are
>    > implemented.  Even so, consider that an algorithm implemented with
>    > (exit) continuations may be easier to debug than one without if using
>    > continuations makes the implementation appreciably cleaner and/or more
>    > compact.
>
>    Hey, you don't have to convince me that exiting early is a good thing.
>     Several years ago I read
>    
> http://www.cis.temple.edu/~ingargio/cis71/software/roberts/documents/loopexit.txt
>    and was easily convinced.
>
> Interesting.  But I suspect that I have less need to do this sort of
> thing (return & break) when I can use functional abstractions instead of
> loops [1].

I am a firm believer in expressing things in the most straightforward
way possible.  Most people find loops straightforward, so I'm happy to
use loops unless I have a good reason not to.

>    >    Indeed, error handling itself makes a good case in point.  The
>    > equivalent of try/recover in many languages makes it easier to separate
>    > error handling from "normal" code, thereby simplifying the normal
>    > control flow, but requires (exit) continuation semantics to make it
>    > happen.  (I was going to say that I rarely use exit continuations in my
>    > day-to-day programming, but then I remembered error handling.)
>
>    I would agree.  Many others would not.  You can get a sampling of
>    opinions at discussions such as
>    http://c2.com/cgi/wiki?AvoidExceptionsWheneverPossible.
>
>    Cheers,
>    Ben
>
> Astonishing.  Even in the 21st century . . .

There are actually a lot of very prominent programmers who strongly
dislike exceptions.  For instance Raymond Chen at Microsoft.  And for
some kinds of programming they have a point.  If your goal is to write
a robust program (ie one that will keep on running and doing the best
it can even though things are going to pot around and inside it) then
exceptions make your life very, very hard.  But in other kinds of
programming it is perfectly fine to terminate the program with an
exception, have the programmer see the error message, and fix it
properly.

Cheers,
Ben
 
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to