Про динамическую типизацию
Oct. 11th, 2012 01:33 pmПоразжигал немного в комментах у ребе Б. рознь к социальной группе "ленивые авторы языков". Чтобы не излагать свою позицию каждый раз заново, сохраню сюда.
Знаете, некоторые печальные даты надолго остаются в памяти людей: 11 сентября, 17 августа, 1917-й год, 1941-й. К ним стоит добавить 1995-й - год появления JavaScript, PHP, Ruby, ну и Java тоже. Кому-то захотелось по-быстрому добавить динамизма в веб-странички, и он за пару недель наговнякал интерпретатор, встроив его в браузер Netscape. Кому-то захотелось оживить свою домашнюю страничку, добавить счетчик посетителей, еще что-то, и он на коленке сделал такой вот изменятель страничек на стороне сервера. О больших проектах тогда никто не думал, personal home page назывался тот изменятель. А когда делаешь интерпретатор, проще всего сделать его на динамической типизации. Это банально очень просто. О системе типов вообще можно не задумываться, не говоря уже об их выводе. К сожалению, на фоне тогдашнего мейнстрима (Си, ранние плюсы, что там еще было?) эти скриптовые языки выглядели очень выигрышно, писать мелкие куски кода на них было намного проще. Что такое нормальная система типов тогда мало кто знал: хаскель был еще в пеленках, ML'и традиционно не выходили из университетов. Так что люди эти скрипты подхватили, стали добавлять все новые функции. Менять систему типов стало поздно. В итоге выросло то, что выросло. С тех пор одна масса людей занята тем, чтобы делать все более сложные интерпретаторы, которые бы не так тормозили, другая масса придумывает 121-й способ добавить в JS типы, а третья на динамических языках пишет и плачет в бложиках о том, как грустно им делается. И проблема не только и не столько в скорости, сколько в maintainability кода и усилиях на необходимые тестирование и отладку при росте проектов.
Единственная реальная причина появления динамически типизированных языков - лень и недальновидность авторов. Эволюционно динамические языки - тупиковая ветвь, хоть они и обречены рождаться вновь и вновь просто потому что их делать проще, а делать языки люди любят. Сегодняшняя популярность некоторых из них - случайность, исторический казус, следствие контраста между этими языками и мейнстримом начала 90-х. То, что много идиотов используют идиотские языки, говорит лишь о том, что идиотов много. Сегодня, когда есть языки с нормальной статической системой типов, никаких реальных преимуществ у динамической больше нет. Только я имею в виду действительно нормальные статически типизированные языки - как минимум с параметрическим и ad hoc полиморфизмами, с выводом типов. Не Си с джавой. Хаскель, окамл, скала - такого уровня. У этих конкретных языков могут быть свои проблемы, часто инфраструктурные, но речь сейчас не о них, речь о динамической vs. статической типизации в целом.
Знаете, некоторые печальные даты надолго остаются в памяти людей: 11 сентября, 17 августа, 1917-й год, 1941-й. К ним стоит добавить 1995-й - год появления JavaScript, PHP, Ruby, ну и Java тоже. Кому-то захотелось по-быстрому добавить динамизма в веб-странички, и он за пару недель наговнякал интерпретатор, встроив его в браузер Netscape. Кому-то захотелось оживить свою домашнюю страничку, добавить счетчик посетителей, еще что-то, и он на коленке сделал такой вот изменятель страничек на стороне сервера. О больших проектах тогда никто не думал, personal home page назывался тот изменятель. А когда делаешь интерпретатор, проще всего сделать его на динамической типизации. Это банально очень просто. О системе типов вообще можно не задумываться, не говоря уже об их выводе. К сожалению, на фоне тогдашнего мейнстрима (Си, ранние плюсы, что там еще было?) эти скриптовые языки выглядели очень выигрышно, писать мелкие куски кода на них было намного проще. Что такое нормальная система типов тогда мало кто знал: хаскель был еще в пеленках, ML'и традиционно не выходили из университетов. Так что люди эти скрипты подхватили, стали добавлять все новые функции. Менять систему типов стало поздно. В итоге выросло то, что выросло. С тех пор одна масса людей занята тем, чтобы делать все более сложные интерпретаторы, которые бы не так тормозили, другая масса придумывает 121-й способ добавить в JS типы, а третья на динамических языках пишет и плачет в бложиках о том, как грустно им делается. И проблема не только и не столько в скорости, сколько в maintainability кода и усилиях на необходимые тестирование и отладку при росте проектов.
Единственная реальная причина появления динамически типизированных языков - лень и недальновидность авторов. Эволюционно динамические языки - тупиковая ветвь, хоть они и обречены рождаться вновь и вновь просто потому что их делать проще, а делать языки люди любят. Сегодняшняя популярность некоторых из них - случайность, исторический казус, следствие контраста между этими языками и мейнстримом начала 90-х. То, что много идиотов используют идиотские языки, говорит лишь о том, что идиотов много. Сегодня, когда есть языки с нормальной статической системой типов, никаких реальных преимуществ у динамической больше нет. Только я имею в виду действительно нормальные статически типизированные языки - как минимум с параметрическим и ad hoc полиморфизмами, с выводом типов. Не Си с джавой. Хаскель, окамл, скала - такого уровня. У этих конкретных языков могут быть свои проблемы, часто инфраструктурные, но речь сейчас не о них, речь о динамической vs. статической типизации в целом.
no subject
Date: 2012-10-11 02:00 pm (UTC)На первый взгляд не сильно многообещающе :)
Заменили бы JS где наследование до сих пор непривычно для ООП-программистов на язык без наследования вообще - ну, были бы другие матюки в форумах - но вряд ли бы меньше ;)
А решать проблемы с неявным преобразованием типов полным отсутствием типов (это если я правильно понял "всё-строка") - это как-то уж больно по-Соломоновски ;)
no subject
Date: 2012-10-11 02:24 pm (UTC)В тикле нет наследования вне предметной области. То есть, виджеты, например, образуют (условную) "иерархию", но и всё. Самостоятельно сделать виджеты можно, хотя и затруднительно, надо много знать.
Поэтому вместо своих собственных объектов народ работал бы с dict (аналог JSON структуры). И вместо eval (дыра в безопасности) использовал бы "dict read $string" (нет дыры в безопасности).
То есть, тикль - идеальный язык-клей. Пишите на нём высокоуровневую логику предметной области, не низкий уровень типа виджетов или DOM структур.
Ну, и мой любимый пример. Когда мы писали на тикле, каждый программист имел не менее одного EDSL. И что самое приятное, от этого была выгода. ;)
no subject
Date: 2012-10-11 02:30 pm (UTC)но поинт в использовании тикля я вроде бы понял - делаем "скромненько, но чисто", лишних возможностей не даём и лишних поводов для ошибок тоже. А как у тикля со скоростью дела? Всё-таки для JS сделали V8+аналоги что дало ему весьма неплохую производительность и позволило сделать его "ассемблером для веба". А я сильно сомневаюсь что в подходе "всё-строка" есть много вариантов для оптимизаций по скорости.
no subject
Date: 2012-10-11 03:30 pm (UTC)Не расскажите как даты json-ом передают?
no subject
Date: 2012-10-11 03:52 pm (UTC)Number (double precision floating-point format in JavaScript, generally depends on implementation)
String (double-quoted Unicode, with backslash escaping)
Boolean (true or false)
Array (an ordered sequence of values, comma-separated and enclosed in square brackets; the values do not need to be of the same type)
Object (an unordered collection of key:value pairs with the ':' character separating the key and the value, comma-separated and enclosed in curly braces; the keys must be strings and should be distinct from each other)
null (empty)
про даты ничего нет :)
т.е. насколько я понимаю - стандартного пути нет (могу приврать, я вообще-то по JSON-у не самый большой специалист)
А нестандартных - начиная от того что передаём getMilliseconds() + timezone - и заканчивая тем что юзаем Date.toString
no subject
Date: 2012-10-11 04:27 pm (UTC)> А нестандартных
И как вы себе это представляете? Как предлагаете строку конвертировать в дату?
Вообще самое нормальное решение пока есть у Microsoft (кто бы сомневался ;). Даты передавать как строку /Date(unixtime)/, валидировать, а потом простым регекспом изменить на new Date () и в eval.
no subject
Date: 2012-10-11 04:36 pm (UTC)ну т.е. мы своими руками пробили дырищу в безопасности, ага...
отличный способ, нечего сказать.
PS: а кто это из Microsoft так делает? Ну т.е. это в каком-то мануале написано, да?
no subject
Date: 2012-10-11 04:51 pm (UTC)о валидации, я так понимаю, вы даже не слышали.
> PS: а кто это из Microsoft так делает? Ну т.е. это в каком-то мануале написано, да?
If I had to pick the best of the bunch from the solutions we currently have that work, I guess it would have to be the Microsoft approach. Whilst it looks rather peculiar and makes use of a strange quirk of the spec, it is probably the best compromise.
http://markembling.info/2011/07/json-date-time
там же ссылки на http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx
Я ж говорю, если б вы занимались чем-то крупнее анимированых менюшек, то со всем этим говном столкнулись бы и не делали такие круглые глаза.
no subject
Date: 2012-10-12 12:09 pm (UTC)Я просил ссылку на Microsoft (эти две ссылки - на блоги людей которые к MS никакого отношения не имеют) в которой было бы написано "используйте eval для парсинга JSON".
вот зашёл я на MSDN:
http://msdn.microsoft.com/en-us/library/12k71sw7(v=vs.94).aspx
вижу
Whenever possible, use the JSON.parse function to de-serialize JavaScript Object Notation (JSON) text. The JSON.parse function is more secure and executes faster than the eval function.
no subject
Date: 2012-10-11 03:58 pm (UTC)я только сейчас понял к чему вопрос
Вы что - парсите JSON eval-ом?
no subject
Date: 2012-10-11 04:34 pm (UTC)no subject
Date: 2012-10-11 06:53 pm (UTC)Для целых чисел и плавающей точки не создаётся строкового представления, если результат вычислений именно целое или плавающая точка. Объект в тикле имеет примерно вот такую внутреннюю структуру:
struct tcl_object { int use_count; byte values_mask; int int_value; char* string_value; double floatingpoint_value; // ...всякая дополнительная информация... };Поэтому вызов "double Tcl_GetFloat(Tcl_Obj*)" не будет делать лишней работы. Как и "char* Tcl_GetString(Tcl_Obj*)". Оба вычислят, запомнят и не будут такое делать дальше. Соответственно, не будет особо большой лишней работы и у вычислений и тп.Было бы желание, можно добиться скорости сравнимой с V8.
И да. Задача тикля - скомпоновать уже готовое, как и у JS, но безопасней.