Re[22]: Мифический Haskell
От: vdimas Россия  
Дата: 22.03.12 12:05
Оценка: +1
Здравствуйте, Klapaucius, Вы писали:

K>Ага, классы типов — это такой недопролог, который интерпретируется, правда во время компиляции.


При чем тут классы типов и паттерн-матчинг алгебраических типов? Классы типов — это лишь проверяемые в compile-time ограничения, то бишь контракты. В данном случае класс типов дает знать, что для типа существует scalarProduct, который можно безопасно вызывать. Я обратил внимание на то, что сама реализация контракта была описана для разных значений дескриминатора АлгТД. Т.е. это такая фишка Хаскеля — при объявлении ф-ий доступен урезанный паттерн матчинг по дискриминаторам АлгТД, где конкретная ф-ия выбирается в рантайм по результатам матчинга.

V>>В отличие от Haskel, подобное преобразование типов (распаковка) для кода Tonal- выполняется в compile-time.


K>Это в хаскеле — во время компиляции. А в C++ такой код не написать.


Никогда в Хаскеле распаковка АлгТД не происходит во время компиляции.


V>>Тоже неправда. Для АлгТД статически проверяется только м-но допустимых запакованных типов, то бишь статически проверяется лишь некое ограничение на возможный тип, но не сам запакованный тип.


K>Не понимаю, что за запакованный тип.


Это тип одного из возможных значений в группе, которая, в свою очередь, реализована техникой АлгТД.


K>Для АлгТД статически проверяется множество населяющих его значений — как и у любого другого типа.


Неверно, статически проверяется мн-во ТИПОВ населяющих его значений, но не сами значения, бо Хаскель, в отличии от С++ НЕ умеет статически реагировать на сами значения (С++ умеет на целочисленные, в т.ч. на указатели). Хаскель умеет только на их типы.
Для случая Хаскеля этот упакованный тип представляет из себя тупл (возможно пустой), где его имя (алиас типа) можно принять за имя соответствующего конструктора АлгТД.


K>Типы, ни "запакованные", ни какие АлгТД не населяют, они населяют кайнд. Кайнды, конечно, тоже бывают алгебраическими.


Вид, сорт, тип — это синонимы в теории групп.


V>>Конкретный тип распаковывается исключительно в рантайм, а сама техника распаковки тождественна технике dynamic_cast (с точностью до деталей, то бишь с точностью до способа кодирования/представления токена типа для целей рантайма).


K>Каст преобразует тип значения. Матчинг АлгТД никаким преобразованием типов не занимается.


Опять неверно, dynamic_cast НЕ изменяет само значение, переданное по ссылке (это обязательно, использовать dynamic_cast можно только через ссылку или указатель), оно тестирует тип поданного значения и преобразует тип ссылки, а не само значение, предоставляя доступ затем к мемберам типа по ссылке. Матчинг АлгТД в Хаскеле аналогично проверяет в рантайм дискриминатор объединения, то бишь запакованный тип, примерно точно так же, как dynamic_cast проверяет токен типа (на который ссылается экземпляр типа через указатель на vtable), а удачная ветка матчинга затем предоставляет доступ к значению упакованного в АлгТД типа.



V>>Там, где ML-яык работает с боксированными значениями в рантайм


K>Какая разница, боксированы значения или нет, если речь идет о типах?


Разница в том, что боксированный рекурсивный тип представляет из себя в памяти список (в простейшем случае, в непростейшем — дерево) из однородных узлов, а в небоксированном случае значение типа должно располагаться в памяти сплошным куском. Поэтому для первого случая достаточно одной реализации на каждый узел, а во втором потребуется столько различного кода, сколько типов было использовано во время компиляции. Поэтому в первом случае — в случае интерпретации структуры типа в рантайм, этот список/дерево может быть сколь угодно большой длины/глубины, то бишь мощность рекурсивного типа может быть сколь угодно большой.

Справедливости ради, в простейшем случае можно обойтись и без боксинга для рекурсивных типов, т.е. для линейного списка в памяти, где рекурсивный тип идет как хвостовой, его можно расположить линейно и сгенерить лишь один однородный код на все типы разной мощности. Но для дерева или для случая нехвостового рекурсивного типа — уже никак. Почему никак? Предлагаю попробовать нарисовать карту памяти как будут располагаться поля.

То бишь боксированность нам гарантирует одинаковый размер полей, т.е. одинаковую карту размещения для любого инстанса такого типа. Возвращаясь к примеру: в итоге, код ф-ии scalarProduct будет одинаков для всех узлов рекурсивного типа Cons int a.


K>Будут значения боксированными или нет — это вообще детали реализации, на статичность/динамичность системы типов не влияющие.


Угу, именно на это твое непонимание и обратил внимание. Статическая система типов хапрактерна не тлько статической проверкой контрактов. Упоминание эффективности статики как само собой разумеющееся (и даже ты тут отметился не раз в этой ветке, напоминая про статику) — это следствие того, что статически порожденный код ЗНАЕТ, как расположено в памяти значение оперируемого типа, и обращается к полям значения непосредственно, то бишь через фиксированные смещения в памяти, а не через дескрипторы/акцессоры.


V>>там мы имеем классическую эмуляцию динамики/интерпретации, хоть и со статическими проверками допустимости


K>Так динамика или стат. проверки? Тут одно из двух.


Мн-во допустимых типов значений АлгТД проверяется статически, конкретный тип из множества — динамически. Какие проблемы-то?


V>>мн-ва АлгТД в момент компиляции.


K>Что за "множество АлгТД"?


ОМГ


V>>инстанциировать типы целиком


K>А это что значит?


Наверно криво выразился. Имел ввиду, что в случае боксированной реалиации рекурсивных типов порожденному компилятором коду для его работоспособности достаточно знать об устройстве лишь части значения, а не всего значения целиком. Доступ к остальной части значения происходит рекурсивно через паттерн-матчинг, т.е. через рантайм-проверку, ну т.е. через динамику.


V>>Они не нужны только для боксированной реализации рекурсивных типов и прочей динамической типизации.


K>Типы не бывают "боксированными" — такими бывают значения. И к динамике это не имеет отношения. Динамика — это когда нет стат. типов, есть рантайм проверки. Типы в рантайме в хаскеле вообще не проверяются. В рантайме их нет — они уже стерты.


Неверно. Дискриминатор АлгТД присутствует в рантайм будучи сохраненным по адресу значения, и этот дискриминатор проверяется исключительно в рантайм. Доступ к запакованному в АлгТД значению предоставляется затем исключительно через ПМ (фишка Хаскеля — у него других способов и нет), т.е. делает невозможным неверную интерпретацию памяти, в которой находится значение АлгТД. В этом и заключается типобезопасность, которая таки для случая Хаскеля динамическая, когда идет оперирование АлгТД. Статически может проверяться лишь полнота, т.е. наличие всех веток для всех дискриминаторов АлгТД, одна из которых должна быть вызвана в рантайм (угу, включая умолчательное '_', но уже без доступа к памяти значения!).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.