Вчера
ivan_gandhi сделал замечание что я, пользуясь динамически типизированной кложурью, при этом требую, чтобы в Java проверяли входные параметры на валидность. (Если что, проверка валидности в дотнете есть на каждом шагу, а объяснения вида "экономят циклы и не делаю проверки" в контексте жабы, тяжелого железа, JIT и прочего звучат крайне странно).
Собирался на эту тему устроить срач с утра, но
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
Собирался на эту тему устроить срач с утра, но
Так вот, динамически типизированными языками мы пользуемся от бедности - нету статически типизированных языков, которые давали бы ту же функциональность.
Например, я хочу использовать кортеж с именованными полями (потому что позиционные кортежи нихера нечитабельны и их тип вида 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
no subject
Date: 2012-10-11 07:32 pm (UTC)no subject
Date: 2012-10-11 07:39 pm (UTC)В принципе, мой комментарий к посту и был призывом раскрыть карты. Он проигнорирован, и это не значит, что я должен что-то делать. Ровно наоборот.
Ощущаемые мной проблемы автора пусть остаются его проблемами. Может, мне только кажется, что это проблемы. Может, так ему легче жить. Быть может, это конкурентное преимущество.
У меня есть забота протестировать, как Хаскель разбирает регекспы на скорости в 1,25ГБайт/сек. Укладываемся ли мы в указанный диапазон. Вот это на самом деле интересно.
no subject
Date: 2012-10-11 08:58 pm (UTC)По сути - просто высказали своё оценочное суждение.
Призыв открыть карты я не видел.
no subject
Date: 2012-10-11 09:08 pm (UTC)Но теперь-то уж всем понятно, что я хотел услышать.
no subject
Date: 2012-10-11 09:13 pm (UTC)no subject
Date: 2012-10-11 09:37 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-11 11:25 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-11 07:42 pm (UTC)На кложуре это можно сделать за пару дней, видя ее в первый раз.
no subject
Date: 2012-10-11 07:44 pm (UTC)Как boost.program_options или python argparse
no subject
Date: 2012-10-11 07:47 pm (UTC)no subject
Date: 2012-10-11 07:48 pm (UTC)no subject
Date: 2012-10-11 07:50 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-11 07:54 pm (UTC)Если задаться целью написать сложносочиненную систему - с базами данных, железом, GUI, веб-сервисами, да еще на нескольких языках c разными библиотеками - то с хаскелем мы упремся в то, что сокращение размера кода алгоритмов за счет лаконичности языка с лихвой компенсируется boilerplate кодом для FFI и прочим взаимодействием с внешним миром.
no subject
Date: 2012-10-11 09:35 pm (UTC)Почему тогда Хаскель упрётся, а другие языки нет?
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-11 07:51 pm (UTC)no subject
Date: 2012-10-11 07:54 pm (UTC)И буст - ОН ОДИН. Один и хороший.
no subject
Date: 2012-10-11 07:58 pm (UTC)Открываешь attoparsec, понимаешь, что его не понимает даже автор, закрываешь и идешь писать конечные автоматы на сишечьке :)
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-11 08:40 pm (UTC)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
...
Твоя лень не делает хаскель непригодным.
no subject
Date: 2012-10-12 04:55 am (UTC)no subject
Date: 2012-10-11 08:45 pm (UTC)no subject
Date: 2012-10-11 08:46 pm (UTC)Выглядит это просто, а вот если разбираться начать - там происходит ёбанное вуду и магия, которую я понять до сих пор так и не смог до конца
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From: (Anonymous) - Date: 2012-10-13 03:19 pm (UTC) - Expand(no subject)
From:(no subject)
From:(no subject)
From: (Anonymous) - Date: 2012-10-15 02:07 pm (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2012-10-15 08:13 pm (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2012-10-15 10:04 pm (UTC) - Expand(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2012-10-12 03:01 am (UTC)это плохой пример. только чтобы прочитать документацию по ней и понять из неё что же там будет происходить нужно больше времени чем написать свой разборщик опций для хаскеля
no subject
Date: 2012-10-12 06:39 am (UTC)no subject
Date: 2012-10-12 06:29 pm (UTC)1) на хаскеле пишут с this. Монада — это обертка по скрыванию стейта и вызову на нём методов
2) хаскель медленный. Непредсказуемо медленный из-за ленивости. С предсказуемостью теряется ленивость.
no subject
Date: 2012-10-11 08:37 pm (UTC)Человек не знакомый с лиспами вообще врядли тоже что-то напишет на кложуре за пару дней. Тем более, что с "пакетами" у кложуры всё гораздо хуже, чем у хаскеля :)