是否有一些模型可用于理解 Raku 中的容器、引用、raw、rw、\?

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

提问人:Konrad Eisele 提问时间:7/24/2020 最后编辑:jjmereloKonrad Eisele 更新时间:7/25/2020 访问量:150

问:

在 perl5 中,您可以将其视为指针,并通过在前缀中加上特定的 sigil 或 来取消引用该指针。您还具有使符号显式的类型球。在 perl5 中,底层的 C 代码结构将提供一个很好的模型来与语言的语法相关联。\->

在 Raku 中,你有一组概念,例如:容器(和非容器?)、绑定、与 and 的赋值、参数中的不同特征,如 and(这似乎与 perl5 的 ?)。=:=rawrw\\

是否有一些基础模型可用于确定我在代码中的某个点实际使用的内容以及我有哪些选项?

绑定 引用 raku assignment-operator

评论

0赞 jjmerelo 7/24/2020
基础模型是什么意思?如果你说出你打算做什么,可能会有所帮助。无论如何,一切的基础都是元模型。
0赞 Konrad Eisele 7/24/2020
即,像“perl-guts lustustrated”中那样的图形模型,或者如果元模型是定义容器的东西,则引用描述“容器”是什么。我只在这里和那里找到碎片。元模型在哪里定义,或者 := 与 = 相比有什么作用?它是否指定了 rw 特征?

答:

6赞 Elizabeth Mattijsen 7/24/2020 #1

好的,我试着给你一个心智模型:

  1. Raku 中没有真正的赋值,只有绑定(如 NQP)
  2. Raku 中的一切都是一个对象。
  3. 对象可以具有可以绑定到其他对象的属性。
  4. Raku 添加了语法糖来编写赋值,但实际上这只是将对象绑定到 Container 对象的属性。

那么这意味着什么呢?

# 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;

通常,您不需要知道容器内是否有东西,因为大多数解箱都是在幕后为您完成的。例如,如果从子例程返回变量,则会自动将其从其容器中删除。除非子例程标记为 。is raw

这对创建模型有帮助吗?

评论

0赞 librasteve 7/25/2020
嗨,@elizabeth - 将其视为应用类型系统规则的容器是否公平?
0赞 Konrad Eisele 7/25/2020
我现在找到了这个:docs.raku.org/language/containers。也许是这样的:raku 中的“容器”是 Perl5 中所谓的“引用”(RV),一个容器指向一个实体。“绑定”可能意味着设置容器指向的引用。
1赞 Elizabeth Mattijsen 7/25/2020
@psteve:是的,容器知道它允许接受哪些类型。
0赞 librasteve 7/26/2020
@KonradEisele - 我发现文档简洁但精确。在我看来,Raku 在处理这种内务管理方面领先 10 年,但不会打扰编码员(除非你想要)。
3赞 librasteve 7/25/2020 #2

我喜欢关于这个主题的降临节日历文章 https://perl6advent.wordpress.com/2017/12/02/perl-6-sigils-variables-and-containers/ ,不确定这是否是你要找的,但它帮助我更好地了解正在发生的事情......

评论

0赞 Konrad Eisele 7/25/2020
我想我需要阅读某些构造的 VM 字节码,以便在 VM 中实现任何概念。
0赞 Brad Gilbert 7/25/2020
@KonradEisele我不知道读取 VM 字节码会有多大帮助。VM 并不真正理解 Raku。事实上,每次加载运行时时,都必须教它 Raku 对象模型是如何工作的。
7赞 Brad Gilbert 7/25/2020 #3

当你写这个的时候:

my $a = 'b';

$a = 'c';

say $a;

发生的事情是这样的:

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

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

say $a.get-value();

基本上,将创建一个新的 Scalar 对象,并且是指向它的指针。$a


当然,这并不是那么简单,因为你甚至不能调用标量并让它做任何事情。.new

Scalar 对象内部还存储了更多信息。 例如,类型信息和任何默认值。

实际上,你对变量的看法都包含在 Scalar 对象中。$

通常,此容器尝试完全透明。 但是,您可以使用方法/宏获取 Scalar 对象。.VAR

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

还有其他方法可以使这种透明度比透明更透明。

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

这是因为 Scalar 被传递给子例程,而不是 Scalar 内部的值。 Scalar 总是传递给函数调用,只是函数经常决定做一些事情,而不是允许您原始访问原始 Scalar。

在下文中,传递的 Scalar 内部的值将复制到不允许修改的新 Scalar 中。

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

如果声明为 或,则实际上是指向您传入的 Scalar 容器的指针,就像上面一样。( 与 非常相似。$vis rwis raw$v\v\vis raw