2016-08-14 92 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