metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2013-09-14 08:17 am

Хаскельное

http://vit-r.livejournal.com/679524.html?thread=3691364#t3691364
решили на прошлой работе трое таки попробовать Хаскель, для неспешной задачи. генерация DDL, DML c скриптами SQL. Бились, бились, - но сделали, и был восторг! Потом, затянула обычная работа, через месяцок нужно было добавить кое-чего... и никто из троих не смог понять как оно работает, и как же добавить.

Звучит похоже на правду. Хотя у меня и F# и Clojure в подобных задачах живут и развиваются без проблем.

[identity profile] thedeemon.livejournal.com 2013-09-16 03:58 pm (UTC)(link)
>Статические анализаторы кода для Хаскеля есть?

Да, они там называются "компилятор".

[identity profile] metaclass.livejournal.com 2013-09-16 04:10 pm (UTC)(link)
50% же.

[identity profile] thedeemon.livejournal.com 2013-09-16 04:25 pm (UTC)(link)
Почему?
Первый тест заходит в строчки 1,2,4.
Второй - в 1,3.
Вместе покрывают все 1-4.
Edited 2013-09-16 16:27 (UTC)
ext_646638: (Default)

[identity profile] rdia.livejournal.com 2013-09-16 06:04 pm (UTC)(link)
> Да, они там называются "компилятор".

Т.е. нет. В отличие от компилятора, статический анализатор

1. не ограничен во времени => может проводить более глубокую проверку кода.

2. имеет право на ошибку - предупреждения статического анализатора любой степени серьёзности могут быть ложными.

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

let 2d_distance_from_origin {x : float; y : float; z : float} in
let x = p.x in
let y = p.z in
x^2 + x^2;;

Ну и тому подобные, формально верные конструкции, которые часто могут быть следствием опечатки.

И, хотя, Хаскел значительно лучше С, от подобных вещей он не защищает.
ext_646638: (Default)

[identity profile] rdia.livejournal.com 2013-09-16 06:07 pm (UTC)(link)
> а доказательство, что в тестах проверятся каждая строка кода.

Т.е., действительно, как пишет тов. ниже, корреляции позволяется упустить?

[identity profile] geniepro.livejournal.com 2013-09-16 07:13 pm (UTC)(link)
Ну а сколько нужно?
В сях/сишарпе мне действительно часто приходится писать длинющие строки по 120 символов, но в хаскелле почему-то нет -- идентификаторы обычно короткие, так что сильно вправо код не лезет. Зато удобно два разных модуля на одном широкоформатном экране редактировать...

[identity profile] geniepro.livejournal.com 2013-09-16 07:24 pm (UTC)(link)
Был как-то тест, в котором в программы на разных языках вносили случайные опечатки, и смотрели, у кого компилятор больше таких ошибок обнаружит.
Хаскелл оказался защищён от таких ошибок гораздо хуже, чем с++ )))

[identity profile] geniepro.livejournal.com 2013-09-16 07:28 pm (UTC)(link)
Есть что-то типа того:

http://hackage.haskell.org/package/hlint

[identity profile] thesz.livejournal.com 2013-09-16 09:20 pm (UTC)(link)
data X
data Y
data Z

data Coord c a = C a -- c - phantom type, does not add runtime overhead.
instance Num a => Num (Coord c a) where ... -- you cannot add Coord X Float and Coord Y Float
type Vec a = (Coord X a, Coord Y a, Coord Z a)
field :: XYZ b => Vec a -> b -> Coord b a
field = ...

f p = let x = field p X; y = field p Z in x*x + castFromY (y*y) -- compiler error

[identity profile] vit-r.livejournal.com 2013-09-16 09:20 pm (UTC)(link)
Вот только это довольно бессмысленное занятие.

Для теоретика - да.

Для практика полное покрытие unit tests показывает, что в каждой строчке кода написали на самом деле то, что хотели написать.

[identity profile] vit-r.livejournal.com 2013-09-16 09:31 pm (UTC)(link)
Не надо писать "выше-ниже" для дерева из сотни комментариев. При чём тут корреляции, я не понял. Это практическая методика, а не попытка доказать что-то статистикой.

[identity profile] vit-r.livejournal.com 2013-09-16 09:35 pm (UTC)(link)
идентификаторы обычно короткие,

Можно подумать, что это хорошо.
ext_646638: (Default)

[identity profile] rdia.livejournal.com 2013-09-16 09:43 pm (UTC)(link)
Это, безусловно, классный приём, но что делать, если в 3-х местах не нужно складывать, а в 4-м нужно складывать координаты? Как норму считать - ещё пару вызовов вставить?

Подобную же штуку можно криво-косо сделать на С++, только овчинка выделки не стоит. Из-за раздутия кода вы сделаете ещё пару ошибок и т.д. Ухудшите ясность.

Я не спорю, что проверки в Хаскелле значительно круче, чем проверки в С++. Но в любом языке остаётся круг ошибок, которые не являются достойными занесения в компилятор, но вполне известны и часто повторяемы.

[identity profile] thesz.livejournal.com 2013-09-17 04:24 am (UTC)(link)
Я потерял вашу мысль.

В Хаскеле я могу ограничить круг пропускаемых ошибок чрезвычайно малым числом. Библиотекой, не компилятором. Ну, и что, что в C++ так нельзя?

Насчет "как норму считать" - отдельной функцией, верифицированной. Как это делается в обычных библиотеках.

[identity profile] geniepro.livejournal.com 2013-09-17 04:25 am (UTC)(link)
Идентификаторы не нужны сами по себе, и они должны отражать какую-то сущность. А в хаскелле чаще всего функции полиморфны, ну какие там сущности у их параметров? Имена вида x:xs достаточны в 80% случаев, имхо...

[identity profile] vit-r.livejournal.com 2013-09-17 05:32 am (UTC)(link)
Я рад, что имена "ХЗ" достаточны для пишущих на Хаскеле. Я говорю про реальные задачи, где нужно писать что-то вроде "дополнительный коэффициент накопления поправки 1998 года"

[identity profile] thesz.livejournal.com 2013-09-17 10:12 am (UTC)(link)
Кусок реальной программы:
-- | Вид блока памяти (для карты памяти)
data StoreKind addr where
    SKRegFile   :: StoreKind Int
    -- | Отображение внутренних переменных ядра в память (SPH, SPL, SREG)
    SKCPUVars   :: AVRCPU a =>
                   -- список переменных для отображения изменений в
                   -- отладочной печати (можно было бы и автоматом
                   -- извлекать из выражений)
                   [CPUVar (AVR a)] ->
                   StoreKind (AVRExpr a SIZE8, -- read expr
                              [Stat (AVR a)])  -- write stats
    SKSRAM      :: StoreKind Int
    SKFlash     :: StoreKind Int
    SKIO        :: StoreKind Int
    -- Внешняя память, с идентификатором
--    SKExternal  :: String -> StoreKind Int
    SKUndefined :: StoreKind ()
Есть ли вопросы?

[identity profile] kurilka.livejournal.com 2013-09-17 10:30 am (UTC)(link)
А комментарии на английском и русском сразу не смущают?

[identity profile] thesz.livejournal.com 2013-09-17 12:35 pm (UTC)(link)
Я пишу на английском, коллеги пишут на русском. Что поделать. ;)

[identity profile] thesz.livejournal.com 2013-09-17 12:42 pm (UTC)(link)
Expression trees весьма ограниченный инструмент, хотя и полезность его нельзя отрицать. На одних expression trees я довольно быстро сваял подобие LINQ для некоей гиперграфовой БД (с преобразованием запросов а-ля LINQ в текст запросов к сей БД).

Если бы была возможность преобразовывать тела функций с циклами for и тому подобного, это был бы номер. Тогда можно было бы делать совершенно удивительные вещи, типа кода с циклами, компилирующегося в код над OpenCL. Или делать триггеры для тех же БД.

[identity profile] jakobz.livejournal.com 2013-09-17 12:53 pm (UTC)(link)
>возможность преобразовывать тела функций с циклами for и тому подобного
В F# есть такое: http://msdn.microsoft.com/en-us/library/dd233182.aspx

В C# есть надежда на "Roslyn" - они собираются выкатить API к компилятору, с возможностью использовать его куски, или втыкаться в середину: http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx
ext_646638: (Default)

[identity profile] rdia.livejournal.com 2013-09-17 01:21 pm (UTC)(link)
> В Хаскеле я могу ограничить круг пропускаемых ошибок чрезвычайно малым числом.

Со стат. анализатором наверняка можно будет ещё больше ограничить. Но пока, видимо, кол-во ошибок слишком мало по сравнению с конкурентными языками. Поэтому создание стат. анализатора для Хаскеля нерентабельно.

[identity profile] thesz.livejournal.com 2013-09-17 01:47 pm (UTC)(link)
Вы про зависимые типы слышали? Хаскель движется в ту сторону.

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

[identity profile] vit-r.livejournal.com 2013-09-17 08:46 pm (UTC)(link)
Ну и зачем начинать? Вопросы, естественно, есть. И они, естественно, не понравятся.

[identity profile] thesz.livejournal.com 2013-09-17 09:18 pm (UTC)(link)
Так задавайте.

Page 5 of 6