Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I not create nested packages within one?

Tags:

syntax

raku

This is "lib/Packr.rakumod":

unit package Packr;

our class Packd is export {}

our class D::Packd is export {}

our class B::Packd is export {}

And this is packr.rakumod:

use Packr;

for (Packr::Packd Packr::B::Packd Packr::D::Packd ) -> \P {
    say P.new().raku;
}

This errors with:

Could not find symbol '&Packd' in 'Packr::D'

It does not matter the order in which I declare it, or if I use "U" instead of "D". I will try with other combination of letters, but unless I'm missing something obvious, or mistyping something, I'm really baffled at this.

This happens also if I simply delete Packr::D::Packd. It looks like it bails out after the first error, which seems to be the last in the iteration, for some reason.

And this being my first question of the year, happy new year to everyone!

like image 250
jjmerelo Avatar asked Jan 04 '21 08:01

jjmerelo


1 Answers

TL;DR Raku's error message for an unrecognized identifier, when it's treated as a potential post-declared routine, is arguably LTA. (I would argue it is.) Other than that, I'm not sure what your question is, but will attempt to answer it anyway...


Your lib/Packr.rakumod example?

If one applies is export to multiple exports such that the symbols that would be exported are the same, the compiler should bail at compile time:

class A::foo is export {}    # would export `foo`
class B::foo is export {}    # would export `foo`

displays:

A symbol 'foo' has already been exported

So if your lib/Packr.rakumod example compiles for you, I suspect your compiler is screwed up. Perhaps you're not using an official release?[1]

Your packr.rakumod example?

If one omits commas between two terms, then unless the first one is a valid identifier that has not yet been declared (in which case the compiler presumes it might be a routine that will be declared later on in the same unit), the compiler bails at compile time:

for (1 2) {}

displays:

Two terms in a row

Your packr.rakumod example omits commas, and the terms are each valid identifiers that the compiler does not recognize as having yet been declared / imported.

So the compiler allows that perhaps they are all post-declared routines (routines declared later on in the source code):

foo;           # compiler doesn't bail because...
sub foo {}     # `foo` might be declared later

But if/when the compiler reaches the end of the unit being compiled and has failed to find a declaration of what it earlier treated as a possibly missing/post-declared routine, it realizes that it needs to fail compilation and generate an error message.

It explains this rather tersely and cryptically:

Could not find symbol '&Packd' in 'Packr::D'

A critical issue here is that it hopes the reader pays attention to the &, and understands that for some reason it's looking for that despite the source code not mentioning an &, and knows how Raku supports post-declared routines, and so on, and puts 2 and 2 together to say "Ohhh, of course".

But what if you're a newbie? Or JJ getting distracted by some other deeper question?

So, what is your question?

Perhaps you're just not using an official release, and that has ended up confusing you, and/or it was the error message combined with being distracted, and perhaps there's no question left standing that needs to be answered.

But I rather suspect there is, and it just got lost in translation into an SO.

Having gone through the example, and found it somewhat wanting, I'll now focus on the title:

Can I not create nested packages within one?

Yes:

package Foo { package Bar {} }

say Foo::Bar; # (Bar)

Is this a possibly acceptable answer?

Well, yes, in the sense I posted it as an answer, and all answers are possibly acceptable, but perhaps no, in that I'm not sure what the question is, so much so that I've ended up closing with my answer being a question. :)

So to try to ensure it really is a possibly acceptable answer, I'll close with this thought, which in a sense is the acceptable answer to everything: Happy New Year. :)

Footnotes

[1] Quoting Minimal, Reproducible Example:

...Reproducible -- Test the code you're about to provide to make sure it reproduces the problem

Murphy's Law has routinely applied when I've shared code without testing it, often because I'm very confident it's fine, or in a hurry.

The only way I've fixed the ensuing problems that routinely caused is to carefully test code I'm about to share after pasting it into any comment or answer, and before clicking submit, even if I think I haven't changed anything since I last compiled and ran it, and to do this every single time, after every single edit.

Of course, this is a chore, and some will feel it isn't worth the hassle...

like image 52
raiph Avatar answered Oct 11 '22 12:10

raiph