Strange message declaring a Pointer[void] in a NativeCall perl6 module - raku

These snippets of code may seem odd, it's because I started with my original code and cut off pieces until I arrived to the minimal set of instructions that reproduced the error. So bear with the apparent uselessness.
There are two perl6 modules, one uses the other one, and a program.
This is the first module:
unit class test1;
use NativeCall;
use test2;
method test
{
my Pointer[void] $dummy .= new;
}
The second module is included by the first one, but no part of it is actually used:
unit module test2;
use NativeCall;
class A is repr('CStruct') is export {
has Pointer[void] $.wrongdoer;
has int32 $.a;
}
The program creates a test1 object and calls the test method:
use lib '.';
use test1;
my test1 $t .= new;
$t.test;
This program outputs an error, apparently caused by the assignment in the class test1's method test:
Type check failed in assignment to $dummy; expected NativeCall::Types::Pointer[NativeCall::Types::void] but got NativeCall::Types::Pointer[NativeCall::Types::void].new(0)
If I comment out the $.wrongdoer in the second class, the program executes with no error.
I'm running rakudo 2018.06.
Is this a bug in the NativeCall module or something else I fail to see?

As suggested by Brad Gilbert, removing the [void] stops the spooky action at a distance.

Related

Kotlin script: main function does not get called locally, unlike in online judge

I am trying to participate in online Codeforces contests using Kotlin.
My understanding is I should use Kotlin script if my code is contained within a single file.
If I run the following file locally (version 1.6.10):
kotlin just_main.main.kts
// just_main.main.kts
fun main() {
println("Hello World")
}
Nothing happens. I need to add an explicit call for it to actually execute main:
// top_level_call.main.kts
fun main() {
println("Hello World")
}
main()
So far, so normal. The problem occurs when I try to submit my solution to the Codeforces online judge. The judge expects no top-level code and runs the main function instead. So just_main runs fine, but top_level_call produces a compilation error:
Can't compile file:
program.kt:43:1: error: expecting a top level declaration
main()
^
This leads to the awkward situation of me having to add the main() call when I want to try my solution locally, but having to remove it every time I upload an attempt.
Is there a way to have my local Kotlin behave the same as the online judge, meaning implicitly running any main functions (meaning just_main would produce output)?
I haven't found a way to do this with Kotlin script files, but you can also use normal .kt files without having any classes in the file (my understanding is that Kotlin magically turns them into Java class bytecode/files):
kotlinc a.kt && kotlin AKt < a.in
This "runs" a.kt with standard input from a.in.
(And yes I only found this after I already wrote the question)

Alter how arguments are processed before they're passed to sub MAIN

Given the documentation and the comments on an earlier question, by request I've made a minimal reproducible example that demonstrates a difference between these two statements:
my %*SUB-MAIN-OPTS = :named-anywhere;
PROCESS::<%SUB-MAIN-OPTS><named-anywhere> = True;
Given a script file with only this:
#!/usr/bin/env raku
use MyApp::Tools::CLI;
and a module file in MyApp/Tools called CLI.pm6:
#PROCESS::<%SUB-MAIN-OPTS><named-anywhere> = True;
my %*SUB-MAIN-OPTS = :named-anywhere;
proto MAIN(|) is export {*}
multi MAIN( 'add', :h( :$hostnames ) ) {
for #$hostnames -> $host {
say $host;
}
}
multi MAIN( 'remove', *#hostnames ) {
for #hostnames -> $host {
say $host;
}
}
The following invocation from the command line will not result in a recognized subroutine, but show the usage:
mre.raku add -h=localhost -h=test1
Switching my %*SUB-MAIN-OPTS = :named-anywhere; for PROCESS::<%SUB-MAIN-OPTS><named-anywhere> = True; will print two lines with the two hostnames provided, as expected.
If however, this is done in a single file as below, both work identical:
#!/usr/bin/env raku
#PROCESS::<%SUB-MAIN-OPTS><named-anywhere> = True;
my %*SUB-MAIN-OPTS = :named-anywhere;
proto MAIN(|) is export {*}
multi MAIN( 'add', :h( :$hostnames )) {
for #$hostnames -> $host {
say $host;
}
}
multi MAIN( 'remove', *#hostnames ) {
for #hostnames -> $host {
say $host;
}
}
I find this hard to understand.
When reproducing this, be alert of how each command must be called.
mre.raku remove localhost test1
mre.raku add -h=localhost -h=test1
So a named array-reference is not recognized when this is used in a separate file with my %*SUB-MAIN-OPTS = :named-anywhere;. While PROCESS::<%SUB-MAIN-OPTS><named-anywhere> = True; always works. And for a slurpy array, both work identical in both cases.
The problem is that it isn't the same variable in both the script and in the module.
Sure they have the same name, but that doesn't mean much.
my \A = anon class Foo {}
my \B = anon class Foo {}
A ~~ B; # False
B ~~ A; # False
A === B; # False
Those two classes have the same name, but are separate entities.
If you look at the code for other built-in dynamic variables, you see something like:
Rakudo::Internals.REGISTER-DYNAMIC: '$*EXECUTABLE-NAME', {
PROCESS::<$EXECUTABLE-NAME> := $*EXECUTABLE.basename;
}
This makes sure that the variable is installed into the right place so that it works for every compilation unit.
If you look for %*SUB-MAIN-OPTS, the only thing you find is this line:
my %sub-main-opts := %*SUB-MAIN-OPTS // {};
That looks for the variable in the main compilation unit. If it isn't found it creates and uses an empty Hash.
So when you try do it in a scope other than the main compilation unit, it isn't in a place where it could be found by that line.
To test if adding that fixes the issue, you can add this to the top of the main compilation unit. (The script that loads the module.)
BEGIN Rakudo::Internals.REGISTER-DYNAMIC: '%*SUB-MAIN-OPTS', {
PROCESS::<%SUB-MAIN-OPTS> := {}
}
Then in the module, write this:
%*SUB-MAIN-OPTS = :named-anywhere;
Or better yet this:
%*SUB-MAIN-OPTS<named-anywhere> = True;
After trying this, it seems to work just fine.
The thing is, that something like that used to be there.
It was removed on the thought that it slows down every Raku program.
Though I think that any slowdown it caused would still be an issue as the line that is still there has to look to see if there is a dynamic variable of that name.
(There are more reasons given, and I frankly disagree with all of them.)
May a cuppa bring enlightenment to future SO readers pondering the meaning of things.[1]
Related answers by Liz
I think Liz's answer to an SO asking a similar question may be a good read for a basic explanation of why a my (which is like a lesser our) in the mainline of a module doesn't work, or at least confirmation that core devs know about it.
Her later answer to another SO explains how one can use my by putting it inside a RUN-MAIN.
Why does a slurpy array work by default but not named anywhere?
One rich resource on why things are the way they are is the section Declaring a MAIN subroutine of S06 (Synopsis on Subroutines)[2].
A key excerpt:
As usual, switches are assumed to be first, and everything after the first non-switch, or any switches after a --, are treated as positionals or go into the slurpy array (even if they look like switches).
So it looks like this is where the default behavior, in which nameds can't go anywhere, comes from; it seems that #Larry[3] was claiming that the "usual" shell convention was as described, and implicitly arguing that this should dictate that the default behavior was as it is.
Since Raku was officially released RFC: Allow subcommands in MAIN put us on the path to todays' :named-anywhere option. The RFC presented a very powerful 1-2 punch -- an unimpeachable two line hackers' prose/data argument that quickly led to rough consensus, with a working code PR with this commit message:
Allow --named-switches anywhere in command line.
Raku was GNU-like in that it has '--double-dashes' and that it stops interpreting named parameters when it encounters '--', but unlike GNU-like parsing, it also stopped interpreting named parameters when encountering any positional argument. This patch makes it a bit more GNU-like by allowing named arguments after a positional, to prepare for allowing subcommands.
> Alter how arguments are processed before they're passed to sub MAIN
In the above linked section of S06 #Larry also wrote:
Ordinarily a top-level Raku "script" just evaluates its anonymous mainline code and exits. During the mainline code, the program's arguments are available in raw form from the #*ARGS array.
The point here being that you can preprocess #*ARGS before they're passed to MAIN.
Continuing:
At the end of the mainline code, however, a MAIN subroutine will be called with whatever command-line arguments remain in #*ARGS.
Note that, as explained by Liz, Raku now has a RUN-MAIN routine that's called prior to calling MAIN.
Then comes the standard argument processing (alterable by using standard options, of which there's currently only the :named-anywhere one, or userland modules such as SuperMAIN which add in various other features).
And finally #Larry notes that:
Other [command line parsing] policies may easily be introduced by calling MAIN explicitly. For instance, you can parse your arguments with a grammar and pass the resulting Match object as a Capture to MAIN.
A doc fix?
Yesterday you wrote a comment suggesting a doc fix.
I now see that we (collectively) know about the coding issue. So why is the doc as it is? I think the combination of your SO and the prior ones provide enough anecdata to support at least considering filing a doc issue to the contrary. Then again Liz hints in one of the SO's that a fix might be coming, at least for ours. And SO is itself arguably doc. So maybe it's better to wait? I'll punt and let you decide. At least you now have several SOs to quote if you decide to file a doc issue.
Footnotes
[1] I want to be clear that if anyone perceives any fault associated with posting this SO then they're right, and the fault is entirely mine. I mentioned to #acw that I'd already done a search so they could quite reasonably have concluded there was no point in them doing one as well. So, mea culpa, bad coffee inspired puns included. (Bad puns, not bad coffee.)
[2] Imo these old historical speculative design docs are worth reading and rereading as you get to know Raku, despite them being obsolete in parts.
[3] #Larry emerged in Raku culture as a fun and convenient shorthand for Larry Wall et al, the Raku language team led by Larry.

Why does direct binding of an `our &foo` not work, but indirecting via a dynamic lookup does?

Why is there a difference between r1 and r2 when called outside of module TEST?
module TEST {
our &r1 := OUR::{'&r1'} := sub {
say 'routine 1'
}
r1(); # routine 1
our &r2 := sub {
say 'routine 2'
}
r2(); # routine 2
}
import TEST;
say TEST::.keys; # (&r1 &r2)
TEST::r1(); # routine 1
TEST::r2(); # Cannot invoke this object (REPR: Uninstantiable; Callable) ...
There is an error when trying to run subroutine r2 outside of module TEST where it was defined.
TL;DR Binding to an our is pointless. Binding to an OUR::<&foo> is effective. I like naming things... It seems you've invented a technique which I hereby dub "#jakar's double bind our".
Why the direct binding only works inside the module
In a comment on his answer to an earlier SO jnthn concludes that we could perhaps have an error message, or perhaps a warning, to the effect that:
binding to an our variable is pointless use of our.
(What he means is that the binding only works inside the module, not outside, as you have discovered.)
There's an old and still open issue Binding a variable at BEGIN time doesn't stick around for runtime that discusses the general problem in depth.
Why the dynamic lookup works outside the module
From Symbols that start with core namespaces always get exported, jnthn notes that:
stashes are always open to poke symbols in to.
So, ignoring use of symbols inside your module, your code is doing this:
module TEST {
OUR::{'&r1'} := sub { say 'routine 1' }
our &r2;
}
import TEST;
TEST::r1(); # routine 1
TEST::r2(); # Cannot invoke this object (REPR: Uninstantiable; Callable) ...
#jakar's double bind our
If one wants to be able to declare a symbol and use it both inside and outside the module and insists on using binding then your trick of declaring it with a double bind may be the best technique available:
our &r1 := OUR::{'&r1'} := sub { ... }
^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *outside* module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *inside* module
Some things I'm curious about:
Have you been able to confirm any significant specific and practical advantage(s) that can be accrued from binding instead of assigning an our?
Do folk want to get around the "binding to an our variable is pointless" issue? If so, would they be happy to use #jakar's double bind our?
Does your technique apply to all sigils? (I would expect so but will leave it to you to explore such aspects. :))

Using modules to load a group of related functions

I want to use Raku Modules to group some functions, I often use. Because these functions are all loosely coupled, I don't like to add them in a class.
I like the idea of use, where you can select, which functions should be imported, but I don't like it, that the functions, which are imported are then stored in the global namespace.
For example if I have a file my_util.pm6:
#content of my_util.pm6
unit module my_util;
our sub greet($who) is export(:greet) {
say $who;
}
sub greet2($who) is export(:greet2) {
say $who;
}
sub greet3($who) is export(:greet3) {
say $who;
}
and a file test.p6:
#!/usr/bin/perl6
#content of test.p6
use v6.c;
use lib '.';
use my_util :greet2;
greet("Bob"); #should not work (because no namespace given) and also doesn't work
greet2("Bob"); #should not work (because no namespace given) but actually works
greet3("Bob"); #should not work (because no namespace given) and also doesn't work
my_util::greet("Alice"); #works, but should not work (because it is not imported)
my_util::greet2("Alice"); #should work, but doesn't work
my_util::greet3("Alice"); #should not work (because it is not imported) and also doesn't work
I would like to call all functions via my_util::greet() and not via greet() only.
The function greet() defined in my_util.pm6 comes very close to my requirements, but because it is defined as our, it is always imported. What I like is the possibility, to select which functions should be imported and it should be possible to leave it in the namespace defined by the module (i.e. it doesn't pollute the global namespace)
Does anyone know, how I can achieve this?
To clear up some potential confusion...
Lexical scopes and package symbol tables are different things.
my adds a symbol to the current lexical scope.
our adds a symbol to the current lexical scope, and to the public symbol table of the current package.
use copies the requested symbols into the current lexical scope.
That's called "importing".
The :: separator does a package lookup – i.e. foo::greet looks up the symbol greet in the public symbol table of package foo.
This doesn't involve any "importing".
As for what you want to achieve...
The public symbol table of a package is the same no matter where it is referenced from... There is no mechanism for making individual symbols in it visible from different scopes.
You could make the colons part of the actual names of the subroutines...
sub foo::greet($who) is export(:greet) { say "Hello, $who!" }
# This subroutine is now literally called "foo::greet".
...but then you can't call it in the normal way anymore (because the parser would interpret that as rule 4 above), so you would have to use the clunky "indirect lexical lookup" syntax, which is obviously not what you want:
foo::greet "Sam"; # Could not find symbol '&greet'
::<&foo::greet>( "Sam" ); # Hello, Sam!
So, your best bet would be to either...
Declare the subroutines with our, and live with the fact that all of them can be accessed from all scopes that use the module.
Or:
Add the common prefix directly to the subroutine names, but using an unproblematic separator (such as the dash), and then import them normally:
unit module foo;
sub foo-greet($who) is export(:greet) { ... }
sub foo-greet2($who) is export(:greet2) { ... }
sub foo-greet3($who) is export(:greet3) { ... }

SystemC constructor, class

I am new in systemc. There is one confusion that I am having.
I am creating a sc_module(hello_world). The sc_ctor(hello_world) has nothing between the curly braces and I just have a simple void say_hello() function inside the module which prints "hello world."
In the sc_main, I did this:
hello_world hello;
hello.say_hello();
However, I am getting an error that error C2228: left of '.say_hello' must have class/struct/union.
I tried this and it worked:
in sc_main, I did this:
hello_world hello("hi ");
hello.say_hello();
Why it is showing error in the first place? I didn't use one argument constructor.
So, instead of hello_world hello("hi ") shouldn't it be hello_world hello ? I was just trying to compare with C++ class.
Every SystemC module, whether defined with macro SC_MODULE or inherits sc_module, needs to have a module name. Constructors of SystemC modules must have one parameter of class sc_module_name.
In SystemC standard (IEEE Std 1666-2011)
Every class derived (directly or indirectly) from class sc_module shall have at least one constructor. Every such constructor shall have one and only one parameter of class sc_module_name but may have further parameters of classes other than sc_module_name. That parameter is not required to be the first parameter of the constructor.
If you are using macro SC_CTOR, it is actually a constructor with one sc_module_name parameter!
in sc_module.h:
#define SC_CTOR(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE; \
user_module_name( ::sc_core::sc_module_name )
I can´t see nothing wrong.
In fact, it seems to me, that you have the same code like this example -> http://www.asic-world.com/systemc/first1.html
I hope you could check your with this one.
The macro SC_CTOR has created a hello(const sc_module_name name&) constructor for you. Therefor the compiler will not generate a default constructor for you to call and the object hello cannot be created.
Inbuilt constructor after macro expansion must have an argument.
It is possible that you defined your constructor as private. As a result compiler cannot name it from main.cpp.