LINUX.ORG.RU

«Утиная типизация» (Duck-typing) — зло или благо?

 duck-typing


3

8

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

★★

Последнее исправление: GreenBag (всего исправлений: 1)

Ответ на: комментарий от proud_anon

Я джва года о таком мечтал.

а си-погромисты на таком пишут с 90-х годов. ;-) а с некоторого времени — даже пользующиеся gcc (-fplan9-extensions).

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

struct biobufhdr {...};
struct biobuf {biobufhdr; uchar b[bsize];};
int bfunc(biobufhdr *b) {...}

(это пример из стандартной библиотеки plan9, смысл в том, что если размер буфера (bsize) устраивает, можно пользоваться biobuf, а если нет — определить свою «обертку» над biobufhdr с нужным размером буфера, и, возможно, еще какими-то полями и, соответственно, новыми функциями)

anonymous
()
Ответ на: комментарий от HerrWeigel

Лень писать самому

Ну, хоть покажи, где там слова «утиная типизация».

Miguel ★★★★★
()
Ответ на: комментарий от tailgunner

Некоторые альтернативно образованные и вывод типов называют «утиной типизацией».

Мда. Бывает.

Miguel ★★★★★
()
Ответ на: комментарий от anonymous

Всегда поражали другие языки обилием всяких ненужностей, по сравнению с си.

anonymous
()
Ответ на: комментарий от true_admin

кстати, всегда бесили такие аналогии

меня обычно интересует, какие у авторов были детские травмы

wxw ★★★★★
()
Ответ на: комментарий от Miguel

А можно с этого места поподробнее.

template<class InputIterator, class T>
  InputIterator find ( InputIterator first, InputIterator last, const T& value )
  {
    for ( ;first!=last; first++) if ( *first==value ) break;
    return first;
  }
O02eg ★★★★★
()

Это нормально. Но надо чётко помнить что и куда ты передаёшь, без этого становится плохо через некоторое время.

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

ИМХО, для развесистого проекта лучше брать язык со статической типизацией

Dark_SavanT ★★★★★
()

Так всё же: это благо или зло

зло, адъ и израилъ

drBatty ★★
()
Ответ на: комментарий от Miguel

Шаблоны позволяют делать утиную типизацию(проверяемую в статике):

template<typename T>
void call_f(T obj)
{
    obj.f(); // <- будет работать для всех типов, у которых есть метод f()
}

anonymous
()
Ответ на: комментарий от anonymous

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

Все проблемы(кроме первой) решаемы. Жаль, что концепты так и не появились. С ними все красиво, почти как в Haskell(и даже лучше).

anonymous
()
Ответ на: комментарий от anonymous

Зачем нужен go?

Для разработки ПО очевидно. ИМХО, отличная замена С и С++ в прикладном программировании.

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Так он не лучше же. Такое же г.

anonymous
()
Ответ на: комментарий от no-such-file

Почему? Разница с

def call_f(obj):
    obj.f()
Только во времени проверки. При статической типизации проверка будет осуществляться в статике, при динамической - в динамике. Что не так?

anonymous
()
Ответ на: комментарий от no-such-file

Template, or generic functions or methods apply the duck test in a static typing context; this brings all the advantages and disadvantages of static versus dynamic type checking in general.

anonymous
()
Ответ на: комментарий от true_admin

глупо спорить по поводу названий.

«Названий»?

главное суть.

Если для тебя «суть» «статического duck typing» и «динамического duck typing» одинакова или хотя бы схожа, у тебя проблема.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

может с точки системного программиста это и проблема, а для меня нет :). Суть в том что объект считается подходящим не потому что имеет нужный тип, а потому что реализует нужный интерфейс. Я прав?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Суть в том что объект считается подходящим не потому что имеет нужный тип, а потому что реализует нужный интерфейс. Я прав?

Не знаю. Почему-то мне кажется, что реализация некого интерфейса как-то связана с типом объекта %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

«суть» «статического duck typing» и «динамического duck typing» одинакова

В языках с динамической типизацией типы проверяют во время выполнения, в языках со статической - при компиляции. Аналогично выполняются проверки на «крякает как утка», «летает как утка». Если ты этого не понимаешь, то у тебя проблема.

O02eg ★★★★★
()

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

Legioner ★★★★★
()
Ответ на: комментарий от tailgunner

как-то связана с типом объекта %)

Тип у объекта один, а интерфейсов много. Или множество интерфейсов это некое подобие множественного наследия? Короче, имхо, словоблудие всё это.

true_admin ★★★★★
()
Ответ на: комментарий от tailgunner

Если что-то заставило тебя подумать, будто я этого не знаю - просто скажи «нет» наркотикам.

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

O02eg ★★★★★
()
Ответ на: комментарий от O02eg

В таком случае тебе бы не мешало прислушаться к собственному совету.

Я давно уже не принимаю вещества. Но вокруг столько норкоманов, что это просто удивительно.

tailgunner ★★★★★
()
package main

import "fmt"

type Quacker interface {
    Quack()
}

type Human struct{}
type Duck struct{}

func (h Human) Quack() {
    fmt.Println("Fuck you")
}

func (d Duck) Quack() {
    fmt.Println("Quack")
}

func main() {
    var q Quacker
    q = Human{}
    q.Quack()
    q = Duck{}
    q.Quack()
}

Утиная типизация рулёз.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

Да, «рулез», только одно но — определять Quack для Human на «всякий пожарный» — не глупо ли это? (да, и можно ли предусмотреть _всё_: можно еще добавить Woof для «защиты» от собаки и т.п.)

GreenBag ★★
() автор топика
Ответ на: комментарий от GreenBag

определять Quack для Human на «всякий пожарный»

А какой в этом смысл? Наоброт надо определять только там где нужно, никаких «пожарных».

true_admin ★★★★★
()
Ответ на: комментарий от tailgunner

Я к тому, что обе подходят под: When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck

anonymous
()
Ответ на: комментарий от PolarFox

Ну, я не знаком с языком, что приведен в качестве примера — ориентировался на Ruby (Python).

GreenBag ★★
() автор топика
Ответ на: комментарий от PolarFox
#include <iostream>

struct Human {};
struct Duck {};

void Quack(Human)
{
    std::cout << "Fuck you" << std::endl;
}

void Quack(Duck)
{
    std::cout << "Quack" << std::endl;
}

template<typename T>
void foo(T x)
{
    Quack(x);
}

int main()
{
    foo(Human());
    foo(Duck());
}
anonymous
()
Ответ на: комментарий от anonymous

Ну то что у меня написано компилируется, но диспетчирезуется в рантайме динамически. Ближайшая альтернатива на C☦☦ — наследование класса с виртуальной функцией.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

то что у меня написано компилируется, но диспетчирезуется в рантайме динамически.

пичалька, можно же было всё сделать на этапе компиляции.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

В данном примере да, в более сложном случае уже не особо.

PolarFox ★★★★★
()
Ответ на: комментарий от PolarFox

Можно написать абстрактный класс и шаблонную реализацию wrapper'а, которая будет брать объект любого класса с соответствующим методом и сделает из него наследника абстрактного класса. Будет то же самое.

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.