Динамические свойства языка программирования как преимущество — objective-c теория связывание-данных

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд
Загрузка...

Вопрос:


Наверстываю упущенную теорию по парадигмам языков программирования.

В обучающих материалах по ObjC часто встречается восхищение динамичностью языка (динамическое связывание, динамическая типизация…) с указанием на то что многое можно делать в рантайме плюс описание соответствующих трюков. Читая документ со страницы 23 я понимаю что это есть свойство языка, но не преимущество. Предполагаю, что сравнивая со статически типизированными языками все те же трюки выполняются в них с тем же успехом, но не в runtime a в compile-time. Раздел статьи Преимущества (равно как и другие статьи в сети) свет на вопрос для меня не пролил и не дал понять в чем именно преимущество а не просто отличие от парадигмы статической типизации. Прошу просветить и указать в чем именно преимущество динамической типизации над статической.

UPDATE:
Если будут получены объемные ответы на вопрос о природе явления в целом, то с целью оставить тред потомкам я добавлю метки всех языков соответствующих парадигме и уберу акцент на objc из топика.

UPDATE 2:
Получены прекрасные всеобъемлющие ответы, в частности от @VladD. C целью аккумулирования топиком общеобразовательной ценности хотелось бы читать мнение и других участников форума. Заранее благодарен за передачу опыта и знаний!

Автор вопроса: AlexThumb

VladD

Если уж зашла речь о «динамичности языка» вообще, должен отметить, что отдельное понятие «динамического языка» лишено смысла. В основном, когда говорят о «динамическом языке», имеют в виду «язык с динамической системой типов», хотя существуют и другие «динамические» черты языка (первое, что приходит в голову — «динамическая область видимости»).

Итак, что такое «динамическая система типов»? Определения в источниках наподобие Википедии говорят, что разница в том, присваивается ли тип переменной при объявлении (и остаётся ли таким навсегда) либо при присваивании (и меняется с каждым следующим присваиванием). Это, однако, слишком грубое описание существующего положения вещей. Куда честнее и точнее было бы говорить о богатстве системы типов, и о том, насколько полно она отображает семантику предметной области.

Крайний пример — языки типа большинства ассемблеров, в которых существует лишь один тип — числовой. Это соответствует примерам «максимально динамической» системы типов: переменная может содержать число, указатель, структуру из двух байт и т. д.

Примера противоположной крайности — языка, в котором каждый элемент программной семантики описывается отдельным типом — наверное не существует, но старые диалекты Паскаля довольно близки к этому. Полностью последовательным строго типизированным языком был бы язык, в котором, например, была бы невозможна ошибка при взятии квадратного корня из отрицательного числа: в языке был бы определён тип «неотрицательное действительное число», и этот тип был бы типом аргумента корня. (То же для например арксинуса.)

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

В качестве примера рассмотрим javascript. Его переменные, по существу, имеют лишь один тип — переменная 🙂 Вы можете вызвать любую операцию на переменной, вне зависимости от фактического содержимого этой переменной. Для некоторых операций (например, вызов функции) неправильное содержимое переменной вызовет исключение, для некоторых же (например, сложение) операция будет выполнена с результатом, неожиданным для программиста, который не во всех деталях проштудировал спецификацию языка.

Языки наподобие C++ предоставляют более богатую систему типов: вы, например, не сможете «вызвать функцию» по переменной типа int. Таким образом, у операций в C++ гораздо меньше возможностей завершиться аварийно из-за несоответствия типов. Тем не менее, язык предоставляет вам возможность нарушить защиту: оператор приведения типов. Вы можете привести тип строки к типу числа, и попытаться выполнить числовую операцию с полученным значением. Согласно стандарту языка, вы получите неопределённое поведение, то есть, что угодно имеет право произойти. Кроме того, определённые черты слабо типизированных языков есть и в C++: операция сложения между различными арифметическими типами вызывает неявную конверсию операндов к наиболее общему типу.

Язык наподобие C# мог бы казаться ещё более статически типизированным (в нём нету аналога reinterpret_cast, и тип проверяется всегда), но зато в нём есть ключевое слово dynamic, близкое по идеологии к eval. Из особенностей динамических языков, перечисленных в Википедии, C# обладает в той или иной степени всеми, за исключением, пожалуй, макросов.

Где-то посередине по богатству системы типов стоит SQL: в нём есть набор примитивных типов, но нет возможности расширить систему типов, применимо к нуждам пользователя.


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

Литература для дальнейшего чтения: [1], [2], [3], [4].


Преимущества «более динамических» языков:

  • Лучшая выразительность в некоторых сценариях, например, там где программист хочет сказать «я уверен, что этот объект умеет выполнить эту операцию» или «объекты, не умеющие делать это, игнорируются». Для сильнее типизированных языков такая семантика достигается использованием приведения типов или другой разновидностью проверки времени выполнения. Например, в Objective C, насколько я знаю, можно отправить произвольное сообщение произвольному объекту (разновидность duck typing); в C# для этого нужно, чтобы объект поддерживал соответствующий интерфейс, или использование dynamic, то есть откладывание проверки до момента выполнения.
  • Неявная, «плавающая» семантика объектов по сравнению с явно заданными, продуманными и жёстко прописанными типами позволяет легко менять смысл классов и операций при разработке. (Не могу придумать пример для Objective C.) Это увеличивает скорость прототипирования, хотя, возможно, и негативно скажется на качестве кода при длительной разработке проекта. Отсюда распространённое мнение о том, что «динамические» языки лучше подходят для построения proof of concept, а статические — для имплементации.
  • Более удобное общение с популярными нетипизированными или слаботипизированными структурами, такими как XML- и JSON-документы.
  • Ещё один часто забываемый пример динамического свойства языков: виртуальные функции.
  • Преимуществом более динамических языков является более простая диспетчеризация вызовов функций: если у меня определены f(Base, Base), f(Base, Derived), f(Derived, Base) f(Derived, Derived), язык с развитой динамической типизацией сможет автоматически выбрать нужную перегрузку при вызове метода, в то время как другие языки вынуждены пользоваться паттерном наподобие Visitor. Частным случаем диспетчеризации по одному, нулевому аргументу является вызов виртуальной функции.
  • Некоторые языки умеют управлять кодом во время выполнения. Например, в Javascript’е можно переопределить любой метод через прототип, в Objective C можно подменить класс, используя категории (если я не ошибаюсь), в Питоне можно модифицировать поведение методов при помощи аннотаций. Достижение подобных эффектов в не приспособленных для этого языках сопряжено со значительным объёмом кода и нередко требует от пользователей неестественного, неудобного или даже опасного синтаксиса. (Например, оборачивать каждое объявление поля в макрос.)

Суммируя: для понятий, встроенных в систему типов, динамически типизированные языки проигрывают статически типизированным в выразительной силе (пример: в статическом языке легко запретить складывать длину с весом, а в динамическом — нет). Для понятий, не описываемых системой типов, динамические языки выразительнее (пример всем объектам с полем возраст увеличить этот самый возраст на 1: в статических языках требует интерфейса, одинакового имени свойства и одинакового типа свойства).


Многие преимущества, которые традиционно считаются преимуществами динамических языков, на самом деле лишь следствия хорошо организованной среды выполнения (рантайма), и в частности не требуют интерпретации или виртуальной машины. Например, интроспекция/рефлексия есть не вопрос динамичности, а лишь вопрос доступности метаданных во время выполнения, и вполне статичная с точки зрения системы типов Java её реализует. Замыкания, которые в Javascript’е есть чисто динамическая особенность, реализуются статически с полным контролем типизации в Objective C (под именем блоков) и C#. Английская Википедия считает, что динамические черты

… can be emulated in nearly any language of sufficient complexity, but dynamic languages provide direct tools to make use of them.

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

— но я позволю себе частично не согласиться. То, как динамические свойства языка реализованы, может быть сделано при подходящей реализации и в любом другом языке, так что слово «эмуляция» здесь неприменимо: если статический язык «эмулирует» рефлексию при помощи метаданных, что же делает динамический? Итак, мы видим, что граница между статическими и динамическими языками довольно сильно размыта.

Преимущества

  • Минимум дополнительных строк: переменные надо либо просто объявить без указания типа (JavaScript), либо вообще объявлять не нужно (Бейсик) или не обязательно (PHP).
  • Соответственно, упрощается написание простых программ
  • Повышается гибкость языка. Например, только динамический язык может иметь функцию eval(), вычисляющую значение произвольного выражения.
  • Ускоряет работу компилятора — а значит, производственный цикл «написать-проверить».
  • Автоматически даёт языку элементы метапрограммирования и интроспекции.
  • Упрощается работа прикладного программиста с СУБД, которые принципиально возвращают информацию в «динамически типизированном» виде. Поэтому динамические языки ценны, например, для программирования веб-служб.
  • Иногда требуется работать с данными переменного типа. Например, функция поиска подстроки возвращает позицию найденного символа (число) или маркер «не найдено». В PHP этот маркер — булевское false. В статических языках это особая константа (0 в Паскале, std::string::npos в C++).
    Динамическая типизация Википедия

Источник

Вам также может быть интересно:

Переадресация запросов по данным из тела запроса — java nginx spring-mvc
Вопрос: Существует сервис с "кучей" контроллеров. Стоит задача "распилить" данный сервис на микросервисы. Сами микросервисы будут крутится на самостоятельных машинах. Основная проблема в том, что есть ...
Java. Деление в столбик. Съезжает вывод в консоль — java
Вопрос: Кто-нибудь может подсказать почему при делении 1034/15 съезжает вывод в консоль? public class Division { private StringBuffer result = new StringBuffer(); ...
Доступ к cookies другого сайта — javascript
Вопрос: Не знаю, или правильно написал вопрос в заголовке. Вообще вопрос такой. Есть, например виджет коминтариев фб, его можно установить на свой сайт. При заходе, он ...
Не видит загрузочной флешки с Ubuntu — linux windows ubuntu
Вопрос: Решил установить Ubuntu второй ОС. Скачал образ и установил его на флешку. Память для будущей Ubuntu выделил ещё когда устанавливал Windows. Проблема в том, что когда ...
Как устроен Netty? — java async netty
Вопрос: Немного почитал про асинхронные сокеты и про фреймворк Netty, но у меня возник вопрос о том как устроен механизм обработки многочисленных запросов к Netty. ...
Как реализовать правильную связь классов в javascript? — javascript ооп полиморфизм
Вопрос: Теперь в деталях : имеются несколько классов : class RemovedItem { constructor(value, key) { this.value = value; ...
Модификация Observable при помощи дополнительного запроса в сеть — android kotlin rxjava
Вопрос: работаю с Vk.APi и произвожу поиск списка групп. В ответе с API получаю список групп, но проблема в том, что каждая из них не содержит ...
Как загрузить Layout в Activity или View из переменной типа String — android xml activity
Вопрос: Обычно внешний вид Activity или View загружается из файлов типа *.xml, вложенных в папку res/layout проекта. А как сделать, чтобы внешний вид загружался из ...
Как выбрать максимальное значение в столбце? — sql sql-server
Вопрос: У меня есть таблица которая состоит из 2 столбцов OrderID OrderDate ------------------------------- 1021 1976-07-04 00:00:00 2312 ...
Форма TextView XML — android xml
Вопрос: Прошу понять меня правильно: Я не прошу что-то сделать за меня и предоставить готовый код ВОПРОС: Какие атрибуты необходимо использовать, чтобы выполнить такой же вид ...
Отловить закрытие консольной программы — c# console
Вопрос: Есть консольное приложение (C#), мне нужно отловить событие его закрытия. Это может быть и Ctrl+C и нажатие на крестик, вообще любое событие после которого ...
Странное поведение jQuery — jquery
Вопрос: Есть веб-страница, на которой естественно имеются стили и скрипты. При очистке кэша и полной перезагрузке страницы (Ctrl + F5) jQuery неправильно определяет height() и ...
Оверлей для любой программы и игры DirectX в фуллскрине через инжект dll — c# wpf
Вопрос: Всем привет. Хочу сделать универсальный оверлей, который при запуске из консольного приложения будет инжектить dll с самим оверлеем в любую программу, как у стима/дискорда. Про инжект ...
Использование, связка бинов в Java — java netbeans xhtml
Вопрос: У меня есть example.xhtml, я не знаю как правильно его заполнить, так как NetBeans предлагает один вариант, а видео, где все работает, заполняют по-другому.Netbeans: <?xml ...
Удалил rfremix-relese при попытке обновления — linux fedora
Вопрос: Сегодня хотел обновить Руссиан Федора Ремикс (RFRemix) 28->29. dnf upgrade выдал сообщение о конфликте в пакете rfremix-release-2.ххххххх Немного посомневался, но решил что это модуль именно ремикса ...

Оставьте ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *