Каковы преимущества (и недостатки) слабо типизированного языка?

Я большой поклонник PHP, и это, очевидно, очень слабо типизированный язык. Я понимаю, что некоторые из преимуществ включают общую независимость от изменения типов переменных «на лету» и т. Д.

Мне интересны недостатки. Что вы можете получить от строго типизированного языка, такого как C, который вы иначе не можете получить от слабо типизированного, например PHP? Также с настройкой типа (например, double ($ variable)) можно утверждать, что даже слабо типизированный язык может действовать так же, как сильно типизированный.

Так. Слабый тип. Какие преимущества я не включил? Что еще более важно, каковы недостатки?

Приведенное преимущество статической типизации заключается в том, что во время компиляции есть целые классы ошибок, которые не могут достичь времени выполнения. Например, если у вас есть статически типизированный класс или интерфейс как параметр функции, тогда вы чертовски хорошо не собираетесь случайно передавать объект неправильного типа (без явного и неправильного литья, то есть).

Конечно, это не останавливает вас в неправильном объекте правильного типа или реализации интерфейса, где вы дали ему правильные функции, но они делают неправильные вещи. Кроме того, если у вас есть 100% -ный охват кода, скажем, PHP / Python / etc, кто заботится о том, поймаете ли вы ошибку во время компиляции или во время выполнения?

Лично у меня были интересные времена на языках со статической типизацией и веселые времена на языках без. Это редко решает вопрос, так как мне никогда не приходилось выбирать между двумя языками, которые идентичны, чем их типизация, и, как правило, важнее всего беспокоиться. Я нахожу, что, когда я использую статически типизированные языки, я сознательно «опираюсь на компилятор», пытаясь написать код таким образом, что если он ошибочен, он не будет компилироваться. Например, есть определенные рефактории, которые вы можете выполнять, внося изменения в одно место, а затем фиксируя все ошибки компиляции, которые приводят к повторению, до тех пор, пока не будет скомпилирована чистая компиляция. Выполнение одного и того же действия путем запуска полного набора тестов несколько раз может быть не очень практичным. Но для разработчиков IDE нет неслыханной возможности автоматизировать одни и те же рефакторы на других языках или быстро завершить тесты, поэтому речь идет о том, что удобно, а не о том, что возможно.

Люди, которые имеют законную озабоченность по сравнению с удобством и предпочтением стиля кодирования, – это те, кто работает над формальными доказательствами правильности кода. Мое невежественное впечатление заключается в том, что дедукция статического типа может выполнять большую часть (но не все) работы, которую делает явный статический ввод, и сохраняет значительный износ клавиатуры. Поэтому, если статический ввод текста заставляет людей писать код таким образом, чтобы его было легче доказать, то от этого POV может быть что-то от него. Я говорю «если»: я не знаю, и это не так, как если бы большинство людей доказывало свой статически типизированный код.

изменение переменных типов на лету и

Я думаю, что это сомнительная ценность. Всегда так заманчиво делать что-то вроде (Python / Django):

user = request.GET['username'] # do something with the string variable, "user" user = get_object_or_404(User,user) # do something with the User object variable, "user" 

Но действительно, следует ли использовать одно и то же имя для разных вещей внутри функции? Может быть. Возможно нет. «Повторное использование», например, целочисленные переменные для других вещей в статически типизированных языках также не поощряется массово. Желание не думать о кратких, описательных именах переменных, возможно, в 95% случаев не должно отменять желания однозначного кода …

Кстати, обычно слабая типизация означает, что происходят неявные преобразования типов, а сильная типизация означает, что они этого не делают. По этому определению C слабо набирается в отношении арифметических типов, поэтому я предполагаю, что это не то, что вы имеете в виду. Я считаю, что широко распространено мнение о том, что полная сильная типизация – это скорее неприятность, чем помощь, и «полная слабая типизация» (все может быть преобразовано во что-либо еще) на большинстве языков бессмысленна. Поэтому возникает вопрос о том, сколько и какие неявные преобразования можно переносить до того, как ваш код станет слишком сложно понять. См. Также, в C ++, постоянную трудность при принятии решения о том, следует ли реализовать операторы преобразования и неявные конструкторы one-arg.

Слабые и сильные – это загруженные термины. (Вы хотите быть слабым программистом на языке?) Динамические и статические лучше, но я бы предположил, что большинство людей предпочитают быть динамическим программистом, чем статическим. Я бы назвал PHP беспорядочным языком (Thats не загруженный термин;))

PHP:

 garbage_out = garbage_in * 3; // garbage_in was not initialized yet "hello world" + 2; // does this make sense? 

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

Об этом написано много книг. Есть неотъемлемый компромисс; со слабо типизированным языком многие неприятности просто перестают быть. Например, в Python вам никогда не придется беспокоиться о делении float на int ; добавление int в list ; (знаете ли вы, у OCaml есть специальные + .операторы для добавления float s, потому что (+) отправляет int s в int s!); забывая, что переменная может быть нулевой … эти виды задач просто исчезают.

На их место приходит целый ряд новых ошибок времени выполнения: Python's [0]*5 дает, ждут его, [0,0,0,0,0] ! OCaml, за все раздражение сильной типизацией, ловит много ошибок с его компилятором; и именно поэтому это хорошо. Это компромисс.

См. Эту таблицу , показывая результаты оператора PHP == применяемые к парам пустых или других главных значений различных типов, таких как 0 , "0" , « NULL и "" . Оператор некоммутативен, и таблица, по меньшей мере, неинтуитивная. (Не то, чтобы было бы разумно спросить, равнозначна ли строка массиву, но вы можете сделать это на слабо типизированном языке, что является ловушкой, и может ли Turing помочь вам, если язык пытается " помочь тебе.)

Я использую как сильные типизированные (например, Java), так и слабые типизированные (например, JavaScript) языки в течение некоторого времени. Я обнаружил, что удобство слабых типизированных языков отлично подходит для небольших приложений. К сожалению, по мере увеличения размера приложения становится невозможно управлять. Слишком много, чтобы отслеживать в голове, и вам нужно больше начинать в зависимости от вашей IDE и компилятора, или ваша кодировка останавливается. То есть, когда сильные типизированные языки начинают становиться более полезными – приложение очень велико.

Два примера, которые постоянно приводят меня в шок в слабом типизированном JavaScript, – это использование внешних библиотек, которые не были полностью задокументированы и рефакторизованы.

Внешние библиотеки. При работе с строго типизированным языком код из самой библиотеки предоставляет самостоятельную документацию. Когда я создаю переменную типа Person, среда IDE может проверять код и указывать, что есть getFirstName (), getLastName () и getFullName (). В слабых типизированных языках это не так, поскольку переменная может быть чем угодно, иметь любую переменную или функцию и иметь аргументы функции, которые также могут быть любыми (они явно не определены). В результате разработчик должен опираться на документацию, веб-поиск, дискуссионные форумы и их память о прошлых обычаях. Я нахожу, что может потребоваться несколько часов поиска вещей в JavaScript для внешних библиотек, в то время как с Java я просто ударил "." и он отображает все мои варианты с прилагаемой документацией. Когда вы сталкиваетесь с библиотеками, которые не полностью документированы на 100%, это может быть очень неприятно со слабыми типизированными языками. Недавно я обнаружил, что спрашиваю: «Что такое аргумент« сюжет »в функции« draw »?» при использовании jqplot, достаточно хорошо, но не полностью документированной библиотеки JavaScript. Мне пришлось потратить час или два на то, чтобы прорваться через исходный код, прежде чем, наконец, сдаться и найти альтернативное решение.

Рефакторинг. С сильно типизированными языками я могу быстро реорганизовать, просто изменив файл, который мне нужно изменить, а затем исправлю ошибки компилятора. Некоторые инструменты даже реорганизуют вас простым нажатием кнопки. Со слабыми типизированными языками вам необходимо выполнить поиск, а затем заменить с осторожностью, а затем проверить, протестировать, тестировать, а затем проверить еще несколько. Вы редко уверены, что нашли и исправили все, что сломали, особенно в крупных приложениях.

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

Я думаю, что многие разработчики расстраиваются из-за этого и превращают его в эмоциональную дискуссию, потому что мы иногда понимаем, что есть один правильный и неправильный подход. Но каждый подход имеет свои достоинства – свои преимущества и недостатки. Как только вы узнаете, что вы отбросили эмоции и выберите лучшее для вас, что вам нужно прямо сейчас.

Прямо из Википедии:

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

Это примерно то же самое, что я сказал бы. Однако остерегайтесь относительной двусмысленности этих терминов («сильная типизация» и «слабая типизация»), поскольку неявные преобразования размывают линию.

Источник: http://en.wikipedia.org/wiki/Weak_typing

Вы должны понимать, что PHP создан для контекста веб-приложений. Все в контексте сети – это строка. Поэтому это очень редко, когда сильный ввод текста будет полезен.