metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-10-11 03:22 pm

Динамическая типизация, или статическая типизация для ленивых

Вчера [livejournal.com profile] ivan_gandhi сделал замечание что я, пользуясь динамически типизированной кложурью, при этом требую, чтобы в Java проверяли входные параметры на валидность. (Если что, проверка валидности в дотнете есть на каждом шагу, а объяснения вида "экономят циклы и не делаю проверки" в контексте жабы, тяжелого железа, JIT и прочего звучат крайне странно).
Собирался на эту тему устроить срач с утра, но [livejournal.com profile] thedeemon уже начал, так что я продолжу :)

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

Например, я хочу использовать кортеж с именованными полями (потому что позиционные кортежи нихера нечитабельны и их тип вида int*string*smallint*money*bool*Chervie ни о о чем не говорят). От входа в F# при этом нужно:
1) объявить этот чертов record где-то
2) сослаться на модуль с объявлением везде где он нужен
3) создавать экземпляры рекорда кривопачвярными конструкциями, причем оставить поля значениями по умолчанию нельзя.
4) паттерн матчинг с декомпозицией вроде не работает с рекордами.

Хаскель сразу закапываем - там на каждый случай имеется 3-4 расширения и 10 пакетов в hackage различной степени недоделанности, идиоматический подход - писать в point-free style, чтобы коллеги не разобрались, а работать в продакшене можно только с теми сторонними библиотеками, которые я могу сам починить.

При этом, у меня при работе с оперденями постоянно ситуации вида: есть запись с тремя полями, полученная из БД, мне нужно произвести обработку этой записи и добавить результат обработки в виде четвертого поля, получив новый тип записи.
Я НЕ хочу объявлять каждый раз такое руками и в Clojure это делается элементарно, добавлением нового ключа в map в функции-обработчике записей.

При этом РЕАЛЬНО динамическую типизацию я не использую. Она мне почти не нужна, потому что единственная ситуация, где вменяемый человек будет на одном цикле биндить к имени число, на втором строку, на третьем - список записей - это когда по условию задачи нужна, например, EAV-модель во все поля. И то - обычно EAV делается от безысходности, потому что пользователь не может нормально работать со схемой БД, а задача требует чего-нибудь вроде "добавить к части записей атрибут "фаза луны в которую производилась приемка товара"". В норме должны быть зависимые типы и миграции и пользователи бы пользовались той же системой типов что и разработчик.
Т.е. нормальный вывод типов - это когда программа берет типы из тут же описанного SQL-запроса, а рекорды расширяемые и объявлять их не нужно.

Второй use-case, где "вроде бы динамическая типизация" - это когда я делаю документы в виде кложурных структур данных, подгоняя комбинации списков-мапов-массивов-множеств под предметную область. В кложуре же это делается в лоб, а в хаскеле в один список не положишь три разных по структуре(типу) раздела документа. Но на самом деле, то что я делаю в кложури - это просто алгебраический тип данных "для бедных", без объявления заранее и без явно выделенных-именованных конструкторов данных. Если бы была возможность делать расширяемые и объявляемые по месту типы данных (чтобы каждый раз при разработке не переключаться между объявлением типа и конструированием данных по этому типу) - то было бы то же самое что в кложури - но статически типизированное.

PS: На ту же тему: http://justy-tylor.livejournal.com/190153.html

[identity profile] zamotivator.livejournal.com 2012-10-11 07:44 pm (UTC)(link)
На Haskell я лично так и не осилил написать банальный hello world, что умеет работать с командной строкой и читать то же самое из конфиг файла и переменных окружения.

Как boost.program_options или python argparse

[identity profile] voidex.livejournal.com 2012-10-11 07:47 pm (UTC)(link)
СУБД писать проще, чем хелловорлды на Haskell?

[identity profile] zamotivator.livejournal.com 2012-10-11 07:48 pm (UTC)(link)
В разы. Там хотя бы понятно, что нужно и откуда ноги растут.
Edited 2012-10-11 19:48 (UTC)

[identity profile] voidex.livejournal.com 2012-10-11 07:50 pm (UTC)(link)
У знакомой мне девушки с хелловорлдом, что умеет работать с командной строкой, на хаскеле проблем с первого же дня не было. Мне кажется это потому, что она кроме хаскеля ничего не видела.

[identity profile] zamotivator.livejournal.com 2012-10-11 07:53 pm (UTC)(link)
Не, ну написать что-то работающее - это немножко не то.
Я хочу написать код, который я понимаю
Каждый раз сажусь, смотрю на этот долбанный IO, иду читать про него, через четыре часа вываливаюсь из дремучих дебрей с мыслями "да пошло оно всё в жопу".

[identity profile] voidex.livejournal.com 2012-10-11 08:42 pm (UTC)(link)
Мне правда интересно, что там сложного?
Я понимаю, может быть сложно, когда пытаешься понять, как же это так, чистота и ввод-вывод, монады какие-то. Ну так это всё равно что таблицы виртуальных функций изучать. Без этого знания можно писать, хотя лучше с ним.

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 20:44 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 01:07 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 01:10 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 01:43 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:27 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-14 11:06 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 06:38 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 08:08 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 08:11 (UTC) - Expand

[identity profile] metaclass.livejournal.com 2012-10-11 07:54 pm (UTC)(link)
В общем, да.
Если задаться целью написать сложносочиненную систему - с базами данных, железом, GUI, веб-сервисами, да еще на нескольких языках c разными библиотеками - то с хаскелем мы упремся в то, что сокращение размера кода алгоритмов за счет лаконичности языка с лихвой компенсируется boilerplate кодом для FFI и прочим взаимодействием с внешним миром.

[identity profile] thesz.livejournal.com 2012-10-11 09:35 pm (UTC)(link)
Я опять потерял мысль где-то в середине, в районе "на нескольких языках".

Почему тогда Хаскель упрётся, а другие языки нет?

[identity profile] metaclass.livejournal.com 2012-10-12 05:03 am (UTC)(link)
Потому что другие языки используют ADO.NET, JDBC и прочие готовые либы и фреймворки.
И починить эти либы можно, не выходя из обычных способов работы с языком.
На хаскеле сразу втыкаешься в hackage и то, что авторы либ их поддерживают от случая к случаю.
А попытка починить самостоятельно втыкается в то, что у каждого автора свой стиль использования языка, а уж если там оптимизация производительности имеется - то закапывать лучше сразу.

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 11:32 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 11:42 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 11:47 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 11:56 (UTC) - Expand

[identity profile] metaclass.livejournal.com 2012-10-11 07:51 pm (UTC)(link)
Да, тут от входа начинается - "найди наиболее зрелую библиотеку на hackage, выясни в каком стиле автор любит обрабатывать ошибки и с какой стороны вставлять IO".

[identity profile] zamotivator.livejournal.com 2012-10-11 07:54 pm (UTC)(link)
Вот именно. В С++ при всех его косяках есть boost, который закрывает собой кроссплатформенную разработку огромного количества стандартных задач.
И буст - ОН ОДИН. Один и хороший.

[identity profile] metaclass.livejournal.com 2012-10-11 07:58 pm (UTC)(link)
Тут есть показатель. Открываешь исходники например boost.filesystem - и понимаешь, что происходит.

Открываешь attoparsec, понимаешь, что его не понимает даже автор, закрываешь и идешь писать конечные автоматы на сишечьке :)

[identity profile] zamotivator.livejournal.com 2012-10-11 07:58 pm (UTC)(link)
Вот это, кстати, офигенный аргумент. Я его как-то упускаю в баталиях с фанатиками haskell.

[identity profile] migmit.livejournal.com 2012-10-15 07:26 am (UTC)(link)
Эм... Ну вот, я писал на днях одну приблуду для просмотра неких специфических дампов памяти. Раньше я парсинг бинарных данных не делал, но слышал краем уха, что для этого есть attoparsec. Скабалил его, покурил пять минут доку. После этого взял и написал. Оно заработало сразу, за вычетом одного косяка, который я поправил ещё за пять минут курения доки.

[identity profile] voidex.livejournal.com 2012-10-12 01:18 am (UTC)(link)
А что, в Haskell при всех его достоинствах огромное количество стандартных задач нельзя решить кроссплатформенно?

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 06:39 (UTC) - Expand

(Anonymous) 2012-10-11 08:40 pm (UTC)(link)
Это делается не просто, а очень просто. Простеньким гуглением, просто не надо лениться.

defaultOptions = Options
{ optVerbose = False
, optShowVersion = False
, optTargetLang = "python2"
, optMinify = False
}

options :: [OptDescr (Options -> Options)]
options =
[ Option ['v'] ["verbose"]
(NoArg (\o -> o { optVerbose = True }))
"verbose output (default false)"
, Option ['V'] ["version"]
(NoArg (\o -> o { optShowVersion = True }))
"show version number (default false)"
, Option ['t'] ["type"]
(ReqArg (\t o -> o { optTargetLang = t }) "LANG")
"target language"
, Option ['m'] ["minify"]
(NoArg (\o -> o { optMinify = True }))
"minify files during processing (default false)"
]

getOptions :: [String] -> IO (Options, [String])
getOptions args =
case getOpt Permute options args of
(o, n, []) -> return (foldl (flip id) defaultOptions o, n)
(o, [], _) -> ioError $ userError $ "No input files.\n" ++ usageInfo header options
(_, _, errs) -> ioError $ userError $ concat errs ++ usageInfo header options
where header = "Usage: program [OPTIONS...] FILES..."


main :: IO ()
main = do
args <- getArgs
res <- try $ getOptions args
case res of
...

Твоя лень не делает хаскель непригодным.

[identity profile] metaclass.livejournal.com 2012-10-12 04:55 am (UTC)(link)
Да, эта либа наиболее адекватная из всех - я ее тоже использовал.

[identity profile] zw0rk.blogspot.nl (from livejournal.com) 2012-10-11 08:45 pm (UTC)(link)
Анонимус это я, почему-то пускает по OpenID через раз.

[identity profile] zamotivator.livejournal.com 2012-10-11 08:46 pm (UTC)(link)
отвечаю на ваш вопрос - вот у вас там есть $ и IO ()
Выглядит это просто, а вот если разбираться начать - там происходит ёбанное вуду и магия, которую я понять до сих пор так и не смог до конца

[identity profile] zw0rk.blogspot.nl (from livejournal.com) 2012-10-11 08:48 pm (UTC)(link)
Для меня 80% кода на C++, особенно на Qt++, выглядит как "ёбаное вуду и магия" и что теперь?

[identity profile] zamotivator.livejournal.com 2012-10-11 08:57 pm (UTC)(link)
Ну, поскольку на С++ вакансий дофига, а на haskell почти нет - ну вы понели, да?

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 20:59 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:00 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 21:03 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:04 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 21:06 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:13 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 21:18 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:21 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 21:23 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:27 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:25 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:29 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:31 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:34 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:36 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:40 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:45 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:50 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:56 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:08 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 23:11 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:12 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:13 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:16 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 22:52 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:53 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 22:55 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:01 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 23:10 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:17 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 23:20 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:24 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 23:50 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:55 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:03 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:08 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:17 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:19 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:22 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:23 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:29 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:39 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 00:40 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:39 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 00:40 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 00:47 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 09:21 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:23 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 11:41 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-13 15:19 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 01:07 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 01:10 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-15 14:07 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 14:47 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-15 20:13 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 21:06 (UTC) - Expand

(no subject)

(Anonymous) - 2012-10-15 22:04 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 23:19 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-15 23:20 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 23:54 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-10-15 07:30 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:12 (UTC) - Expand

(no subject)

[identity profile] nivanych.livejournal.com - 2012-10-12 17:38 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 19:41 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 19:56 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 07:15 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 07:22 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 07:24 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-12 07:28 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 04:59 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 21:31 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:34 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 22:04 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:09 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-11 22:21 (UTC) - Expand

(no subject)

[identity profile] nivanych.livejournal.com - 2012-10-12 17:42 (UTC) - Expand

(no subject)

[identity profile] thesz.livejournal.com - 2012-10-12 19:32 (UTC) - Expand

(no subject)

[identity profile] nivanych.livejournal.com - 2012-10-13 03:26 (UTC) - Expand

(no subject)

[identity profile] nealar.livejournal.com - 2012-10-16 09:21 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:22 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:33 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:40 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:44 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 22:48 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 22:52 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 23:00 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:12 (UTC) - Expand

(no subject)

[identity profile] zw0rk.blogspot.nl - 2012-10-11 23:16 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 23:18 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:20 (UTC) - Expand

(no subject)

[identity profile] metaclass.livejournal.com - 2012-10-12 05:06 (UTC) - Expand

(no subject)

[identity profile] nivanych.livejournal.com - 2012-10-12 17:46 (UTC) - Expand

(no subject)

[identity profile] miserakl.livejournal.com - 2012-10-13 12:33 (UTC) - Expand

(no subject)

[identity profile] nealar.livejournal.com - 2012-10-12 10:58 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 01:20 (UTC) - Expand

(no subject)

[identity profile] berezovsky.livejournal.com - 2012-10-12 01:30 (UTC) - Expand

(no subject)

[identity profile] voidex.livejournal.com - 2012-10-12 01:56 (UTC) - Expand

(no subject)

[identity profile] kiryl.livejournal.com - 2012-10-11 21:00 (UTC) - Expand

(no subject)

[identity profile] zamotivator.livejournal.com - 2012-10-11 21:01 (UTC) - Expand

(no subject)

[identity profile] migmit.livejournal.com - 2012-10-15 07:35 (UTC) - Expand

[identity profile] max630.livejournal.com 2012-10-12 03:01 am (UTC)(link)
> boost.program_options

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

[identity profile] zamotivator.livejournal.com 2012-10-12 06:39 am (UTC)(link)
Ну неправда же. Мой личный контрпример это опровергает

[identity profile] levgem.livejournal.com 2012-10-12 06:29 pm (UTC)(link)
Не переживай. Я кое как продрался, мне помогли как-то разобраться с монадами и выяснилось, что:
1) на хаскеле пишут с this. Монада — это обертка по скрыванию стейта и вызову на нём методов
2) хаскель медленный. Непредсказуемо медленный из-за ленивости. С предсказуемостью теряется ленивость.