Is there some model to use to understand containers, references, raw, rw, \ in Raku?
Asked Answered
T

3

11

In perl5 you could think of \ as a pointer and dereference that pointer by prefixing with the specific sigil or ->. You had also typeglobs that made the symbol explicit. In perl5 the underlying C code structures would give a good model to relate to the syntax of the language.

In Raku you have a set of concepts like: containers (and non-containers?), binding, assignment with = and :=, different traits in arguments like raw and rw and \ (which seems not related to perl5's \ ?).

Is there some underlying model that I can use to determine what I am actually using at a certain point in code and which options I have?

Tenet answered 24/7, 2020 at 9:11 Comment(2)
What do you mean by underlying model? It would probably help if you said what you intend to do. Underlying everything is the Metamodel, anyway.Jenijenica
I.e. a pictorial model like that in "perl-guts illustrated" or if the metamodel is what defines a container a reference to the description what a "container" is. I only find pieces here and there. Where is the metamodel defined or what := does compared to =? Does it specify the rw trait?Tenet
F
7

When you write this:

my $a = 'b';

$a = 'c';

say $a;

What happens is something that is sort-of like this:

my $a := Scalar.new( value => 'b' );

$a.set-value('c');

say $a.get-value();

Basically a new Scalar object is created and $a is a pointer to it.


Of course it isn't quite that simple as you can't even call .new on a Scalar and have it do anything.

There is also a lot more information stored inside of the Scalar object. For example the type information and any default.

Really what you think about $ variables is all contained inside of the Scalar object.

Normally this container tries to be completely transparent. You can however get at the Scalar object with the .VAR method/macro.

my Int $a is default(42) = 3;

my $var = $a.VAR;

say $var.name;    # $a
say $var.of;      # (Int)
say $var.default; # 42
say $var.self;    # 3

There are other ways that this transparency gets more translucent than transparent.

sub foo ( \v ){ # the \ is so it isn't seen as a Type name
  say v.VAR.name
  v = 22;
}
foo $a; # $a
say $a; # 22

That is because the Scalar gets passed to the subroutine, not the value inside of the Scalar. The Scalar is always passed to the function call, it's just that the function often decides to do something other than allowing you raw access to the original Scalar.

In the following, the value inside of the passed Scalar is copied to a new Scalar that doesn't allow modification.

sub bar ( $v ){
  # $v = 3; # ERROR
}
bar $a

If you had declared $v as is rw or is raw, $v would actually be a pointer to the Scalar container you passed in just like \v above. (\v is very similar to is raw.)

Firenze answered 25/7, 2020 at 0:23 Comment(0)
E
6

Ok, I'll try to give you a mental model:

  1. there is no real assignment in Raku, only binding (like NQP)
  2. everything in Raku is an object.
  3. objects can have attributes, that can bind to other objects.
  4. Raku adds syntactic sugar to write assignments, but really that's just binding an object to an attribute of a Container object.

So what does this mean for:

# bind a container object to the name '$a' in the lexpad
my $a;

# bind an Int object to the value attribute of that container
$a = 42;

Normally, you don't need to know if something is inside a container or not, as most decontainerization is done for you behind the scenes. For instance, if you return a variable from a subroutine, it is automatically removed from its container. Except if the subroutine is marked as is raw.

Does that help with creating a model?

Epinephrine answered 24/7, 2020 at 14:30 Comment(4)
Hi @elizabeth - is it fair to think of it as the Container that applies the type system rules?Petrapetracca
I found this one now: docs.raku.org/language/containers. Maybe it is like this: A "container" in raku is what is called a "Reference" (RV) in Perl5 with one container pointing to one entity. "binding" maybe means set the reference that the container points to.Tenet
@psteve: yes, a container knows which types it make accept.Epinephrine
@KonradEisele - I find the docs are terse, but precise. in my opinion, raku is 10 years ahead in handling this kind of housekeeping, yet without bothering the coder (unless you want that).Petrapetracca
P
3

I like the advent calendar article on this topic https://perl6advent.wordpress.com/2017/12/02/perl-6-sigils-variables-and-containers/ , not sure if that is what you are looking for, but it helped me to getter a better feel of what’s going on...

Petrapetracca answered 24/7, 2020 at 17:29 Comment(2)
I think I need to read the VM bytecode for certain constructs any its implementation in the VM to understand the concepts.Tenet
@KonradEisele I don't know how reading the VM bytecode would help that much. The VM doesn't really understand Raku. In fact it has to be taught every time you load the runtime how the Raku object model works.Firenze

© 2022 - 2024 — McMap. All rights reserved.