Про динамическую типизацию
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 01:33 pm (UTC)- для программистов которые нынче юзают JS как раньше ассемблер (корявая но тем не менее везде работающая платформа код для которой лучше генерить а не писАть ручками)
- для программистов которые лабают формочки на PHP и которым всё что нужно от скриптового языка - это отфильтровать ввод по регэкспу, сравнить что инт в пределах от сель до сель и т.п.
?
это как бы 2 разных варианта использования, и JS худо-бедно их удовлетворяет.
Сам я тикль не трогал даже издалека палочкой, отзывы слышал не очень приятные - интересно чем он мог быть лучше.
no subject
Date: 2012-10-11 01:53 pm (UTC)Tcl не имеет наследования внутри. Вы работаете с объектами, но не с иерархией.
Посмотрите на виджеты Tk. Это объекты, но не в иерархии. От них также нельзя унаследовать.
Таким образом, одной головной болью меньше.
Второе, в тикле "всё - строка". Поэтому для вычисления булевских значений вам надо использовать expr для чисел или булевские операции над объектами (string equal $a $b), где вы явно задаёте выполняемую операцию.
То есть, проблем с typeof и неявными преобразованиями значений не будет.
Нет замыканий, да. Но асинхронная работа используется в тикле спокон веков, см. fileevent. Это используется для серверов и прочего. Наработаны средства для работы, всё такое.
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, но безопасней.
no subject
Date: 2012-10-11 02:28 pm (UTC)no subject
Date: 2012-10-11 07:17 pm (UTC)Как создаётся, например, виджет. Вы вызываете команду label с параметрами, одним из параметров будет "путь" до виджета. "label .окно.моя_надпись". Вам возвращается имя команды (строка), связанная с объектом "моя_надпись" в объекте "окно". Сам объект-команда хранит некую информацию о своём содержимом, это содержимое присоединяется к команде в процессе её создания и автоматически передаётся в Сишный код.
Виджеты также могут искать себя по пути и тп. То есть, интерпретатор хранит некое общее для всех виджетов хранилище, куда можно обращаться.
Можно заводить несколько интерпретаторов, и ограничивать их в правах - interp -safe. Таким образом, сделать разбор TCLSON'а (если бы такой был) можно через eval - никаких рисков.
Если я всё правильно помню, если вы заведёте несколько интерпретаторов в разных нитях, то вы сможете создать несколько корневых окон (с именем "."). По-моему, у меня так и получилось однажды случайно.
Что интересней, если ваш сишный код умеет работать с несколькими интерпретаторами, вы умеете работать с несколькими нитями, ваша программа автоматически становится параллельной. Никаких GIL.
if - команда Tcl. Первым параметром идёт выражение, вычисляющее булево значение. Да, в качестве выражения может быть просто строка "yes" и ветвь "тогда" будет всегда выполняться. Можно использовать == для сравнения строк, но уже сложить строку и число вам не удастся. "yes" + 1 не будет равно 2. И да, для сравнения строк есть команда string equal $a $b (string compare и тп).
Практика применения тикля показывает, что никаких приведений типов нет. Если вам нужно проверить размеры виджета, вы пишете if {[$w configure -width] > 100} { ... }.
И тд, и тп.
Тикль - это правильный скриптовый язык. Он именно что язык-клей и на большее не сильно претендует. "Всё - строка" не так уж и страшно в дизайне тикля. Это не REXX.
no subject
Date: 2012-10-12 10:14 am (UTC)Одно из двух: или "твой" или "Ваш". Я тут один.
И таки неявные приведения тут возможны, 1 + "yes" правильный пример ситуации - через строку булевое к числу не привелось.
Если они не стали практикой, то хочется понять, почему они в тикле не нужны. Наследования нет?