Entry tags:
Динамическая типизация, или статическая типизация для ленивых
Вчера
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
Это очень важный показатель. Есть спрос - будут программисты - будет кому заменить человека в команде после ухода
> То есть R -- нужен? Потому что его используют. Но ведь у него те же проблемы, что и у хаскелля, нет? Тоже мало кто его знает, тоже понапишут шибко умные, потом сиди разбирайся.
"шибко умные" - это когда файлы сканируются на диске через эндофункторы или нужен гамак с лыжами и монадами для скачки файлов по http.
R сидит хорошо в своей нише - научные вычисления. Линейная алгебра, та же. Люди что берут R они знают, что такое матрицы, и язык ими выбранный адекватен их задаче.
Человек, что пишет простого робота для анализа сайтов для своей мелкой хотелки - ему нафиг не впёрлись эти монады и доллары. Ему нужно РЕШИТЬ ЗАДАЧУ. Вот на Питон это элементарно. Пара запросов в гугль. Этим скачиваем странички. Этим парсим и и ищем нужную нам инфу. А вот так складываем результат в файлик. Всё просто и понятно.
> Не надо мне объяснять что такое эрланг и с чем его едят. Вообще, зачем от темы уходить? По вашей логике получается, что эрланг тоже не нужен, как и R, по тем же причинам.
Как же с Хаскелл-фанатиками туго-то, а. Речь идёт не про то, лучше ищи хуже язык. Речь идёт про адекватность языка поставленным задачам и риски компании связанные с его использованием.
> На этот вопрос я вам не отвечу, я хаскель использую редко.
Нишы Ерланга и R я описал. Могу и нишу Питона описать - это скриптовый язык, что работает везде, и оптимально годится для автоматизации мелких рутинных задач.
Лучше чем shell.
no subject
Опять двадцатьпять. Мы уже это обсуждали. Это вопрос менеджмента -- ну вот выживают конторы сумасшедших хаскелефилов, стало быть находят они специалистов. Не иначе как без вмешательства сатаны не обходиться.
> "шибко умные" - это когда файлы сканируются на диске через эндофункторы или нужен гамак с лыжами и монадами для скачки файлов по http.
Шибко умные, это когда зачем-то свои матрицы и детерминанты тащат в СЛУ. Ведь любому дураку понятно, что можно решить простым перебором. Тоже ведь подход? И найти таких решателей на рынке еще проще, чем тех, кто знает про алгебру что-то?
> Человек, что пишет простого робота для анализа сайтов для своей мелкой хотелки - ему нафиг не впёрлись эти монады и доллары. Ему нужно РЕШИТЬ ЗАДАЧУ. Вот на Питон это элементарно. Пара запросов в гугль. Этим скачиваем странички. Этим парсим и и ищем нужную нам инфу. А вот так складываем результат в файлик. Всё просто и понятно.
Ну порадуемся за человека. А другой пишет "на эндофункторах" и у него тоже задача решается. Надо его убить, чтобы не смущал?
> Как же с Хаскелл-фанатиками туго-то, а. Речь идёт не про то, лучше ищи хуже язык. Речь идёт про адекватность языка поставленным задачам и риски компании связанные с его использованием.
Ну вот я уже и фанатик. Я привёл уже довод о законах рынка и хаскель/скала/whatever-конторах. Ну разбейте этот довод, раз я фанатик.
no subject
Либо они работают за такие деньги, на которые нормальных специалистов на других языках не наймёшь. Это называется "демпинг" и говорит не в пользу Haskell.
> Шибко умные, это когда зачем-то свои матрицы и детерминанты тащат в СЛУ. Ведь любому дураку понятно, что можно решить простым перебором. Тоже ведь подход? И найти таких решателей на рынке еще проще, чем тех, кто знает про алгебру что-то?
Никому "СЛУ" работе решать не нужно. Людям нужно решать задачи, то поставил менеджмент.
Один знакомый не так давно пришёл тимлидом в проект по написанию систему рекомендаций.
Почитал что и как делают в machine learning, почесал репу, взял Java + Hadoop, вспомнил матрицы, заколбасил решение, работает. СЛУ в процессе тоже решать приходилось. Только это детали реализации, особенности алгоритмов такие, что их удобней делать через СЛУ и линейную алгебру.
Для скачивания файла по http не нужно знать всякого дерьма типа монад.
Правильное решение задачи выглядит так:
import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
И что, сука, характерно, будет работать на любом линуксе сразу, без всяких приседаний. запихивается в script.
Не нужно решать квест "как скачать haskell", квест "какую лтбу взять" и квест "как мне пофильтровать из скачанного файла через монады бесплатно без смс" когда приспичит.
> Ну порадуемся за человека. А другой пишет "на эндофункторах" и у него тоже задача решается. Надо его убить, чтобы не смущал?
Если он это притащил в рабочий проект без чёткого письменного обоснования почему это нужно и подписей менеджмента - то это попахивает саботажем, с моей точки зрения.
Вообще говоря, любые свои решения в проекте нужно обосновывать. Не абстрактными "эффективность выше", а конкретикой - вот линейная алгебра нужна, потому что через неё существенно проще описывать рекомендации и веса, алгоритм линейной регрессии через неё работает - другими способами решать сложней.
Понимаете? Когда ДРУГИЕ РЕШЕНИЯ - СЛОЖНЕЕ.
no subject
Нет, не на любом.
no subject
no subject
desktop или сервер версию. embedded - там другие линуксы, там не только haskell, но и python не пахнет.
no subject
Вопросы начнутся, когда потребуется чтобы при плохо работающем DNS и тормозящем сайте можно было прервать скачивание кнопочкой с GUI и чтобы при этом в лог были записаны ошибки, а в программе не было утечек хендлов. И чтобы это было оформлено в DLL, которую руками грузят и выгружают из какой-нибудь 1C.
Если что - хаскель рантайм под виндой не умеет работать после однократной переинициализации извне. Там статические переменные. Не очищаются инициализацией/деинициализацией, да :)