Дайка печатается, должно быть, она динамична?

Википедия говорила * о утка-типизация:

В компьютерном программировании с объектно-ориентированные языки программирования, утиная типизация - стиль динамического ввод, в котором текущий объект набор методов и свойств определяет действительную семантику, а чем его наследование от конкретного класса или реализации конкретного интерфейс.

(* Примечание: Поскольку этот вопрос был опубликован, статья Википедии была отредактирована для удаления слова "динамический".)

В нем описывается структурная типизация:

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

Это контрастирует структурный подтипирование с утиным типом:

[Структурные системы] контрастирует с... утка, в которой только часть структуры, доступ к которой время выполнения проверяется на совместимость.

Однако термин "утка-типизация" мне кажется, по крайней мере, для интуитивного подбора структурных систем подпечатывания. Фактически Wikipedia говорит:

Название понятия [утка-типизация] ссылается на утиный тест, приписываемый Джеймс Уиткомб Райли, который может быть сформулирован как следует: "Когда я вижу птицу, которая ходит как утка, и плавает, как утка и кляки, как утка, я называю эту птицу утка".

Итак, мой вопрос: почему я не могу назвать структурный подтипирование утиной печати? Существуют ли даже динамически типизированные языки, которые также нельзя отнести к типу?

Постскриптум:

Как кто-то назвал daydreamdrunk на reddit.com, поэтому красноречиво положить-это "Если он компилируется как утка и ссылки, как утка..."

Пост-постскриптум

Многие ответы, похоже, в основном просто перефразируют то, что я уже цитировал здесь, не обращаясь к более глубокому вопросу, поэтому не следует использовать термин "утиная печать" для покрытия как динамического набора текста, так и структурного подтипа? Если вы хотите только поговорить о наборе утиных, а не о структурном подтипе, просто назовите его: динамический поиск элементов. Моя проблема в том, что ничего не говорит о термине duck-typing, это относится только к динамическим языкам.

Ответ 1

С++ и D-шаблоны - прекрасный пример утиного набора текста, который не является динамическим. Это определенно:

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

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

Ответ 2

Система структурного типа

Система структурного типа сравнивает один полный тип с другим целым типом, чтобы определить, совместимы ли они. Для совместимости двух типов A и B A и B должны иметь одинаковую структуру, то есть каждый метод на A и на B должен иметь одну и ту же подпись.

Duck Typing

Утиная печать считает, что два типа эквивалентны для задачи, если они могут обрабатывать эту задачу. Для двух типов A и B эквивалентны фрагменту кода, который хочет записать в файл, A и B оба должны реализовать метод записи.

Резюме

Системы структурного типа сравнивают каждую сигнатуру метода (целая структура). Утка набирает сравнение методов, относящихся к конкретной задаче (структура, относящаяся к задаче).

Ответ 3

Утиная печать означает Если она просто подходит, она ОК

Это относится как к динамически типизированному

def foo obj
    obj.quak()
end

или статически типизированные, скомпилированные языки

template <typename T>
void foo(T& obj) {
    obj.quak();
}

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

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

Структурно типизированный код (Scala -стиль) для приведенного выше примера будет

def foo(obj : { def quak() : Unit }) {
    obj.quak()
}

Не путайте это с тем, что некоторые структурно типизированные языки, такие как OCaml, объединяют это с выводом типа, чтобы мы не могли явно определять типы.

Ответ 4

Я не уверен, действительно ли он отвечает на ваш вопрос, но...

Шаблонный код на С++ очень похож на утиную печать, но является статическим, время компиляции, структурное.

template<typename T>
struct Test
{
    void op(T& t)
    {
        t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
    }
};

Ответ 5

Я понимаю, что структурная типизация используется указателями типа и т.п. для определения информации о типе (думаю, Haskell или OCaml), в то время как утиная типизация не заботится о "типах" как таковой, просто то, что вещь может обрабатывать конкретную метод invocation/доступ к свойствам и т.д. (подумайте respond_to? в Ruby или проверяйте возможности в Javascript).

Ответ 6

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

var x:Object = new SomeClass();
if ("begin" in x) {
    x.begin();
}

В этом случае мы протестировали, если экземпляр объекта в "x" имеет метод "начать" перед вызовом его вместо использования интерфейса. Это работает в ActionScript и в значительной степени печатается утки, хотя класс SomeClass() не может быть динамическим.

Ответ 7

Существуют ситуации, когда динамическая утиная печать и аналогичный статический код (например, С++) ведут себя по-другому:

template <typename T>
void foo(T& obj) {
    if(obj.isAlive()) {
        obj.quak();
    }
}

В С++ объект должен иметь методы isAlive и quak для компиляции кода; для эквивалентного кода в динамически типизированных языках, объект должен иметь метод quak, если isAlive() возвращает true. Я интерпретирую это как различие между структурой (структурной типизацией) и поведением (утиная печать).

(Тем не менее, я дошел до этой интерпретации, взяв Википедию "утиная печать должна быть динамичной" по номинальной стоимости и пытаться сделать ее понятной. Альтернативная интерпретация, которая подразумевает структурную типизацию, - это утка, набирающая текст также является когерентной.)

Ответ 8

Я вижу "утиную типизацию" больше как стиль программирования, тогда как "структурная типизация" - это системная функция типа.

Структурная типизация относится к способности системы типов выражать типы, которые включают все значения, которые имеют определенные структурные свойства.

Утиная печать относится к написанию кода, который просто использует функции передаваемых им значений, которые действительно необходимы для работы под рукой, без наложения каких-либо других ограничений.

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

Итак, пока я вижу, как существует общая точка зрения, я не думаю, что утиная печать вводит структурную типизацию. То, как я думаю о них, печатание утки - это даже не то, что могло бы привести к структурной типизации, потому что это не то же самое. Думая о том, что утка набирает динамические языки как "неявные, неконтролируемые структурные типы", что-то не хватает, ИМХО. Duck typing - это стиль кодирования, который вы предпочитаете использовать или нет, а не только техническую особенность языка программирования.

Например, можно использовать isinstance проверки в Python для подделки типов типа "класс-подкласс" типа OO. Также можно проверить определенные атрибуты и методы, подделать структурные ограничения типа (вы даже можете поместить проверки во внешнюю функцию, тем самым эффективно получив именованный структурный тип!). Я бы сказал, что ни один из этих вариантов не является примером утиного набора текста (если структурные типы не очень мелкие и не находятся в тесной синхронизации с проверкой кода для них).