2016-08-14 3 views
12

Я недавно смотрел на wikipedia page for dependent types, и мне было интересно; действительно ли Perl 6 действительно вводит зависимые типы? Я не могу найти надежного источника, утверждающего это.Поддерживает ли Perl6 зависимые типы?

Для некоторых это может быть очевидно, но это точно, поскольку черт не очевиден для меня.

ответ

11

против Вен, в комментариях после ответа Perl 6 на вопрос SO «Есть ли язык с constrainable типов?», Пишет "perl6 doesn't have dependant types" и позже написал «зависимый тип, вероятно, не ... ну, если мы получим разрешимый where s ... "в обмен на # perl6. (Ответ Ларри Уолла был "what's a few halting problems among friends". Кстати, на сегодняшний день является лучшим способом, чтобы получить достоверный ответ на все вещи, Perl 6, чтобы спросить TimToady через # Perl6.)

Для резюме для '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 

Означает ли это, 6 subset функция Perl генерирует зависимые типы? Возможно, это то, о чем думает Авваид.

+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

Смежные вопросы