Re[37]: Мифический Haskell
От: VoidEx  
Дата: 04.04.12 15:11
Оценка: 12 (1)
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, VoidEx, Вы писали:


VE>>>>Классы типов — это АлгТД.

S>>>Можно развернуть мысль?

VE>>Можно.


V>А можно, для не имеющих достаточной практики в Хаскеле его Prelude пояснить, где здесь используются классы типов?


Можно.

module Equal (
    ) where

import Prelude hiding (Eq(..))

-- class Eq a where
--   (==) :: a -> a -> Bool
--     (/=) :: a -> a -> Bool
data Eq a = EqCtor {
    equal :: a -> a -> Bool,
    notEqual :: a -> a -> Bool }

-- instance Eq Bool where
--   (==) = eq
--     (/=) = neq
boolEq :: Eq Bool
boolEq = EqCtor eq neq where
    eq True True = True
    eq False False = True
    eq _ _ = False
    neq x y = not $ eq x y

-- instance Eq Int where
--   (==) = eq
--     (/=) = neq
intEq :: Eq Int
intEq = EqCtor eq neq where
    eq 0 0 = True
    eq 0 x = False
    eq x 0 = False
    eq x y = eq (pred x) (pred y)
    neq x y = not $ eq x y

-- foo :: Eq a => a -> a -> a -> Bool
foo :: Eq a -> a -> a -> a -> Bool
-- foo x y z = (==) x y || (==) y z
foo (EqCtor eq neq) x y z = eq x y || eq y z

test1 = foo boolEq True False False
test2 = foo intEq 0 2 5


Тип Eq a полностью аналогичен классу Eq.
Отличие в том, что instance может быть только один, и передаётся он неявно.
Re[27]: Мифический Haskell
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 04.04.12 15:16
Оценка:
FR>Рантаймное ветвление при ПМ есть, почему ты и vdimas называете это динамической типизацией я не понимаю,

дай формальное опредение, которое бы строгим образом отличало одно (динамическую типизацию) от другого (runtime-ветвление)?
причем чтобы это определение не зависело от конкретного ЯП, и было одинаково подходящим для произвольного языка.

ззы
так как такого формального определения разницы дать нельзя, то я считаю — что это одно и тоже, а то что некоторые люди пытаются отличать одно от другого является чистой вкусовщиной и субъективизмом

зы
Если один и тот же код над данными выполняет разные операции значит это данные разного типа.
if в генеренном коде, как раз и это обозначает. что код вроде бы один, но данные обрабатывает по разному.

если операция деления выглядит как:
div(a, b)=
  if (b == 0) 
    throw error 
  else 
    посчитать сколько раз b входит в a

то этого достаточно для утверждения, что для операции div если два типа: 0 и не 0:
а также достаточно для выделения двух функций:
type number_not_0:number where number != 0;
type 0:number where number == 0;
div(a, number_not_0 b) =
    посчитать сколько раз b входит в a
div(_, number_0) =
    throw error
Re[45]: Мифический Haskell
От: VoidEx  
Дата: 04.04.12 15:18
Оценка:
Здравствуйте, DarkGray, Вы писали:

VE>>Почему невозможно?


DG>если ты говоришь, что каждая type system полностью независима от другой, и что в типе не указано как он хранится в памяти, то невозможно с map<string, array<int>> работать из haskell-я, из C++ и из питона, обращаешь к представлению данного типа в памяти напрямую.


В типе — не указано. В языке — указано.

VE>>Смотреть на типы с т.з. haskell, C и python — это не выйти в надсистему, а перейти в другую систему и при этом пытаться применить термины из одной системы с другой.


DG>при выходе в надсистему появляется обобщенный Type (будем его писать с большой буквы для однозначности), которые включает в себя C-тип, Haskell-тип, python-тип, ATS-тип и т.д

DG>Соответственно Type включает в себя все возможности, которые были у C/Haskell/python/ats-типов и т.д.:
DG>если C-тип умеет описывать как данные хранятся в памяти, значит и Type умеет,

C-тип не умеет этого описывать. Как хранятся конкретные типы, описывает язык Си, а не тип. Типизировать программу можно вне зависимости от того, как хранятся данные в памяти. Не надо мешать всё в кучу.
Re[27]: Мифический Haskell
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 04.04.12 15:23
Оценка:
DG>>Это утверждение неявно использует допущение, что описание функции в ЯП и генеренный для нее код соотносится как 1 к 1.
DG>>Такое допущение сильно упрощает действительность, и и является неверным и опасным.

FR>Генеренный код в данном случае делает ровно то что описывает ЯП а именно статически типизированную

FR>неполиморфную функцию.

и что эта фраза утверждает?
Re[27]: Мифический Haskell
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 04.04.12 15:29
Оценка:
FR>Мне кажется ты не понимаешь что в том коде который привел я (и по его мотивам D. Mon)
FR>нет разных типов и нет полиморфизма.

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

FR>Есть один единственный тип:


FR>type test = Int of int | Float of float | String of string


с точки зрения конструктивной логики (и наличия операций композиции и декомпозиции) — это как минимум 4 типа (вся необходимая информация есть), при необходимости можно построить и другие типы (в частности, type Number = Int of int | Float of float и т.д.)


FR>и фукция dummy_id мономорфна и работает с этим типом а функция dummy2 которую привел

FR>D. Mon с массивами этого типа, а не с массивами int, float или string. Так что такая
FR>развертка которую ты хочешь просто невозможна.

с точки зрения какой логики это невозможно?
Re[38]: Мифический Haskell
От: vdimas Россия  
Дата: 04.04.12 15:29
Оценка:
Здравствуйте, VoidEx, Вы писали:

V>>Это такое условное ветвление, целью которого является выбрать ветку алгоритма, умеющего работать с неким конкретным устройством значения (т.е. с неким конкретным типом).


VE>И if именно это и делает.


Там, где в рамках статически-типизированного языка не выполняется реинтерпретация памяти, то if этого не делает ни разу.


VE>Не путайте то, какие байтики лежат, с типом. В случае указателя конкретное устройство значения одно и то же — указатель, но тип тем не менее разный.


Это ты путаешь. Одинаковое устройство даже двух объявленных одинаково типов не гарантируется в том же С++. А в плане указателей (при чем тут они, кстати?), если работаем именно со значением указателя, а не с указываемой областью памяти, то одинаковое устройство указателей проявляется в полной мере — мы можем присвоить void * значение типизированного указателя, преобразовать в число, получить из числа и т.д. Попробуй преобразовать в число, скажем, struct A {}.

V>>Т.е. имеем следующее: в compile-time пишем алгоритмы под все возможные (или уникально обрабатываемые) типы, ожидаемые в некоей точке алгоритма, а в рантайм через ветвление выбираем одну из веток алгоритма, согласно фактически поданному типу значения.


V>>Для работоспособности этой схемы обязательно нужен некий механизм реинтерпретации памяти. Например, в C# это приведение типов as или через (Type1), в С++ через dynamic_cast или через reinterpret_cast, еще через встроенный рантайм-полиморфизм, в ML-языках через паттерн-матчинг.


VE>Какая связь типов с памятью?


Такая, что в статически-типизированном языке компилятору требуется знать представление любого типа в памяти для генерации кода.


VE>Вот тут, например, о каком механизме реинтерпретации памяти вообще в принципе может идти речь?


А где по ссылке ограничения в реализации, присущие компиляторам статически-типизированных языков? где там вообще идет речь о компиляции vs интерпретации или же где там вообще обсуждается реализация?
В общем, мы уже договорились чуть выше, что статическая типизация и статическая компиляция — вовсе не одно и то же. А ты продолжаешь их путать.

Заметь, в SystemF присутствуют т.н. абстрактные типы данных с конструкторами. А реализация абстрактных типов данных без какой-либо техники динамической диспетчеризации по конкретным устройствам значений, то бишь по конкретным типам, невозможна.

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



VE>>>То, что при наличии разных вариантов у АлгТД происходит ветвление — это динамическая типизация в той же мере, что и ветвление по 0 и не 0 в факториале.


V>>Нет.


VE>Да.


VE>Я вас удивлю, но (x:int){x==0} — это тип. У него ровно одно значение. И if это проверяет, а затем работает с этим типом.


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


VE>

VE>Formally, a type can be defined as "any property of a programme we can determine without executing the program"


VE>Вы же почему-то под типом подразумеваете какое-то внутреннее представление.


Почему нет, если речь идет непосредственно об этом представлении? Например, когда мы обсуждаем компилятор статически-типизируемого языка, а не некий интерпретатор.

И да, содержимое АлгТД, кроме вырожденных случаев (на которые тебя упорно тянет), невозможно определить ДО выполнения. Именно поэтому в ПМ по дискриминатору АлгТД более одной ветки, под все необходимые случаи, возможные в рантайм. А ведь в реальности многие из этих веток могут быть "мертвыми", т.е. не быть вызванными ни разу. Как тебе такое "property of a programme we can determine without executing the program"?


VE>Мол, что (x:int){x==0}, что (x:int){x>0}, один чёрт int, 4 байта, да?


Да, значение дискриминатора (т.е. некое его представление) само имеет некий тип, а что? Тебя смущает, что этот тип тебе не доступен в общем случае? ИМХО, лишь для того, чтобы не ограничивать способ реализации. Но для случая встроенных интегральных типов Хаскеля — доступен. Т.е. для некоего мн-ва встроенных типов, для которых объявлено, что они являются АлгТД, прямо в спецификации указан способ представления дискриминаторов этих АлгТД. Теперь полегчало?


VE>Ну так и указатель любой 4 (или 8) байта, ан нет, типы-то разные!


Ну и каша... В одном и том же варианте все значения дискриминаторов представлены одним и тем же типом by design алгебраического типа. Т.е. заведомо совместимы. А указатели разных типов в С++ сделаны несовместимыми, в отличие от С, именно затем, чтобы процедуру реинтерпретации памяти описывать в коде явно через специально предназначенные синтаксические конструкции реинтерпретации памяти, а не через простое присвоение указателей как в С.
Re[28]: Мифический Haskell
От: FR  
Дата: 04.04.12 15:40
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>с точки зрения какой формальной логики ты утверждаешь, что там этого нет?

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

Я утверждаю с точки зрения конкретного языка (вернее семейства ML языков) программирования.
Для Standard ML 97 есть полное формальное описание как синтаксиса так и семантики, если нужна полная
математическая формализация ищи это описание.


FR>>Есть один единственный тип:


FR>>type test = Int of int | Float of float | String of string


DG>с точки зрения конструктивной логики (и наличия операций композиции и декомпозиции) — это как минимум 4 типа (вся необходимая информация есть), при необходимости можно построить и другие типы (в частности, type Number = Int of int | Float of float и т.д.)


Понятно пошла альтернативная терминология и логика тут я пас, на десятки страниц обсуждения
ни о чем нет времени.
Re[40]: Мифический Haskell
От: vdimas Россия  
Дата: 04.04.12 15:42
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Можно вообще все unsigned int на int поменять (и наоборот), только придётся ручками указывать, какой именно мы less хотим.

VE>Т.е. они по сути оба strong typedef на одно и то же.

Именно строгий. Только это и позволяет использовать статический полиморфизм в операциях <, >.
Хотя, бывают и другие плюшки, например массив int в дотнете приводим к массиву uint, т.е. среда исполнения допускает такую реинтерпретацию памяти. А вот со ссылочными значениями уже обломс.


VE>Собственно, можно как раз про strong typedef и вспомнить. Неужто они определяет способ хранения в памяти, вводя новый тип?


Дык, представление значения типа в памяти — это не единственный признак типа. Один из. Прдеставь, что ты делаешь такой typedef в каком-нить интерпретаторе, где вся информация о типах нужна в момент исполнения. Тогда у тебя не будет возможности создать в памяти два одинаковых значения разного типа, т.к. будет всегда отличаться минимум одно поле — признак типа. Считай, что в статически-типизируемом происходит тоже самое, только признак типа "сокращается" компилятором. Но даже при компиляции статически-типизированного языка, признак типа сокращается не везде, а только там, где рантайм полиморфизм заведомо недоступен. Если же полиморфизм доступен в рантайм, то признак типа обязательно хранится вместе со значением.
Re[37]: Мифический Haskell
От: vdimas Россия  
Дата: 04.04.12 15:50
Оценка:
Здравствуйте, vdimas, Вы писали:

Поправка (болдом):

V>i]В общем виде[/i] такая структура в статически-типизированном языке после компиляции представима только через ...
Re[46]: Мифический Haskell
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 04.04.12 15:58
Оценка:
VE>C-тип не умеет этого описывать. Как хранятся конкретные типы, описывает язык Си, а не тип. Типизировать программу можно вне зависимости от того, как хранятся данные в памяти. Не надо мешать всё в кучу.

на твой взгляд, какие типы умеют описывать хранение в памяти?

ASN.1 подойдет?
давай его тогда добавим к нашей надсистеме.
Re[29]: Мифический Haskell
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 04.04.12 16:05
Оценка:
FR>Я утверждаю с точки зрения конкретного языка (вернее семейства ML языков) программирования.
FR>Для Standard ML 97 есть полное формальное описание как синтаксиса так и семантики, если нужна полная
FR>математическая формализация ищи это описание.

и какой смысл фиксировать такие общие определения, как: тип, типизация, полиморфизм, динамическая типизация и т.д. на основе кодогенерации конкретной реализации конкретного языка?
Re[28]: Мифический Haskell
От: VoidEx  
Дата: 04.04.12 16:08
Оценка:
Здравствуйте, DarkGray, Вы писали:

FR>>Рантаймное ветвление при ПМ есть, почему ты и vdimas называете это динамической типизацией я не понимаю,


DG>дай формальное опредение, которое бы строгим образом отличало одно (динамическую типизацию) от другого (runtime-ветвление)?

DG>причем чтобы это определение не зависело от конкретного ЯП, и было одинаково подходящим для произвольного языка.

DG>ззы

DG>так как такого формального определения разницы дать нельзя, то я считаю — что это одно и тоже, а то что некоторые люди пытаются отличать одно от другого является чистой вкусовщиной и субъективизмом

Невозможность надо доказывать. То, что пока не привели такого определения, не означает, что его нет.
Например, навскидку, динамическая типизация:
Каждому типу a ставится в соответствие множество типов T свободных по a таких, для каждого t : T существуют примитивные параметрически полиморфные (с ограничением по множеству T) функции
cast : a -> t
dynamicCast : t -> Maybe a

При этом выполняется
backCast : a -> Prop
backCast x = dynamicCast (cast x : t) === Just x


Уточнение: сводобных по a означает, что t : T не содержит в своем выражении тип a. Т.е. например Either a b туда не подходит.

Не динамическая типизация (в случае, конечно, если они внутри не используют её некоторым образом):
left :: Either a b -> Maybe a

template <class T>
T * cast(Some<T> * p);


Динамическая типизация:
fromDyn :: (Typeable a) => Dynamic -> Maybe a

template <class T, class U>
U * myDynamicCast(T * p);


Т.е. в Haskell каждому Typeable a ставится в соотсветствие Dynamic, и есть функции туда-обратно с нужными свойствами:
toDyn :: Typeable a => a -> Dynamic
fromDyn :: Typeable a => Dynamic -> Maybe a


В Си++ такая "функция" dynamic_cast и встроенный каст в родителю.

Не является динамической типизацией функция
foo :: a -> Maybe b
foo _ = Just undefined

Так как результат не определён.

Не является динамической типизацией функция
bar :: a -> Maybe b
bar _ = Nothing

Так как (bar 4 :: Maybe Int) =/= (Just 4 :: Maybe Int)

Не является динамической типизацией функция
template <class T, class U>
T * notDyn(U * x) { return 0; }

Так как notDyn<int, int>(p) != 0

Не является динамической типизацией функция
template <class T, class U>
class NotDyn
{
public:
  T * cast(U *) { return 0; }
};

template <class T>
class NotDyn<T, T>
{
public:
  T * cast(T * x) { return x; }
};

Так как она не параметрически полиформная.
Re[30]: Мифический Haskell
От: FR  
Дата: 04.04.12 16:18
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>и какой смысл фиксировать такие общие определения, как: тип, типизация, полиморфизм, динамическая типизация и т.д. на основе кодогенерации конкретной реализации конкретного языка?


Во первых не на основе кодогенерации, а на основе спецификации (или стандарта) языка, тут Standart ML как-раз
подходит лучше всех так как имеет полностью математически формализованную спецификацию.

Общие определения ни к чему кроме терминологического спора не приведут. Причина простая в большинстве языков
эти определения слишком размыты и для разных языков часто противоречивы.
Re[36]: Мифический Haskell
От: vdimas Россия  
Дата: 04.04.12 16:30
Оценка:
Здравствуйте, VoidEx, Вы писали:

V>>Тогда нафига классы типов вообще нужны?

VE>Чтобы не передавать Eq a явно. Правда, для этого вовсе не обязательно надо было городить классы типов.

А что можно?


V>>Например, обсуждаемый пример, где Nil и Cons — это совершенно независимые типы, а не конструкторы одного АлгТД. И где де-факто рекурсия была сделана на полиморфном аргументе, а не рекурсивном АлгТД. Т.е. классы типов позволяют использовать в алгоритмах независимые типы.


VE>Этот пример переписывается без использования классов типов один в один.


А обсуждаемый compile-time контроль длины массива остается?
Моя версия была такова:

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

Можно, добавив фиктивные тайлевел вычисления, не участвующие в рантайм-вычислениях. Я имел ввиду организацию рекурсивного типа. Сейчас эта рекурсия выполнена на полиморфном аргументе, а можно было сделать явно на алгТД.



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


VE>Не знаю, кто вам что доказывал, но если этот пример таки написать на Си, у вас там будут те же самые проверки в том же объёме. Cons у вас будет не шаблоном, а struct Cons { int value; void * p; } и т.п.

VE>Статическую проверку можно будет наложить шаблоном и кастами void* <-> T*

VE>На исходном Си++ примере же у нас кодогенерация, которая не даёт тех же возможностей, что и Haskell, но зато избавлена от проверок. Ну дак и на TemplateHaskell это можно сделать точно так же. Без проверок.


VE>Итого: либо оба примера работают, как хотел МигМит, с одинаковым кол-вом проверок, либо оба не используют проверки, как Си++, но и никакой вводимой длины списка не будет, а только определённая в compile-time.


+1000
спасибо за полноценное пояснение происходящего в рантайм, но вопрос насчет compile-time в силе.


V>>Таки нет. АлгТД имеет вполне конкретное определение. А тот факт, что классы типов конкретно в Хаскеле, с его, скажем так, особенностью представления модулей, вполне можно выразить через неявные АлгТД — это частность, которая может исчезнуть при другом представлении модулей. Просто сейчас компиляторам доступен "исходник" (пусть даже в распаршенном виде) всех используемых модулей, что можно в процессе компиляции статически сгенерить АлгТД по всем инстансам класса.


VE>Это шутка что ли или непонимание?

...
VE>Что теперь? Туплы и ФВП у нас работают тоже благодаря особенностям представления модулей?

Я имел ввиду, что компилятор "видит" все инстансы классов типов из зависимых модулей.
Re[41]: Мифический Haskell
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 04.04.12 16:30
Оценка:
Здравствуйте, DarkGray, Вы писали:

DM>>Ну так речь шла о типизации, а не о типе.


DG>если в понятие типа упоминается о способе хранения в памяти, а в более сложном понятии (типизация или type system) — этой составляющей нет, то можно сделать вывод, что определение сложного понятия как минимум не полное.


По-твоему, всякое определение должно включать в себя определения и подробности всех используемых терминов? Это нереально. Человечество придумало другой способ, получше: использовать лишь названия терминов, определения которых даются отдельно.

DG>>>, во-вторых: это ужасное определение: определение должно определять понятие через более простые, а в данном случае — определение элементарного понятия "type system" идет через такиие неопределяемые понятия как: syntactic, framework, classifying, phrases, kind, compute, according.

DG>>>можно получить строгое формализованное определение всех перечисленных понятий?

DM>>Можно. А нужно?


DG>строго необходимо, если стоит задача получить корректное описание реальности.


Ок, займусь завтра. Только как бы это не вылилось в просьбы с твоей стороны дать определения всем-всем словам русского и английского языков, так мы нескоро закончим. Я (как и цитируемый в вики Пирс) надеялся на наличие у собеседников каких-то общих знаний, но видимо зря.

DM>>Это одна структура в Си, содержащая внутри union. Она трактуется по-разному в зависимости от значения определенного поля.


DG>здесь неявно подразумевается, что одна структура в C — это строго один математических тип.

DG>из какого определения это следует?

Из определения структур в языке Си.

DM>>Я и говорю, подходов к определению может быть много.

DG>определения все одинаковые?, или можно их классифицировать чем они лучше/хуже по тем или иным признакам?

Разные. При желании, вероятно можно.
Re[39]: Мифический Haskell
От: VoidEx  
Дата: 04.04.12 16:32
Оценка:
Здравствуйте, vdimas, Вы писали:

VE>>И if именно это и делает.


V>Там, где в рамках статически-типизированного языка не выполняется реинтерпретация памяти, то if этого не делает ни разу.


Делает, делает.

VE>>Не путайте то, какие байтики лежат, с типом. В случае указателя конкретное устройство значения одно и то же — указатель, но тип тем не менее разный.


V>Это ты путаешь. Одинаковое устройство даже двух объявленных одинаково типов не гарантируется в том же С++. А в плане указателей (при чем тут они, кстати?), если работаем именно со значением указателя, а не с указываемой областью памяти, то одинаковое устройство указателей проявляется в полной мере — мы можем присвоить void * значение типизированного указателя, преобразовать в число, получить из числа и т.д. Попробуй преобразовать в число, скажем, struct A {}.


Типы Base * и Child * — разные. Не Base и Child, а именно Base * и Child *. Где тут реинтепретация памяти?

VE>>

VE>>Formally, a type can be defined as "any property of a programme we can determine without executing the program"


VE>>Вы же почему-то под типом подразумеваете какое-то внутреннее представление.


V>Почему нет, если речь идет непосредственно об этом представлении? Например, когда мы обсуждаем компилятор статически-типизируемого языка, а не некий интерпретатор.


Потому, что тогда мы придём к вырожденному случаю: при любом ветвлении программа ведёт себя с памятью по-разному.
Т.е. проверка на if (x == 0) меняет её работу с памятью, т.е. приводит к различной её интерпретации.

И именно поэтому важно не то, что с памятью работают иначе (ибо это всегда так), а то, как на это дело наложена система типов.

V>И да, содержимое АлгТД, кроме вырожденных случаев (на которые тебя упорно тянет), невозможно определить ДО выполнения. Именно поэтому в ПМ по дискриминатору АлгТД более одной ветки, под все необходимые случаи, возможные в рантайм. А ведь в реальности многие из этих веток могут быть "мертвыми", т.е. не быть вызванными ни разу. Как тебе такое "property of a programme we can determine without executing the program"?


Мёртвыми могут быть ветки и в банальном Си. Иногда компилятор это даже умеет определять и оптимизировать. К типизации это отношения не имеет.
Или что, назовём динамической типизацией лишние if, когда согласно алгоритму в этот if мы никогда не попадём (но при этом выяснить это в compile-time = решить проблему останова)?

VE>>Мол, что (x:int){x==0}, что (x:int){x>0}, один чёрт int, 4 байта, да?


V>Да, значение дискриминатора (т.е. некое его представление) само имеет некий тип, а что? Тебя смущает, что этот тип тебе не доступен в общем случае? ИМХО, лишь для того, чтобы не ограничивать способ реализации. Но для случая встроенных интегральных типов Хаскеля — доступен. Т.е. для некоего мн-ва встроенных типов, для которых объявлено, что они являются АлгТД, прямо в спецификации указан способ представления дискриминаторов этих АлгТД. Теперь полегчало?


Чего? Ты читаешь, что я пишу? Причём тут АлгТД вообще?
Давай перепишу иначе:
(x:int){x > 10} и (x:int) { 10 * x + 23 < 2332 } — это разные типы. Но по-твоему получается, что нет.
Нотация (x:t){f(x)} означает, что x принадлежит подмножеству t такому, что выполняется f(x). Это тип. Никакой f не вычисляется в runtime и даже не существует.
Типы разные, представление — абсолютно одинаковое.

VE>>Ну так и указатель любой 4 (или 8) байта, ан нет, типы-то разные!


V>Ну и каша... В одном и том же варианте все значения дискриминаторов представлены одним и тем же типом by design алгебраического типа. Т.е. заведомо совместимы. А указатели разных типов в С++ сделаны несовместимыми, в отличие от С, именно затем, чтобы процедуру реинтерпретации памяти описывать в коде явно через специально предназначенные синтаксические конструкции реинтерпретации памяти, а не через простое присвоение указателей как в С.


Ты по ходу с собой общаешься.
Re[37]: Мифический Haskell
От: VoidEx  
Дата: 04.04.12 16:38
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, VoidEx, Вы писали:


V>>>Тогда нафига классы типов вообще нужны?

VE>>Чтобы не передавать Eq a явно. Правда, для этого вовсе не обязательно надо было городить классы типов.

V>А что можно?


implicit arguments

V>>>Например, обсуждаемый пример, где Nil и Cons — это совершенно независимые типы, а не конструкторы одного АлгТД. И где де-факто рекурсия была сделана на полиморфном аргументе, а не рекурсивном АлгТД. Т.е. классы типов позволяют использовать в алгоритмах независимые типы.


VE>>Этот пример переписывается без использования классов типов один в один.


V>А обсуждаемый compile-time контроль длины массива остается?


Да.

V>>>Таки нет. АлгТД имеет вполне конкретное определение. А тот факт, что классы типов конкретно в Хаскеле, с его, скажем так, особенностью представления модулей, вполне можно выразить через неявные АлгТД — это частность, которая может исчезнуть при другом представлении модулей. Просто сейчас компиляторам доступен "исходник" (пусть даже в распаршенном виде) всех используемых модулей, что можно в процессе компиляции статически сгенерить АлгТД по всем инстансам класса.


V>Я имел ввиду, что компилятор "видит" все инстансы классов типов из зависимых модулей.


Считайте, что они импортируются неявно. Система типов от этого не страдает.
Re[41]: Мифический Haskell
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 04.04.12 16:38
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>пока ты копируешь определения из википедии — никакого сознания нет, есть лишь тот самый автомат из китайской комнаты, который механически подставляет необходимую ссылку на википедию, когда встречает ключевые слова.

DG>сознание определяют как умение выстраивать логические цепочки и гибкое адаптирование к контексту.
DG>при копировании определения из вики — ни первого, ни второго — нет.

Во-первых, не надо путать сознание (consciousness) и интеллект/разум (intelligence), это очень разные вещи. Во-вторых, когда я цитирую википедию, я опираюсь на общую базу знаний и надеюсь, что используемые там слова собеседникам известны. В противном случае коммуникация крайне трудна. В-третьих, китайская комната как раз показывает, что даже демонстрация выстраивания логических цепочек не позволяет определить наличие "настоящего" разума. Зато логические ляпы вроде твоего позволяют показать недостаток разумности.
Re[24]: Мифический Haskell
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 04.04.12 16:41
Оценка:
Здравствуйте, DarkGray, Вы писали:

DM>>Никакой специализации компилятор не сделает, на эффективность dummy_id твой код не повлияет, там внутри по-прежнему будет по 2 if'a.


DG>можно ли при этом сгенерировать более эффективный код? хотя бы руками?


В том конкретном случае, когда все аргументы известны при компиляции, можно суперкомпиляцией сразу получить программу, выводящую ответ, все вычисления выкинув.
Re[38]: Мифический Haskell
От: vdimas Россия  
Дата: 04.04.12 16:43
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Отличие в том, что instance может быть только один, и передаётся он неявно.


Именно, достаточен один экземпляр таблицы ф-ий, который компилятор построит сам.
Странно, что мои аналогичные предположения, как это может быть реализовано, были оспорены здесь: http://www.rsdn.ru/forum/decl/4675175.1.aspx
Автор: Klapaucius
Дата: 25.03.12
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.