Strangely Consistent

Musings about programming, Perl 6, and programming Perl 6

Where in the world is the package lexpad?

(This post isn't very punny. For those of you who need puns to survive, try to figure out why jnthn++ named the IRC logs "the hottest footwear" recently. The answer, as with all good puns, is highly unsatisfying.)

My quest for a Perl 6 implementation takes me ever deeper into the esoterics of lexpads, runtimes, and a far-more-than-everything-you-needed-to-know mindset. Today some random firings in my brain turned into the following conversation on #perl6.

During the conversation, I proposed two theories, both of which turned out to be wrong. (pmichaud++ shone the necessary light both times.) Being wrong felt less important than getting my mental model fixed.

I first thought of presenting the results of the below conversation as a simple tutorial ("How our declarations work. The complete guide."), but now I think that the conversation, minimally edited, manages to be such a tutorial on its own.

Besides, blogging things in their raw and undigested form is a sign of the times. Enjoy!

<masak> I have a question. is there a need for a special "package lexpad" containing 'our'-declared variables, or can the package lexpad simply be equated to the topmost lexpad in the package?

<masak> my suspicion is the latter, but I might be missing something.

<pmichaud> the package lexpad can't be the same as the top most lexical

<pmichaud> module XYZ { my sub abc() { ... } };   # abc should not appear in the package 

<masak> oh!

<masak> right.

<masak> so, separate one, then.

<jnthn> Additionally, lexpads are meant to be static by the time we hit runtime, and you're allowed to shove stuff into the package dynamically. Not quite sure how those two hold together.

<pmichaud> well,  module XYZ { ... }   creates a lexical XYZ entry that holds the package entries

<jnthn> Aha!

<pmichaud> and it's just a hash, really.

<masak> does inserting the package lexpad below the outside lexpad (and above the topmost lexpad) make sense? that way, Yapsi wouldn't need any special opcodes for doing 'our'-variable lookups.

<pmichaud> the package lexpad is an entry in the outside lexpad, yes.

<pmichaud> I'm not sure it encapsulates the nested lexpad, though.

<masak> hm.

<masak> if it doesn't, I don't really see how it's visible from inside the package.

<masak> I've more or less convinced myself that sandwiching it between outer and topmost is what I want to do for Yapsi.

<pmichaud> our &xyz  can make an entry in both the package and in the lexical.

<pmichaud> this is what rakudo does now.

<pmichaud> we have to do similar things for methods already, too.

<masak> sure. it makes entries in both.

<pmichaud> by having entries in both, that's how it's visible inside the package

<masak> hm, indeed.

<masak> no need to have the package lexpad visible from inside.

<pmichaud> anyway, sandwiching might work too.  haven't quite gotten to that point in Rakudo thinking yet.  And it can get a bit tricky with multis.

<masak> no need to sandwich it in, either. it can sit in limbo outside the tree of scopes.

<pmichaud> oh, I know why it perhaps shouldn't (or should) be visible:

<pmichaud> my $x = 'lexical';   module XYZ { say $x;  { our $x = 'package'; } } 

<masak> ...yes?

<pmichaud> I'm pretty sure "say $x" needs to grab the 'lexical' $x, not the one that might be "sandwiched" in a package.

<masak> of course.

<masak> that falls out from ordinary scope nesting and shadowing.

<masak> innermost block binds its lexical to the container in the package lexpad.

<masak> so, that speaks out against sandwiching.

<masak> pmichaud++

So there you go. There's a separate package scope, and it isn't sandwiched.

(Answer: The missing link is the "IR clogs" meme from #parrot. I can hear you groaning... I did warn you.)