
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (33) « Первая ... 6 7 [8] 9 10 ... 32 33 ( Перейти к последнему сообщению ) |
Сообщ.
#106
,
|
|
|
Цитата DarkEld3r @ Они не станут классами. Как были структурами и примитивными типами, так и останутся.Вот, кстати, да - для примитивных типов и структур ещё и семантика нарушится ведь. В смысле, они станут классами. Цитата DarkEld3r @ Это не эквивалентные куски кода.Ну и в D у тебя уже вот тут будет новый тип: ![]() ![]() auto a = makeToString(Foo(30)); В расте не так, там тип за указателем не прячется: ![]() ![]() let a: Foo = Foo { data: 10 }; Тут а вполне себе стековая переменная. И если в структуру дополнительные поля добавить, то размер вырастет. В D просто для классов иначе размер получать надо, только и всего. Дешный вариант: ![]() ![]() Foo a = {data: 10}; Вполне себе стековая переменная. И никаких дополнительных полей в структуру не добавляется. Дык в растовском варианте в функцию тоже передается отнюдь не сам объект Foo, а указатель типа ToString, и лежит там неведомый, скрытый от посторонних глаз объект. Те же яйца вид сбоку. Синтаксический цукер. Добавлено Возможно, я не спорю, что в Rust все плохо. Я считаю данный холивар бессмысленным, так как в конечном счете сравниваем одно и тоже. |
Сообщ.
#107
,
|
|
|
Ну любой холивар бессмысленным можно назвать. Концепция trait'ов в сочетании с impl'ами и generic'ами, а так же, возможно, макросами, проста и представлена довольно ортогональными средствами. И если она при этом способна покрывать большую часть(все?) того, что решается с помощью классового ООП, перегрузки, шаблонной магии и пр. вещей, которые явно сложнее (и не эффективнее), то она, как минимум, заслуживает внимания.
Добавлено Цитата applegame @ Дык в растовском варианте в функцию тоже передается отнюдь не сам объект Foo, а указатель типа ToString, и лежит там неведомый, скрытый от посторонних глаз объект. Те же яйца вид сбоку. Синтаксический цукер. Тут, как мне кажется, ты излишне вдаешься в реализацию. Ты реализовал трейты с имплами через ОО-интерфейсы и врапперы. Но что ты этим показал? |
Сообщ.
#108
,
|
|
|
Цитата D_KEY @ Сложнее и не эффективнее? Не согласен.И если она при этом способна покрывать большую часть(все?) того, что решается с помощью классового ООП, перегрузки, шаблонной магии и пр. вещей, которые явно сложнее (и не эффективнее), то она, как минимум, заслуживает внимания. Цитата D_KEY @ Полагаю они именно так и реализованы в Rust. Тут, как мне кажется, ты излишне вдаешься в реализацию. Ты реализовал трейты с имплами через ОО-интерфейсы и врапперы. Но что ты этим показал? |
Сообщ.
#109
,
|
|
|
Цитата applegame @ Они не станут классами. Как были структурами и примитивными типами, так и останутся. Я всё-таки уточню - результат makeToString ведь будет классом? Цитата applegame @ Я считаю данный холивар бессмысленным, так как в конечном счете сравниваем одно и тоже. Ну почему же, я про D больше узнал, например. ![]() |
Сообщ.
#110
,
|
|
|
Цитата DarkEld3r @ Он будет интерфейсом или трейтом, как угодно. Аналог трейта ToString в Rust. Просто Rust неявно "кастует" Foo к ToString, а в D приходится явно "кастовать" при помощи makeToString. Я всё-таки уточню - результат makeToString ведь будет классом? |
Сообщ.
#111
,
|
|
|
Цитата applegame @ Сложнее и не эффективнее? Не согласен. Не готов оспаривать утверждением в целом, но местами всё-таки поудобнее. По крайней мере, если сравнивать с плюсовыми шаблонами, в D ведь ситуация получше. Не будет, как минимум, многокилометровых ошибок. Да и макросы вполне мощные - регекспы, например, могут компилироваться вместе с программой, в С++ в шаблонах со строками работать удовольствия мало. Добавлено Цитата applegame @ Он будет интерфейсом или трейтом, как угодно. Ну за указателем на интерфейс ведь будет класс? Ну и в расте можно переписать вот так: ![]() ![]() fn foo2<T: ToString>(a: &T) И результат будет совсем другой. В стандартной библиотеке трейты именно так и используются. Потому что эффективнее, в общем случае. |
Сообщ.
#112
,
|
|
|
Цитата DarkEld3r @ В D тоже могут. Любой код D может быть выполнен compile-time, если нет зависимости от неконстантных внешних данных. Да и макросы вполне мощные - регекспы, например, могут компилироваться вместе с программой Добавлено Цитата DarkEld3r @ Будет. А за трейтом, что будет? Ну за указателем на интерфейс ведь будет класс? |
Сообщ.
#113
,
|
|
|
Цитата applegame @ Сложнее и не эффективнее? Не согласен. Т.е. ты не согласен, что классовое ООП, ОО-интерфейсы, шаблоны и концепты сложнее trait'ов с impl и дженериками? Хм. Мне кажется, ты лукавишь. Добавлено Цитата applegame @ Полагаю они именно так и реализованы в Rust. Не знаю. Но не вижу никакого смысла выделять обертку в динамической памяти, да еще и при каждой передаче. Еще не вижу смысла заводить анонимный класс в make*. Так же можно поиграться с передачей аргументов и попробовать передавать трейты отдельно(примерно так делает haskell для тайпклассов). Но тут нужно подумать ![]() DarkEld3r, для rust нет чего-то вроде Compiler Explorer? |
Сообщ.
#114
,
|
|
|
Цитата D_KEY @ Нет не лукавлю. Впрочем в плюсах, наверняка сложнее. В D - сильно сомневаюсь. Приведи примеры, напишу тебе аналоги, сравним. Т.е. ты не согласен, что классовое ООП, ОО-интерфейсы, шаблоны и концепты сложнее trait'ов с impl и дженериками? Хм. Мне кажется, ты лукавишь. |
Сообщ.
#115
,
|
|
|
Цитата applegame @ Цитата D_KEY @ Нет не лукавлю. Впрочем в плюсах, наверняка сложнее. В D - сильно сомневаюсь. Приведи примеры, напишу тебе аналоги, сравним.Т.е. ты не согласен, что классовое ООП, ОО-интерфейсы, шаблоны и концепты сложнее trait'ов с impl и дженериками? Хм. Мне кажется, ты лукавишь. Язык тут ни при чем. Речь о самих концепциях. trait задает набор методов, impl описывает их реализацию для типа. Тут нет никаких интерфейсов, абстрактных классов, классов. Тут нет иерархий наследования, виртуальных/невиртуальных методов, абстрактных методов, private/protected/public и пр. Очень много "лишней" информации уходит. Далее, шаблоны сложнее дженериков. Тут ты вряд ли будешь спорить? При этом Rust ушел от проблемы производительности дженериков в рантайме. Код генерируется. Но при этом нет сложных правил перегрузки, специализаций и т.п. Все разруливается через те же трейты, причем довольно прозрачно. И так же в статике. Концепты сложнее простого указания trait'а. impl'ы проще и декларативнее ручной реализации оберток. |
Сообщ.
#116
,
|
|
|
Цитата DarkEld3r @ Моя мысль правда непонятна? В расте при добавлении трейта типу размер типа не меняется. Цитата applegame @ Невероятно! Представь себе при добавлении новых интерфейсов в D размер типа тоже не меняется! Точно так же и в С++. Размер изменится, только если добавить новые поля, подмешивание чистых абстрактных классов и замещение методов размер класса тоже не меняют |
Сообщ.
#117
,
|
|
|
Цитата D_KEY @ наследование есть, интерфейсы (они же трейты) есть, функции описанные в треатах - виртуальные и абстрактные, отсутствие private/protected/public - недостаток, а не преимущество.Речь о самих концепциях. trait задает набор методов, impl описывает их реализацию для типа. Тут нет никаких интерфейсов, абстрактных классов, классов. Тут нет иерархий наследования, виртуальных/невиртуальных методов, абстрактных методов, private/protected/public и пр. Цитата D_KEY @ Буду спорить с тем, что ты это представляешь как преимущество. Дженерики в расте - частный случай шаблонов. Написать шаблон аналогичный дженерику ничуть не сложнее.Далее, шаблоны сложнее дженериков. Тут ты вряд ли будешь спорить? Цитата D_KEY @ Сложность правил зависит от языка, а не от концепций.Но при этом нет сложных правил перегрузки, специализаций и т.п. Цитата D_KEY @ Концепты != растовским трейтам. Я не буду использовать концепты для примитивных дженерикообразных шаблонов. Для этого есть более простые способы указания template constraints. И уж тем более я не буду городить оберток без крайней необходимости. Опять же для реализации аналогичного растовскому функционала не нужно никаких особых оберток. Тот пример, который я привел - имитация растовских трейтов. Такие декораторы не часто нужены в реальной жизниКонцепты сложнее простого указания trait'а. impl'ы проще и декларативнее ручной реализации оберток. А вообще, это все пустые разговоры, приведи пример, где на Rust все пишется проще, чем на D. Добавлено Цитата amk @ В целом, да. Но ЕМНИП это implementation defined. Стандарт C++ разве требует чтобы потомок имел тот же размер, что и предок, в случаях когда не добавляются дополнительные данные? Точно так же и в С++. Размер изменится, только если добавить новые поля, подмешивание чистых абстрактных классов и замещение методов размер класса тоже не меняют |
Сообщ.
#118
,
|
|
|
Цитата applegame @ наследование есть Нет. Есть возможность для trait'а указать, что его реализация типом требует так же реализации других трейтов. Цитата интерфейсы (они же трейты) есть Допустим(а интерфейсы в D могут иметь реализацию методов по умолчанию?), но кроме них-то нет ничего. Никаких абстрактных классов, например. Цитата функции описанные в треатах - виртуальные и абстрактные Виртуальные или абстрактные. Да. Но это не нужно указывать, об этом не нужно думать, как о каком-то отдельном механизме. Просто trait. Цитата отсутствие private/protected/public - недостаток, а не преимущество При наличии модульной системы это довольно спорно. Цитата Буду спорить с тем, что ты это представляешь как преимущество. Не теряй контекст, мы о простоте. Цитата Дженерики в расте - частный случай шаблонов. Нет. Дженерики - это параметрический полиморфизм, который, в общем случае, шаблонами не покрывается. Цитата Написать шаблон аналогичный дженерику ничуть не сложнее. Помнишь пример с контролем равенства размера двух списков/векторов во время компиляции? Цитата Цитата D_KEY @ Сложность правил зависит от языка, а не от концепций.Но при этом нет сложных правил перегрузки, специализаций и т.п. Если ты вводишь в язык перегрузку, полноценные шаблоны и специализации, то правила уже простыми не будут. Цитата Концепты != растовским трейтам. Не равны. И? Вопрос в том, позволяет ли сочетание более простых и ортогональных средств в Rust решать те же задачи проектирования и управления сложностью, что мы решаем с помощью сложных и связных компонентов в более "классических" языках, без потери эффективности как в работе, так и в производительности систем? Цитата А вообще, это все пустые разговоры, приведи пример, где на Rust все пишется проще, чем на D. Так в Rust вообще нет сложных концепций. Тут скорее ты должен привести пример, когда нам нужно все это многообразие средств и их мощность. |
Сообщ.
#119
,
|
|
|
Цитата applegame @ Ну я специально про С++ уточнил - там ведь со строками в шаблонах нормально работать нельзя. А можно простой пример шаблона в D, который со строкой работает?В D тоже могут. Любой код D может быть выполнен compile-time, если нет зависимости от неконстантных внешних данных. Цитата applegame @ Будет структура содержащая указатель на данные и таблицу виртуальных функций. Но я не придираюсь, если что, просто хотел уточнить правильно ли понимаю происходящее в D.Будет. А за трейтом, что будет? Кстати, поигрался немного с трейтами в D - в ideone если одна из требуемых функций имеет неподходящую сигнатуру, то компилятор не очень понятно ругается: template prog.test(Range) if (isInputRange!(Range)) does not match any function template declaration То есть не показывает, что именно не подходит. Это там компилятор такой или везде так? В расте, конечно, механизм "немного" другой, но если трейт не реализован, то компилятор так и скажет (the trait `...` is not implemented for the type `...`). Если же попытаться неправильно реализовать трейт, то тоже будет явное указание на проблему. Или "not all trait items implemented, missing: `drop`" или указание на неправильную сигнатуру конкретного метода. Кстати, ещё один вопрос - в С++ ведь нельзя шаблонным параметрам-функциям нормально ограничить сигнатуру. В смысле можем или так или так: ![]() ![]() template <typename F> void f(F f) {} void f(const std::function<int (int)>& f) {} Цитата D_KEY @ На мой взгляд, в расте при написании дженериков сильнее с типами "бороться" надо. в С++, в этом плане, проще - если шаблон не будет никуда наружу торчать, то можно не париться с концептами/статик асертами и т.д. Сигнатуры, опять же, сильнее "замусориваются" разными требованиями. Для внешних функций оно, пожалуй, хорошо (хотя всё равно найдутся те, кто будут ныть про нечитаемость/сложность), но побыстрому набросать шаблон уже не выйдет. Т.е. ты не согласен, что классовое ООП, ОО-интерфейсы, шаблоны и концепты сложнее trait'ов с impl и дженериками? Хм. Мне кажется, ты лукавишь. Цитата D_KEY @ Дык - play.rust-lang.org. Там и асмовый и ллвмный выхлоп посмотреть можно. Явно флаги компиляции задавать нельзя, но дебаг/релиз переключать можно. DarkEld3r, для rust нет чего-то вроде Compiler Explorer? Правда перед релизом 1.0 на многие оптимизации забили, чтобы успеть побольше всего стабилизировать. Сейчас уже этим более активно занялись - вон в 1.1 компиляцию ускоряли, например. Добавлено Цитата D_KEY @ Ну... я хоть и защищаю тут раст, но не торопился бы с выводами. Речь о самих концепциях. ![]() Одну сложность убрали, другую добавили. Скажем, в С++ шаблону класса дополнительный параметр можно "просто так" довесить и не париться, а раст требует, чтобы все параметры были задействованы. Конечно, необходимое сделать можно, но более явно - через PhantomData, но это ведь тоже, своего рода, "лишние приседания. Система типов, опять же, выглядит более сложной. Опять же, за безопасность приходится платить тем, что многие структуры данных пишутся заметно сложнее - с привлечением unsafe, если мы хотим такой же эффективности как в С++. Добавлено Цитата amk @ Да, мы уже разобрались. Просто говорили немного о разном. Точно так же и в С++. ![]() |
Сообщ.
#120
,
|
|
|
DarkEld3r, я выводов о том, как это будет на практике, не делал. понятно же, что за все нужно чем-то платить. И вообще, см. подпись
![]() |