Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re^3: Contexts and Perl 6

by TimToady (Parson)
on May 19, 2009 at 16:07 UTC ( #764966=note: print w/replies, xml ) Need Help??

in reply to Re^2: Contexts and Perl 6
in thread Contexts and Perl 6

The parser behaves differently in scalar or list context, like with Perl 5.
Actually, no, unlike Perl 5 the Perl 6 parser has no clue about scalar vs list context, which is completely driven by run-time binding so that context can be lazy. The only place the parser appears to pay attention to this is in choosing how to parse assignment based on the form of the left side, but this is merely the application of a precedence limiter to the right side so that the operator precedence parser knows whether to stop at the next comma or not. The only semantic distinction that heavily influences parsing is whether a name is predeclared as a type or named value (in which case the parser will not look for function arguments), but this also is not related to run-time context.

Replies are listed 'Best First'.
Re^4: Contexts and Perl 6
by John M. Dlugosz (Monsignor) on May 19, 2009 at 18:21 UTC
    Very interesting, thanks.

    I see in the Synopses where context behavior is being replaced by typed objects; e.g. "undef in scalar context or () in list context" replaced by "Nil".

    So, is there anything left of the concept of context flowing inward in the manner of a contextual variable?


      The basic problem is one of time travel. Context variables work because you set them up before you ever call the function, because statement boundaries provide a sequence point.
      my $FD is context = open($file); later(1,2,3,sooner());
      So both sooner and later see the value of $*FD in the dynamic context. However, the type context of sooner is not known when it is called, because it it provided by the binding in the later call. (MMD only makes this worse, not just because you have multiple possible type contexts, but because the use of the actual return type for MMD introduces a chicken and egg problem.)

      It would be possible to define a form of laziness that would at least let sooner() see the possibilities, and perhaps even negotiate a unification between the two lists of possibilities (the return possibilities and the binding possibilities). One could imagine that the want function actually takes a continuation, and returns that to be bound lazily, and then continues executing once it knows how it will be bound. That could work directly for dispatch to an "only" version of later (assuming you don't depend on side effects in sooner happening before the call to later). For multiple dispatch we would presumably have to return (along with the continuation) some kind of list of possible return types for MMD to work with, or perhaps just the most general type, if we decide all coercion is to be managed by MMD rather than by want. Or we could take the approach you suggested and do the unification in sooner's switch statement, but then the call to sooner would be driven by the dispatcher, not by the actual binding.

      But this is all conjectural, since at least for 6.0.0 we're aiming to create something implementable on platforms that have difficulty with time travel. There's nothing in the current design that exactly requires continuation support; even resumable exceptions are designed to work on systems without first class support for continuations (that is, we don't unwind the stack till after exception handlers are run, so resuming from an exception is just a return). Lazy lists can be emulated with closures and iterators.

      So for now, we put our thumb on the scales in favor of multiple dispatch using a set of already-computed values of known type, and leave the door open for time travel in the future. We don't exactly know how to install a time-travel booth, but we're saving a spot for someone clever from the future to come back and install one for us, sooner or later. :-)

        So, that would be a "no"? The concept of context flowing inward is deprecated.

        Instead, constructs always do the same thing, which is to return an object that can exhibit different behavior in different contexts later. A simple example, which can be taken as an exemplar, is Nil which replaces "undef in item context or () in list context.".

        Is that the plan?


Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://764966]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2022-07-05 00:37 GMT
Find Nodes?
    Voting Booth?

    No recent polls found