参数化角色上的定义性约束

huangapple go评论72阅读模式
英文:

definedness constraint on parametrized roles

问题

以下是您要翻译的代码部分:

"Should it be possible to add a definedness constraint on parameterized roles? The following attempt:

class C {
	method m ( R[Str]:D $a ) { }
}```
results in:
> Invalid typename 'D' in parameter declaration.
> at ... scratch.raku:4
> -------> method m ( R[Str]:D⏏ $a ) { }

and declaring a variable:
```role R[::T] { }
class S does R[Str] { }
my R[Str]:D $r = S.new;```
results in:
> Malformed my
> at ... scratch.raku:8
> -------> my R[Str]⏏:D $r = S.new;"

如果您需要更多帮助,请告诉我。

<details>
<summary>英文:</summary>

Should it be possible to add a definedness constraint on parameterized roles?  The following attempt:

role R[::T] { }
class C {
method m ( R[Str]:D $a ) { }
}

results in:
&gt; Invalid typename &#39;D&#39; in parameter declaration.  
&gt; at ... scratch.raku:4  
&gt; ------&gt;         method m ( R[Str]:D⏏ $a ) { }

and declaring a variable:

role R[::T] { }
class S does R[Str] { }
my R[Str]:D $r = S.new;

results in:
&gt; Malformed my  
&gt; at ... scratch.raku:8  
&gt; ------&gt; my R[Str]⏏:D $r = S.new;



</details>


# 答案1
**得分**: 5

**TL;DR** @wamba的回答假定了您的问题的“确定性”解释(这似乎是您实际上想要的),并为此提供了一个简洁的解决方案。这个答案解释了您的问题为什么模棱两可,并为两种解释提供了解决方案。我的解决方案都不同于@wamba的,因此这个答案可以作为他们答案的补充。

# 您的问题是模棱两可的

这是您在开头写的内容:

&gt; 是否应该能够对参数化角色添加“确定性”约束?

这里实际上是隐含的问题:

&gt; 是否应该能够对参数化角色添加“明确定义性”约束?

我将按相反的顺序来处理它们,因为您几乎可以肯定您指的是“明确定义性”,而不是“定义”。

# 明确定义性

明确定义性对应于`:D`类型约束或`.DEFINITE`编译宏。

这是您问题中的代码所涉及的内容。

您问题中的`R[Str]:D`是无效的语法,可能是由于疏忽、没有时间、没有共识或故意决定。我没有对此进行研究。可能有人已经提出了这个问题。再次强调,我没有研究过。

以下是一种添加等效“明确定义性”约束的方法,适用于您的示例:

role R[::T] { }
class C {
method m ( R[Str] $a where .DEFINITE) { 42 }
}

say C.new.m: R[Str].new; # 42
say C.new.m: R[Str]; # 在绑定到参数'$a'时,约束类型检查失败


# 定义

明确定义性对应于`.defined`方法调用,由`with`和中缀`//`等功能进行测试。

这是您问题的标题和开头的句子所涉及的内容,字面上理解。

&gt; 是否应该能够对参数化角色添加“定义性”约束?

以下是一种方法:

role R[::T] { }
class C {
method m ( R[Str] $a where .defined) { 42 }
}

say C.new.m: R[Str].new; # 42
say C.new.m: R[Str]; # 在绑定到参数'$a'时,约束类型检查失败


---

注意结果与`.DEFINITE`的结果相同(如果`Type[Type]:D`的语法有效的话,结果也将相同)。

但它们并不总是适用于所有对象,这反映了明确定义性约束与定义性约束不完全相同的事实,`:D`和`.DEFINITE`对应于“确定性”,而`.defined`对应于“定义性”。

# 确定性与定义性

确定性和定义性之间的相似性是有意的。如果给定对象没有`.defined`方法(几乎没有一个有这个方法),它将继承`Mu`的方法,而这个`.defined`方法只返回`self.DEFINITE`。

但是,`DEFINITE`方法不能被覆盖,而`.defined`方法可以:

1. *用户*可以为他们的类/对象覆盖`.defined`。这使得编写外部语言适配器以允许Raku与具有与Raku不同的定义性概念的另一种编程语言进行互操作变得容易(这几乎是唯一的用例。通常不建议普通的Raku代码覆盖`.defined`)。

2. 内置的`Failure`类覆盖了`.defined`。它对类型对象(正常情况下)和实例都返回*`False`*。因此:

say "{.DEFINITE.gist}\t{.defined.gist}\t{.gist}"
for (Mu, Mu.new, Int, 42, Failure, Failure.new)

显示如下:

False False (Mu)
True True Mu.new
False False (Int)
True True 42
False False (Failure)
True False (HANDLED) Failed


最后一行对应于`Failure.new`,第一列为`True`(其`.DEFINITE`为`True`),但第二列为`False`(其`.defined`为`False`)。

# 脚注

&#185; 我认为不应该为使`Type[Type]:D`工作而提出问题。类似地,如果已经提出了问题,我预计它将在可预见的未来被忽略,除非非核心开发人员为其创建了合适的PR(这仍然可能会被拒绝)。

&#178; 明确定义性是Raku渐进类型系统的静态类型基础的重要部分,以及“对象”是一种既可以是类型对象又可以是对象实例的概念。为了允许编译器在编译时依赖于这个简单的二选一布尔值,即“确定性”的行为以及`.DEFINITE`宏不能被用户代码覆盖-与`.defined`方法不同。

<details>
<summary>英文:</summary>

**TL;DR** @wamba&#39;s answer assumes the &quot;definiteness&quot; interpretation of your question (which seems likely to be what you actually meant) and provides a nice succinct solution for that. This answer explains why your question is ambiguous, and provides a solution for both interpretations. Neither of my solutions are @wamba&#39;s, so this answer serves as a complement to theirs.

# Your question is ambiguous

Here&#39;s what you wrote at the start:

&gt; Should it be possible to add a *definedness* constraint on parameterized roles?

Here instead is the implicit question:

&gt; Should it be possible to add a **definiteness** constraint on parameterized roles?

I&#39;ll address them in reverse order, given that it&#39;s near certain you meant *definite*, not *defined*.

# Definite

Definiteness corresponds to the `:D` type constraint or `.DEFINITE` compiler macro.

This is what the code in your question is about.

The fact that `R[Str]:D` is invalid syntax may be due to an oversight, or lack of tuits, or lack of consensus, or a deliberate decision. I have not researched that. Someone may have filed an issue about it.&#185; Again, I have not researched that.

Here&#39;s a way to add an equivalent *definiteness* constraint that works for your example:

role R[::T] { }
class C {
method m ( R[Str] $a where .DEFINITE) { 42 }
}

say C.new.m: R[Str].new; # 42
say C.new.m: R[Str]; # Constraint type check failed in binding to parameter '$a'


# Defined

Definedness corresponds to the `.defined` method call, as tested by features such as `with` and infix `//`.

This is what your question&#39;s title and opening sentence refer to, taken literally.

&gt; Should it be possible to add a *definedness* constraint on parameterized roles?

Here&#39;s one way:

role R[::T] { }
class C {
method m ( R[Str] $a where .defined) { 42 }
}

say C.new.m: R[Str].new; # 42
say C.new.m: R[Str]; # Constraint type check failed in binding to parameter '$a'


----

Note how the result is the same as for `.DEFINITE` (and would have been if `Type[Type]:D` was valid syntax).

But they aren&#39;t *always* the same for *all* objects, which reflects the fact that a definiteness constraint is not exactly the same as a definedness constraint -- `:D` and `.DEFINITE` correspond to *definiteness* whereas `.defined` corresponds to *definedness*.

# Definite vs Defined

The similarity between definiteness and definedness is deliberate. If a given object has not got a `.defined` method (and almost none do) it will inherit `Mu`&#39;s. And that `.defined` method just returns `self.DEFINITE`.

But while the `DEFINITE` method cannot be overridden&#178;, the `.defined` one can be:

1. *Users* may override `.defined` for their classes/objects. This makes it easy for someone writing a foreign language adaptor to allow Raku interop with another PL which has a different notion of definedness than Raku&#39;s. (This is pretty much the only use case. It is generally ill-advised for ordinary Raku code to override `.defined`.)

2. The built in `Failure` class overrides `.defined`. It returns *`False`* for *both* the type object (as normal) *and instances*. Thus:

say "{.DEFINITE.gist}\t{.defined.gist}\t{.gist}"
for (Mu, Mu.new, Int, 42, Failure, Failure.new)

displays:

False False (Mu)
True True Mu.new
False False (Int)
True True 42
False False (Failure)
True False (HANDLED) Failed


The last line, which corresponds to `Failure.new`, has `True` in the first column (its `.DEFINITE` is `True`) but `False` in the *second* column (its `.defined` is `False`).

# Footnotes

&#185; I don&#39;t think an issue should be filed for making `Type[Type]:D` work. Similarly, if an issue has been filed, then I would anticipate it being ignored for the foreseeable future unless a non-core-dev creates a suitable PR for it (which may still be rejected).

&#178; Definiteness is fundamental to the static typing foundation of Raku&#39;s gradual type system *and* its notion that an &quot;object&quot; is something that can be either a type object or an object instance. To allow the compiler to rely on this simple either/or boolean at compile time, the behavior of &quot;definiteness&quot;, and thus the `.DEFINITE` macro, cannot be overridden by user code -- unlike the `.defined` method.

</details>



# 答案2
**得分**: 3

可以在参数化角色上使用 `R:D[Str]` 语法添加一个*确定性*约束。所以,你的例子会是这样的:

```lang-raku
role R[::T] { }
class S does R[Str] { }
my R:D[Str] $r = S.new;

但是请注意,$r 可能是确定但是未定义的(参见 @raiph 的回答):

role R[::T] { method defined { False} }
class S does R[Str] { }
my R:D[Str] $r = S.new; 
say $r // 'undefined';
英文:

It is possible add a definiteness constraint on parameterized roles using R:D[Str] syntax.

So, your example would look like this:

role R[::T] { }
class S does R[Str] { }
my R:D[Str] $r = S.new;

However keep in mind that $r could be definite yet undefined (see @raiph's answer):

role R[::T] { method defined { False} }
  class S does R[Str] { }
  my R:D[Str] $r = S.new; 
  say $r // &#39;undefined&#39;;

huangapple
  • 本文由 发表于 2023年3月31日 04:26:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892714.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定