Do declarator blocks work on roles when they are unit-declared? - documentation

They apparently don't, if there's a "use" clause before, like here:
use Foo;
#| Why for Baz
unit role Baz does foo;
method quux { "quux"}
Then
use Baz;
say Baz.WHY;
yields:
No documentation available for type 'Baz'.
Is this a bug, or am I doing something wrong here?
Update: reported as a bug here

Related

A better way to introspect a capture

I want to test the type of the first object in a signature. The following shows some ways I have found that work. But why does a smart match on a Type (2nd of the 3 tests below) not work?
Is there a better way than stringifying and testing for the string equivalent of the Type?
(Below is the use case I am working on)
raku -e "sub a( |c ) { say so |c[0].WHAT.raku ~~ /'Rat'/, so |c[0].WHAT ~~ Rat, so |c[0].^name ~~ /'Rat'/ };a(3/2);a(2)"
TrueFalseTrue
FalseFalseFalse
# OUTPUT:
#TrueFalseTrue
#FalseFalseFalse
I am writing a proto sub handle, and most of the subs have similar signatures, eg. multi sub handle( Pod $node, MyObj $p, Int $level --> Str)
So most of the multi subs do different things depending on what is in $node. However, how to handle cases when the handle is called with Nil or a plain string. I am thinking about something like
proto handle(|c) {
if |c[0].^name ~~ /'Str'/ { # code for string }
else { {*} }
}
A better way to introspect ...
In general, a better way to do anything in any programming language is to not introspect if you can avoid it.
In general, in Raku, you can avoid manual introspection. See the section Introspection toward the end of this answer for further discussion.
... a capture
The best tool for getting the functionality that introspection of a capture provides is to use a signature. That's their main purpose in life.
I want to test the type of the first object in a signature
Use signatures:
proto handle(|) {*}
multi handle( Pod $node ) { ... }
multi handle( Str $string ) { ... }
multi handle( Nil ) { ... }
The following shows some ways I have found that work.
While they do what you want, they are essentially ignoring all of Raku's signature features. They reduce the signature to just a binding to the capture as a single structure; and then use manual introspection of that capture in the routine's body.
There's almost always a simpler and better way to do such things using signatures.
why does [|c[0].WHAT ~~ Rat, with c[0] == 3/2] not work?
I'll simplify first, then end up with what your code is doing:
say 3/2 ~~ Rat; # True
say (3/2) ~~ Rat; # True
say (3/2).WHAT ~~ Rat; # True
say |((3/2).WHAT ~~ Rat); # True
say (|(3/2).WHAT) ~~ Rat; # False
say |(3/2).WHAT ~~ Rat; # False
The last case is because | has a higher precedence than ~~.
Is there a better way than stringifying and testing for the string equivalent of the Type?
OMG yes.
Use the types, Luke.
(And in your use case, do so using signatures.)
Introspection
Compared to code that manually introspects incoming data in the body of a routine, appropriate use of signatures will typically:
Read better;
Generate better low-level code;
Be partially or fully evaluated during the compile phase.
If a language and its compiler have addressed a use case by providing a particular feature, such as signatures, then using that feature instead of introspection will generally lead to the above three benefits.
Languages/compilers can be broken into four categories, namely those that:
Do not do or allow any introspection;
Allow the compiler to introspect, but not devs;
Allow both the compiler and devs to introspect, but aim to make it a last resort, at least for devs;
Enable and encourage devs to introspect.
Raku(do) are in the third category. In the context of this SO, signatures are the primary feature that all but eliminates any need for a dev to manually introspect.
You can simply smartmatch to a type:
raku -e "sub a( *#c ) { say #c[0] ~~ Rat };a(3/2);a(2)"
True
False
Also I am using here a slurpy and not a capture, which is another alternative. Any way, with a single argument you're probably better off using type captures
raku -e "sub a( ::T $ ) { say ::T ~~ Rat };a(3/2);a(2)"
True
False
You can pull stuff out of a Capture in the signature.
# ( |C ( ::Type $a, +#b ) )
proto handle( | ( ::Type, +# ) ) {
if Type ~~ Str {
…
} else {
{*}
}
}
Basically a ::Foo before a parameter (or instead of it) is similar to .WHAT on that parameter.
It also becomes usable as a type descriptor.
sub foo ( ::Type $a ) {
my Type $b = $a;
}
It is an incredibly bad idea to compare types based on their name.
my $a = anon class Foo { has $.a }
my $b = anon class Foo { has $.b }
say $a.WHAT =:= $b.WHAT; # False
say $a.^name eq $b.^name; # True
As far as Raku is concerned it is entirely a coincidence that two types happen to have the same name.
If you do use the names, your code will be confused about the reality of the situation.

How to deal with nullable variables that are not null?

Consider this piece of code:
var foo: Foo? = null
if (foo != null) {
foo!!.bar()
}
If I omit the two !! I get this error:
Smart cast to 'Foo' is impossible, because 'foo' is a mutable property that could have been changed by this time
This is about concurrency, right? Well, there is no concurrent code that might change the value of foo.
Of course, it works with the two !!. However, I was wondering if this is the most idiomatice way or if there is a better way, without the two !!.
I know I could just foo?.bar() in this particular case. But the question is about whether I can treat foo as Foo instead of Foo? somehow after I've checked that it's not null.
Well, this piece of code works if foo is a local variable. I guess, your code looks a little bit different and foo is a field of a class. The solution is simple: use let:
foo?.let {
it.bar()
}
let "captures" the values of a variable so that any modifications to the original one have no effect in the passed lambda. And safe call is used here to invoke let only for non-null values.

Coercion/type checking: manually reproduce Perl6 standards

I have a Module AttrX::Mooish which implements some of attribute features of Moo/Moose frameworks (lazyness, trigger, etc.). I also wanted the module to be as transparent to the end user as possible meaning support for both private and public attributes. It works by replacing attribute's container with a Proxy and storing its value in external storage. It also means that all the type checking and coercion Perl6 was doing is now my responsibility. My target is to mimic the default behavior is much as possible. I.e. for the end user:
has MyClass #foo is mooish(...);
must work the same as it would without the trait applied. Unfortunately, the subject of type manipulations is so much complicated and ununified in the language core that the more problems I fix the more problems I get afterwards. For example:
my Str #a = <a b c>; my Str #b = [1,2,3]
Type check failed in assignment to #b; expected Str but got Int (1)
As expected.
my Str #a; say #a.WHAT
(Array[Str])
Sure.
my Array[Str] $a = ["a", "b", "c"];
Type check failed in assignment to $a; expected Array[Str] but got Array ($["a", "b", "c"])
Well....
my Array[Str] $a = <a b c>;
Type check failed in assignment to $a; expected Array[Str] but got List ($("a", "b", "c"))
Not even coercing List to Array!
No wonder that the final typecheck line in my trait code:
$coerced-value ~~ $attr.type
Fails here and there despite same values/types used in variable/attribute assignments work OK.
I have a question with no hope of getting any positive answer to it: is there a single entry point used by the assignment operator which does all the coerce/typecheck? Ideally I would simply:
$value = coerce($value, $type);
check-type($value, :type($attr.type), :name($attr.name))
I tried to trace down from the grammar, but haven't got enough spare time to complete this yet. Besides, it is mostly nqp which I don't know and can't really understand.
But since the existence of such entry point(s) is unlikely I would like to ask for any advises related to this area. Like, for example, SmokeMachine on #perl6 provided me with a great idea of obtaining base type of a parametrized type using .^parents method.
So far, the biggest problems are with:
To check if type is parametrized I can't use a single role or class to match against. So far the only approach I have is by finding if there is of method and testing its output. Unfortunately, if a class provides FALLBACK very unclear error message (the one about AUTOGEN) is produced. :no_fallback is desirable, but definite and subset types have their own find_method which doesn't support named parameters and I end up with another error message.
If a prepare type-related attributes ($!coerce-type) in compose method of my trait role applied to the Attribute object (where actually the attributes are declared) I find them later at run-time unitialized. Guessing its something related to compose time. But wanna be sure if nothing is missed here.
Is there any better way to perform type-check than $value ~~ $type?
[Comments indicate that this out-of-date question was supposed to be closed in 2020 but it never was. Here's a very brief answer in case someone comes across this.]
Sometime after asking this question, the asker significantly revised Raku's coercion mechanism. See Report on New Coercions. This new syntax for coercion is in the docs.
Using this new style, the following line from the question:
my Array[Str] $a = ["a", "b", "c"];
say $a;
# OUTPUT: Type check failed in assignment to $a;
# expected Array[Str] but got Array ($["a", "b", "c"])
becomes
my Array[Str]() $a = ["a", "b", "c"];
say $a;
# OUTPUT: [a b c]
(That is, Array[Str]() means "something that can be coerced into an Array of Strings". That's different from Array[Str()] ("an Array of things that can be coerced to Strings") and from Array[Str()]() ("something that can be coerced into an Array of things that can be coerced into Strings").)
Similarly, the following part of the question now has an answer:
is there a single entry point used by the assignment operator which does all the coerce/typecheck? Ideally I would simply [define how a type is coerced into my type]
With the new coercion protocol, the "single entry point" is the COERCE method, which users can define for their types to teach Raku how to coerce into those types.

What scope does ":my $foo" have and what is it used for?

With a regex, token or rule, its possible to define a variable like so;
token directive {
:my $foo = "in command";
<command> <subject> <value>?
}
There is nothing about it in the language documentation here, and very little in S05 - Regexes and Rules, to quote;
Any grammar regex is really just a kind of method, and you may declare variables in such a routine using a colon followed by any scope declarator parsed by the Perl 6 grammar, including my, our, state, and constant. (As quasi declarators, temp and let are also recognized.) A single statement (up through a terminating semicolon or line-final closing brace) is parsed as normal Perl 6 code:
token prove-nondeterministic-parsing {
:my $threshold = rand;
'maybe' \s+ <it($threshold)>
}
I get that regexen within grammars are very similar to methods in classes; I get that you can start a block anywhere within a rule and if parsing successfully gets to that point, the block will be executed - but I don't understand what on earth this thing is for.
Can someone clearly define what it's scope is; explain what need it fulfills and give the typical use case?
What scope does :my $foo; have?
:my $foo ...; has the lexical scope of the rule/token/regex in which it appears.
(And :my $*foo ...; -- note the extra * signifying a dynamic variable -- has both the lexical and dynamic scope of the rule/token/regex in which it appears.)
What this is used for
Here's what happens without this construct:
regex scope-too-small { # Opening `{` opens a regex lexical scope.
{ my $foo = / bar / } # Block with its own inner lexical scope.
$foo # ERROR: Variable '$foo' is not declared
}
grammar scope-too-large { # Opening `{` opens lexical scope for gramamr.
my $foo = / bar / ;
regex r1 { ... } # `$foo` is recognized inside `r1`...
...
regex r999 { ... } # ...but also inside r999
}
So the : ... ; syntax is used to get exactly the desired scope -- neither too broad nor too narrow.
Typical use cases
This feature is typically used in large or complex grammars to avoid lax scoping (which breeds bugs).
For a suitable example of precise lexical only scoping see the declaration and use of #extra_tweaks in token babble as defined in a current snapshot of Rakudo's Grammar.nqp source code.
P6 supports action objects. These are classes with methods corresponding one-to-one with the rules in a grammar. Whenever a rule matches, it calls its corresponding action method. Dynamic variables provide precisely the right scoping for declaring variables that are scoped to the block (method, rule, etc.) they're declared in both lexically and dynamically -- which latter means they're available in the corresponding action method too. For an example of this, see the declaration of #*nibbles in Rakudo's Grammar module and its use in Rakudo's Actions module.

Seeking very simple ANTLR error handling example when generating C code

I want to generate C code. I will not be reading from an input file, one line at a time (as, for instance, a compiler might). Rather, I will be parsing user input as it arrives, one line at a time.
I would prefer to detect and handle bad input in the lexer/parser, e.g
/* lexer tokens */
foo : "FOO";
bar : "BAR";
baz : "BAZ";
/* grammar*/
grammar : foo "=" BAZ
| foo "=" BAR
| <some non-existent Antrl-else> : {printf(stderr, "bad input\n");}
;
OK, if I can't catch it in the lexer/parser, it seems like I need to use displayRecognitionError() but how??
Can anyone point me at a very simple example which generates C code and shows some error handling of invalid input?
Thanks!
Ok, bounty, yippee!
But only for a real, working answer, with real, working code. No "use method X()" without an wxample.
What you are most likely looking for is the displayRecognitionError() function. This function is called in the cases that you are interested in, and is part of the C runtime.
If you want to see an example of how to use this function, look at this mailing list post. Although this code mixes C and C++, you should be able to work out what you need from it.
Handling a recognition exception in Java would go like this:
grammar X;
// ...
#rulecatch{
catch(RecognitionException rex) {
// do something
}
}
// parser rules
// lexer rules
In other words, simply add some custom C code inside the #rulecatch{ ... } block.