Каковы преимущества (и недостатки) слабо типизированного языка?
Я большой поклонник PHP, и это, очевидно, очень слабо типизированный язык. Я понимаю, что некоторые из преимуществ включают общую независимость изменения переменных типов на лету и т.д.
Мне интересны недостатки. Что вы можете получить от строго типизированного языка, такого как C, который вы иначе не можете получить от слабо типизированного, например PHP? Также с настройкой типа (например, double ($ variable)) можно утверждать, что даже слабо типизированный язык может действовать так же, как сильно типизированный.
Итак. Слабый тип. Какие преимущества я не включил? Что еще более важно, каковы недостатки?
Ответы
Ответ 1
Приведенное преимущество статической типизации заключается в том, что во время компиляции есть целые классы ошибок, которые не могут достичь времени выполнения. Например, если у вас есть статически типизированный класс или интерфейс в качестве параметра функции, тогда вы чертовски хорошо не собираетесь случайно передавать объект неправильного типа (без явного и неправильного литья, то есть).
Конечно, это не останавливает вас в неправильном объекте правильного типа или реализации интерфейса, где вы дали ему правильные функции, но они делают неправильные вещи. Кроме того, если у вас есть 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% случаев не должно отменять желания однозначного кода...
Btw, обычно слабое типирование означает, что происходят неявные преобразования типов, а сильная типизация означает, что они этого не делают. По этому определению C слабо типизируется по отношению к арифметическим типам, поэтому я предполагаю, что вы не имеете в виду. Я считаю, что широко распространено мнение о том, что полная сильная типизация - скорее неприятность, чем помощь, и "полная слабая типизация" (все может быть преобразовано во что-либо еще) на большинстве языков бессмысленно. Поэтому возникает вопрос о том, сколько и какие неявные преобразования можно переносить до того, как ваш код станет слишком сложно понять. См. Также, в С++, постоянную трудность в решении о том, следует ли реализовать операторы преобразования и неявные конструкторы с одним аргументом.
Ответ 2
Слабые и сильные - это загруженные термины. (Вы хотите быть слабым программистом на языке?) Динамические и статические лучше, но я бы предположил, что большинство людей предпочитают быть динамическим программистом, чем статическим. Я бы назвал PHP беспорядочным языком (Thats не загруженный термин;))
PHP:
garbage_out = garbage_in * 3; // garbage_in was not initialized yet
"hello world" + 2; // does this make sense?
Разрешение неинициализированных переменных очень затрудняет поиск ошибок в орфографических ошибках. Разрешение операций с несвязанными типами также почти всегда является ошибкой, о которой следует сообщить. Большинство интерпретируемых динамических языков не позволяют эти вещи по уважительной причине. Вы можете иметь динамически типизированный язык, не разрешая мусор.
Ответ 3
Много книг написано об этом. Там присущий компромисс; со слабо типизированным языком многие неприятности просто перестают быть. Например, в Python вам никогда не придется беспокоиться о делении a float
на int
; добавление аргументов int
to list
; для ввода символов (вы знаете, у OCaml есть специальные+. операторы для добавления float
, потому что (+)
отправляет int
в int
s!); забывая, что переменная может быть нулевой... эти виды задач просто исчезают.
В их место входит целый ряд новых ошибок времени выполнения: Python [0]*5
дает, ждет его, [0,0,0,0,0]
! OCaml, за все раздражение сильной типизацией, ловит много ошибок с его компилятором; и именно поэтому это хорошо. Это компромисс.
Ответ 4
Смотрите эту таблицу, показывая результаты оператора PHP ==
, применяемого к парам пустых или других основных значений различных типов, таких как 0
, "0"
, NULL
и ""
. Оператор некоммутативен, и таблица, по меньшей мере, неинтуитивная. (Не то, чтобы было бы разумно спросить, равнозначна ли строка массиву, но вы можете сделать это на слабо типизированном языке, что является ловушкой, и может ли Turing помочь вам, если язык пытается "помогите" вам.)
Ответ 5
Я использую как сильные типизированные (например, Java), так и слабо типизированные (например, JavaScript) языки в течение некоторого времени. Я обнаружил, что удобство слабых типизированных языков отлично подходит для небольших приложений. К сожалению, по мере увеличения размера приложения становится невозможно управлять. Слишком много, чтобы отслеживать в голове, и вам нужно больше начинать в зависимости от вашей IDE и компилятора, или ваша кодировка останавливается. То есть, когда сильные типизированные языки начинают становиться более полезными - приложение очень велико.
Два примера, которые постоянно приводят меня в шок в слабом типизированном JavaScript, используют внешние библиотеки, которые не полностью документированы и рефакторизуются.
Внешние библиотеки. При работе с строго типизированным языком код из самой библиотеки обеспечивает самостоятельную документацию. Когда я создаю переменную типа Person, среда IDE может проверять код и указывать, что есть getFirstName(), getLastName() и getFullName(). В слабых типизированных языках это не так, поскольку переменная может быть чем угодно, иметь любую переменную или функцию и иметь аргументы функции, которые также могут быть любыми (они явно не определены). В результате разработчик должен опираться на документацию, веб-поиск, дискуссионные форумы и их память о прошлых обычаях. Я нахожу, что может потребоваться несколько часов поиска вещей в JavaScript для внешних библиотек, в то время как с Java я просто нажал кнопку ".". и он отображает все мои варианты с прилагаемой документацией. Когда вы сталкиваетесь с библиотеками, которые не полностью документированы на 100%, это может быть очень неприятно со слабыми типизированными языками. Недавно я обнаружил, что спрашиваю: "Что такое аргумент" сюжет "в функции" draw "?" при использовании jqplot, достаточно хорошо, но не полностью документированной библиотеки JavaScript. Мне пришлось потратить час или два, пробираясь через исходный код, прежде чем, наконец, сдаться и найти альтернативное решение.
Рефакторинг: с сильно типизированными языками я могу быстро реорганизовать, просто изменив файл, который мне нужно изменить, а затем исправлю ошибки компилятора. Некоторые инструменты даже реорганизуют вас простым нажатием кнопки. Со слабыми типизированными языками вам необходимо выполнить поиск, а затем заменить с осторожностью, а затем проверить, протестировать, тестировать, а затем проверить еще несколько. Вы редко уверены, что нашли и исправили все, что вы нарушили, особенно в больших приложениях.
Для простых потребностей и небольших приложений эти две проблемы минимальны и не существуют. Но если вы работаете с приложением со 100 тысячами или миллионами строк кода, слабые типизированные языки будут приводить вас в бешенство.
Я думаю, что многие разработчики расстраиваются из-за этого и превращают его в эмоциональную дискуссию, потому что мы иногда понимаем, что есть один правильный и неправильный подход. Но каждый подход имеет свои достоинства - свои преимущества и недостатки. Как только вы узнаете, что вы отложили эмоцию и выберите лучшее для вас за то, что вам нужно прямо сейчас.
Ответ 6
Прямо из Википедии:
Преимущество, заявленное в отношении слабого набора текста заключается в том, что он требует меньше усилий для часть программиста, чем сильная набрав, поскольку компилятор или интерпретатор неявно выполняет определенные виды конверсий. Однако, одним из заявленных недостатков является то, что слабоспециализированные системы программирования меньше ошибок во время компиляции, а некоторые из них все еще могут остаться после тестирование завершено.
Это примерно то же самое, что я сказал бы. Однако остерегайтесь относительной двусмысленности этих терминов ( "сильная типизация" и "слабая типизация" ), поскольку неявные преобразования размывают линию.
Источник: http://en.wikipedia.org/wiki/Weak_typing
Ответ 7
Вы должны понимать, что PHP создан для контекста веб-приложений. Все в контексте сети - это строка. Поэтому это очень редко, когда сильная типизация была бы полезной.