dynamic vs object
От: Shmj Ниоткуда  
Дата: 11.01.25 14:00
Оценка:
В любом языке существует наиболее общий тип — т.е. то, что может обозначать все на свете. В нашем языке русском это слово — фиговина. Фиговиной можно назвать все что угодно.

Вот, в Java придумали уникальную идею — все является объектом. Т.е. наследником класса Object. Кроме аксиоматических типов (int, float и пр.), они особняком, но для каждого из них есть объектное соответствие. Т.е. для любого объекта класса можно использовать универсальную ссылку — Object.

В C++, к примеру, неким аналогом является использование указателя void* (но там нет проверки приведения). Или пошли по другому пути — компил-таймовый C++ и шаблоны с T. С шаблонами как бы нет четкой проверки иерархии, но есть просто проверка использования. Не супер идея. Java придумали намного умнее.

Далее. C# чуть искаверкал идею Java, там уже нет аксиоматических типов — int уже как объект как и Int32 — целиком и полностью аналогичны, кроме буквы — аксиоматические как бы с маленькой буквы (причем и object типа аксиоматический). Т.е. пропала чистота идеи, но ОК, можно и так.

А потом в C# добавили как бы второй возможный механизм фиговины — dynamic. Но он скорее не используется или используется просто для синтаксиса — чтобы вместо keys["key1"] писать keys.key1  — ни то ни другое контролировать не нужно, но просто меньше писанины — по прежнему dynamic не особо важен для парадигм.

В Dart стало хуже — этот dynamic стал частью парадигм. К примеру даже есть

abstract interface class Comparable<T>


Я хочу в своем классе сделать поле, которое соответствует этому интерфейсу Comparable. Но без указания T — мне нужно чтобы был любой тип, который умеет сравнивать себя с собой.

Вот так:

abstract interface class ComparableWithSelf implements Comparable<ComparableWithSelf>{
}


— не сработает, т.к нет поддержки ковариантности ентой (или как там ее). Можно написать так:

abstract interface class MyComparable implements Comparable{

}


— тогда Т будет установлен в dynamic, а там можно все

Как бы пропала чистота идеи — по умолчанию возникает dynamic. В C# есть версия IComparable с object — а в Dart решили вместо object — сделать dynamic. Как бы вообще опустились почти до уровня JS.
Отредактировано 11.01.2025 14:15 Shmj . Предыдущая версия . Еще …
Отредактировано 11.01.2025 14:09 Shmj . Предыдущая версия .
Re: dynamic vs object
От: Privalov  
Дата: 11.01.25 19:31
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Как бы пропала чистота идеи — по умолчанию возникает dynamic. В C# есть версия IComparable с object — а в Dart решили вместо object — сделать dynamic. Как бы вообще опустились почти до уровня JS.


Иногда dynamic бывает полезен. Но за его беспорядочное использование надо морально убивать на месте ©.
И в C# dynamic — не определение типа, а указание компилятору не проверять наличие у него свойств и методов. Все проверки переносятся в выполнение. По факту же переменная dynamic — это object в C#.
Re: dynamic vs object
От: Pzz Россия https://github.com/alexpevzner
Дата: 11.01.25 20:02
Оценка: +2
Здравствуйте, Shmj, Вы писали:

S>Далее. C# чуть искаверкал идею Java, там уже нет аксиоматических типов — int уже как объект как и Int32 — целиком и полностью аналогичны, кроме буквы — аксиоматические как бы с маленькой буквы (причем и object типа аксиоматический). Т.е. пропала чистота идеи, но ОК, можно и так.


Это называется, "примитивные типы". Не "аксиоматические". По-английски так же, primitive data types.

https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B8%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9_%D1%82%D0%B8%D0%BF
https://en.wikipedia.org/wiki/Primitive_data_type

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

В Яве это, я так понимаю, не то, чтобы то, к чему стремились, а артефакт реализации. int, завернутый в Object, стоит дороже, чем примитивный int.
Re: dynamic vs object
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.01.25 08:57
Оценка: +3
Здравствуйте, Shmj,
Непонятно, в чём ваш вопрос.
Если вы просто хотели поделиться наблюдениями, то не всё корректно.
S>В любом языке существует наиболее общий тип — т.е. то, что может обозначать все на свете. В нашем языке русском это слово — фиговина. Фиговиной можно назвать все что угодно.
Нет, не в любом.
S>Вот, в Java придумали уникальную идею — все является объектом.
Нет, эту идею придумали не в Java, а в Smalltalk. В нём нет примитивных типов.
S>Т.е. наследником класса Object. Кроме аксиоматических типов (int, float и пр.), они особняком, но для каждого из них есть объектное соответствие. Т.е. для любого объекта класса можно использовать универсальную ссылку — Object.
Не для любого. Примитивные типы ведут себя по-разному в забоксенном и незабоксенном виде.

S>В C++, к примеру, неким аналогом является использование указателя void* (но там нет проверки приведения).

Нет, не является. Точно так же, как в Java вы не можете использовать Object для int-value, так и в С++ void* подходит для указателя на почти всё, но не для примитивных типов. И даже не все указатели совместимы с void*
S>Или пошли по другому пути — компил-таймовый C++ и шаблоны с T. С шаблонами как бы нет четкой проверки иерархии, но есть просто проверка использования. Не супер идея. Java придумали намного умнее.
По итогам забега всё ещё непонятно, кто же придумал умнее. По крайней мере, математика на С++ гораздо эффективнее джавовской (а если захочется сравнимой эффективности, то на Java придётся отказаться от идиоматического кода и начать упарываться. По меткому выражению одного моего знакомого джава-евангелиста, "обмазаться говном").

S>Далее. C# чуть искаверкал идею Java, там уже нет аксиоматических типов — int уже как объект как и Int32 — целиком и полностью аналогичны, кроме буквы — аксиоматические как бы с маленькой буквы (причем и object типа аксиоматический). Т.е. пропала чистота идеи, но ОК, можно и так.

1. Конечно же, такие типы есть. int и Int32 — один и тот же тип, а не "аналогичные типы". При этом int — это честный инт, а не Integer в Java. Его боксинг происходит только там, где нужно привести его к ссылке на object или интерфейс (да и то не всегда)
2. Идея тут гораздо чище, чем в Java — потому что нет принудительного деления на "аристократические" и "плебейские" типы. Поэтому в Linq не нужны функции mapToInteger и mapToFloat, а в Streams API — нужны.
S>А потом в C# добавили как бы второй возможный механизм фиговины — dynamic. Но он скорее не используется или используется просто для синтаксиса — чтобы вместо keys["key1"] писать keys.key1  — ни то ни другое контролировать не нужно, но просто меньше писанины — по прежнему dynamic не особо важен для парадигм.
dynamic очень важен для парадигм, потому что динамическая типизация — совсем другая парадигма, чем статическая. object статически типизирован, и реализация идеи "если у фактического класса object o есть метод Foo(int), то давайте вызовем o.Foo(42), а иначе выкинем исключение" будет чудовищно громоздкой как в исходном коде, так и при исполнении.

S>В Dart стало хуже — этот dynamic стал частью парадигм. К примеру даже есть


S>
S>abstract interface class Comparable<T>
S>


S>Я хочу в своем классе сделать поле, которое соответствует этому интерфейсу Comparable. Но без указания T — мне нужно чтобы был любой тип, который умеет сравнивать себя с собой.


S>Вот так:


S>
S>abstract interface class ComparableWithSelf implements Comparable<ComparableWithSelf>{
S>}
S>


S>- не сработает, т.к нет поддержки ковариантности ентой (или как там ее).

Непонятно, при чём тут ковариантность. В дотнете так вполне себе можно безо всякой ковариантности. Контравариантность в IComparable<T> нужна не для того, чтобы можно было писать ваш пример, а чтобы IComparable<Base> можно было использовать вместо IComparable<Derived>.
В дарте я не специалист, но это не повод использовать термины и понятия не по назначению.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.