2016-08-14 94 views

回答

11

反对法师,在下面的Perl 6的答案的SO问题的意见“是否有与可限制类型的语言?”中写道"perl6 doesn't have dependant types"后来写道:“依赖型,可能不是,......嗯,如果我们在#perl6交换中得到可判定的where s ...“。 (Larry Wall的反应是"what's a few halting problems among friends"。顺便说一句,目前最好的办法让所有的东西Perl 6的是通过#perl6问TimToady一个权威的答案。)

'dependent-type' SO tag的总结是“依赖类型依赖于价值的类型“。 Perl 6支持依赖于值的类型,所以就是这样。

对于由Awwaiid所添加Perl 6的维基百科页面上Dependent Types变化的编辑总结说:“Perl 6的......具有不可判定依赖型”。

的维基百科页面开头:

一个依赖型是一种类型,其定义取决于一个值。 “一对整数”是一种类型。由于依赖于该值,“第二个大于第一个的整数对”是依赖类型。

下面是Perl 6的创建沿着这些线路类型的一种方法:

subset LessMorePair of Pair where { $_.key < $_.value } 
subset MoreLessPair of Pair where { $_.key > $_.value } 

multi sub foo (  Pair) { " P" } 
multi sub foo (LessMorePair) { "LMP" } 
multi sub foo (MoreLessPair) { "MLP" } 

for 1 => 1, 1 => 2, 2 => 1 { say foo $_ } 

# P 
# LMP 
# MLP 

这是否意味着Perl 6的subset功能产生依赖的类型?也许这就是Awwaiid所想的。

+0

那么,在这个意义上,Perl 6的有“根据值类型”,然后是当然。按照这个定义,C也可以。但只有索引类型本身并不是很有用。 – Ven

+0

FWIW,[我也考虑劫持参数化角色](https://github.com/vendethiel/6meta-experiments/blob/master/church.pl),但只有'count'版本可以工作(在运行时解开它们) 。角色需要一个“实例化”阶段(如C++模板)来获得类似于依赖类型的东西,但这不在菜单上:-)。 – Ven

+0

@Ven这听起来像依赖类型的可接受定义可能像“足够有用/一般编译时间完全可判定的依赖于值的类型检查谓词”,因此,在2017年,香草索引类型不计数,因为它们是没有被认为是有用的或通用的,但是使用SMT解算器的类型检查确实有用。所以,即使P6是这样的,编译器可以分析where子句,并转换为where Int | Str | IntStr'类型约束编译为编译时类型检查(它可以做到这一点?),它仍然不依赖于输入。那接近吗? – raiph

11

可以肯定的是,因为子集是可能取决于任意条件的类型。但是,类型系统会被分类为不健全,因为类型不变量不会被强制执行。

特别是变量的类型约束只检查了任务,所以修改一个对象,让它从一个子集落将导致变量持有的对象不应该是可以的,比如

subset OrderedList of List where [<=] @$_; 

my OrderedList $list = [1, 2, 3]; 
$list[0] = 42; 
say $list ~~ OrderedList; 

您可以使用某些元对象向导来使对象系统在通过装入透明防护对象中的对象进行任何方法调用后自动检查类型。

一个天真的实现可能是这样的:

class GuardHOW { 
    has $.obj; 
    has $.guard; 
    has %!cache = 
     gist => sub (Mu \this) { 
      this.DEFINITE 
       ?? $!obj.gist 
       !! "({ self.name(this) })"; 
     }, 
     UNBOX => sub (Mu $) { $!obj }; 

    method find_method(Mu $, $name) { 
     %!cache{$name} //= sub (Mu $, |args) { 
      POST $!obj ~~ $!guard; 
      $!obj."$name"(|args); 
     } 
    } 

    method name(Mu $) { "Guard[{ $!obj.^name }]" } 
    method type_check(Mu $, $type) { $!obj ~~ $type } 
} 

sub guard($obj, $guard) { 
    use nqp; 
    PRE $obj ~~ $guard; 
    nqp::create(nqp::newtype(GuardHOW.new(:$obj, :$guard), 'P6int')); 
} 

这将使以下故障:

my $guarded-list = guard([1, 2, 3], OrderedList); 
$guarded-list[0] = 42; 
+1

我同意一般情绪,虽然硬核依赖打字员(或任何依赖类型的倡导者被称为)可能会反对类型不在编译时检查,所以你的例子不计算。我想这完全取决于解释。 – moritz

+0

@moritz说什么。运行系统是un(i)类型的,所以它需要在编译时发生。 – Ven