Какой профит это даёт по сравнению с вариантом, когда Tuple — структура?
За вычетом возможности скрыть конструктор по умолчанию и возможности наследоваться от кортежа.
Здравствуйте, Мишень-сан, Вы писали:
МС>Сабж. МС>Какой профит это даёт по сравнению с вариантом, когда Tuple — структура?
Например, нет копирования кучи данных на стеке. Одним из вариантом решения этой проблемы является делать часть тюплов с небольшим количеством мемберов структурами, а остальные — классами. Где-то читал, что вроде как первоначально и хотели так сделать, но тут возникает проблема, что вроде бы одна и та же структура данных может вести себя абсолютно по-разному в зависимости от того, добавите ли вы третий (четвертый, пятый) параметр при ее создании или нет. Такое поведение тоже сложно назвать очевидным — особенно в языках, где есть специальный синтаксис для работы с кортежами, и "системные детали" более или менее скрыты.
Поэтому решили пойти по пути наименьшего сопротивления — кортеж как класс.
Здравствуйте, Мишень-сан, Вы писали:
МС>Какой профит это даёт по сравнению с вариантом, когда Tuple — структура? МС>За вычетом возможности скрыть конструктор по умолчанию и возможности наследоваться от кортежа.
Едионобразие. Все туплы — классы. Некоему дженерик-коду не нужно делать ветвлений.
Туплами реализовано несколько интерфейсов (IStructuralEquatable, IStructuralComparable, IComparable) и сценарии работы с туплами подразумевают каст к ним. В случае структур появляются расходы на боксинг.
Туплы так же реализуют [internal] ITuple, который нужен, кажется, только для работы с Tuple<8> — то есь для распознования последнего параметра TRest. Тут так же требуется полиморфное поведение и поэтому класс кажется лучшим решением.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Мишень-сан, Вы писали:
МС>Сабж. МС>Какой профит это даёт по сравнению с вариантом, когда Tuple — структура? МС>За вычетом возможности скрыть конструктор по умолчанию и возможности наследоваться от кортежа.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, Мишень-сан, Вы писали:
МС>>Сабж. МС>>Какой профит это даёт по сравнению с вариантом, когда Tuple — структура?
ВВ>Например, нет копирования кучи данных на стеке. Одним из вариантом решения этой проблемы является делать часть тюплов с небольшим количеством мемберов структурами, а остальные — классами.
В Nemerle именно так и сделано. Tuple<a0, a1> и Tuple<a0, a1, a2> — структуры, все остальные перегрузки — классы.
Кортежи малого размера используются чрезвычайно часто и в основном на стеке (сопоставление с образцом например). Сделать их все классами — дань не функциональным языкам, которым эти кортежи, как собаке пятая нога. Для сравнения — ну кто в здравом уме станет делать Point (или PointF) классом а не структурой?
Здравствуйте, hardcase, Вы писали:
H>В Nemerle именно так и сделано. Tuple<a0, a1> и Tuple<a0, a1, a2> — структуры, все остальные перегрузки — классы.
Я в курсе, что так и сделано. Но у подобного подхода есть и недостатки. В этом я согласен с командой разработчиков кортежей для дотнета. Структуры и классы все же сильно отличаются по поведению, и для пользователя такое отличие может быть неочевидным — добавил еще один параметр в тюпл, и старый код перестал работать. При этом если в языке есть "встроенная поддержка" кортежей, то разницы в объявлении не будет да и интиллисенс тебе, вероятно, реальный тип тоже не покажет, и нужно держать в уме кол-во параметров и зависимость типа от этого.
Тоже не сахар ИМХО.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, hardcase, Вы писали:
H>>В Nemerle именно так и сделано. Tuple<a0, a1> и Tuple<a0, a1, a2> — структуры, все остальные перегрузки — классы.
ВВ>Я в курсе, что так и сделано. Но у подобного подхода есть и недостатки. В этом я согласен с командой разработчиков кортежей для дотнета. Структуры и классы все же сильно отличаются по поведению, и для пользователя такое отличие может быть неочевидным — добавил еще один параметр в тюпл, и старый код перестал работать. При этом если в языке есть "встроенная поддержка" кортежей, то разницы в объявлении не будет да и интиллисенс тебе, вероятно, реальный тип тоже не покажет, и нужно держать в уме кол-во параметров и зависимость типа от этого. ВВ>Тоже не сахар ИМХО.
В языках, где нет поддержи кортежей (это те, где нет сопоставления с образцом) писать много кода, специально работающего с кортежами смысла — никакого, будет неудобно даже не из-за малоинформативных имен FieldX, а из-за недостатка конструкций, позволяющих оперировать кортежами. Кортежи пришли из функциональных языков — там и должны оставаться, в C#/VB.NET им делать нечего.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, hardcase, Вы писали:
H>>В Nemerle именно так и сделано. Tuple<a0, a1> и Tuple<a0, a1, a2> — структуры, все остальные перегрузки — классы.
ВВ>добавил еще один параметр в тюпл, и старый код перестал работать.
Добавил 9й параметр — и старый код перестал работать
Там где есть место для одного исключения — всегда найдется место и для другого.
Если разработчики CLR забили на оптимизацию создания объекта на стеке, предоставив это дело прикладным разработчиками (использовать структуры), то странно, что они отказались от вполне логичного и очевидного хода — использование этого инструмента в фундаментальных типах, особенно принимая во внимание тот факт, что тип этот полностью скрывается инфраструктурой конкретного языка, явно использующего его и заточенного под него.
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, Воронков Василий, Вы писали:
ВВ>>Здравствуйте, hardcase, Вы писали:
H>>>В Nemerle именно так и сделано. Tuple<a0, a1> и Tuple<a0, a1, a2> — структуры, все остальные перегрузки — классы.
ВВ>>добавил еще один параметр в тюпл, и старый код перестал работать.
H>Добавил 9й параметр — и старый код перестал работать H>Там где есть место для одного исключения — всегда найдется место и для другого.
H>Если разработчики CLR забили на оптимизацию создания объекта на стеке, предоставив это дело прикладным разработчиками (использовать структуры), то странно, что они отказались от вполне логичного и очевидного хода — использование этого инструмента в фундаментальных типах, особенно принимая во внимание тот факт, что тип этот полностью скрывается инфраструктурой конкретного языка, явно использующего его и заточенного под него.
Здравствуйте, hardcase, Вы писали:
ВВ>>добавил еще один параметр в тюпл, и старый код перестал работать. H>Добавил 9й параметр — и старый код перестал работать
Это с какого? В языках, где поддержка кортежей на уровне синтаксиса, все будет прекрасно работать.
H>Там где есть место для одного исключения — всегда найдется место и для другого.
Ну пока не видно.
H>Если разработчики CLR забили на оптимизацию создания объекта на стеке, предоставив это дело прикладным разработчиками (использовать структуры), то странно, что они отказались от вполне логичного и очевидного хода — использование этого инструмента в фундаментальных типах, особенно принимая во внимание тот факт, что тип этот полностью скрывается инфраструктурой конкретного языка, явно использующего его и заточенного под него.
А это к чему вообще? System.Int32 — структура, всегда ведет себя как структура и всегда структурой остается, независимого от того, какое она принимает значение.
С кортежами идеального решения нет, делать все кортежами структурами было бы куда хуже как раз в плане "оптимизации". И принятое решение далеко не самое плохое.
А зачем нужны тюплы в шарпе, вы в вспомните, когда попробуете из шарпа работать с кодом на функциональном языке, и вместо зверинца получите единую систему типов.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, hardcase, Вы писали:
ВВ>>>добавил еще один параметр в тюпл, и старый код перестал работать. H>>Добавил 9й параметр — и старый код перестал работать
ВВ>Это с какого? В языках, где поддержка кортежей на уровне синтаксиса, все будет прекрасно работать.
А я как-раз про те языки где ее нет.
В общем-то, за аргумент может сойти это:
class A<T> where T : class
но только не часто такое встречается (и в стандартных контейнерах нет), гораздо чаще в пользовательском коде накладываются ограничения с интерфейсами.
ВВ>А это к чему вообще? System.Int32 — структура, всегда ведет себя как структура и всегда структурой остается, независимого от того, какое она принимает значение. ВВ>С кортежами идеального решения нет, делать все кортежами структурами было бы куда хуже как раз в плане "оптимизации". И принятое решение далеко не самое плохое.
Я не говорю, что нужно делать все структурами. Я говорю что гибридное решение здесь было бы наилучшим. Впрочем, это все мое личное мнение.
ВВ>А зачем нужны тюплы в шарпе, вы в вспомните, когда попробуете из шарпа работать с кодом на функциональном языке, и вместо зверинца получите единую систему типов.
И ничего, работаю Только я не пытаюсь из функциональщины высовывать наружу то, что C# не свойственно.
Здравствуйте, hardcase, Вы писали:
ВВ>>Это с какого? В языках, где поддержка кортежей на уровне синтаксиса, все будет прекрасно работать. H>А я как-раз про те языки где ее нет.
В языках, где ее нет, и проблемы такой, собственно, нет. Вы-то уж разберетесь, что вы на самом деле создаете — структуру или класс. У меня вот студия даже их цветами разными раскрашивает.
Кортежи создавались в первую очередь для более других языков.
ВВ>>А это к чему вообще? System.Int32 — структура, всегда ведет себя как структура и всегда структурой остается, независимого от того, какое она принимает значение. ВВ>>С кортежами идеального решения нет, делать все кортежами структурами было бы куда хуже как раз в плане "оптимизации". И принятое решение далеко не самое плохое. H>Я не говорю, что нужно делать все структурами. Я говорю что гибридное решение здесь было бы наилучшим. Впрочем, это все мое личное мнение.
Наилучшего решения здесь нет. Причины, приведенные разработчиками, мне кажутся вполне убедительными. В статье, на которую я приводил ссылку, это описывается. Они вначале пошли по гибридному пути, но потом отказались. Проводили перфоманс-тесты и пр. Разработчики компилятора F#, написанного на самом себе и активно использующем кортежи, говорят, что деградации перфоманса при полном переходе на реф-типы не произошло. И я им верю. А если это хорошо для F#...
И да, мне кажется большим недостатком гибридного подхода, то, что (1, 2, 3) и (1, 2, 3, 4) — это абсолютно разные типы, по-разному хранящиеся в памяти. Пользователю ФЯ это может быть сильно не очевидно. Да и перфоманс при случае тоже может пострадать.
ВВ>>А зачем нужны тюплы в шарпе, вы в вспомните, когда попробуете из шарпа работать с кодом на функциональном языке, и вместо зверинца получите единую систему типов. H>И ничего, работаю Только я не пытаюсь из функциональщины высовывать наружу то, что C# не свойственно.
Ну а теперь с этим проблем не будет, можно выставлять тюплы. Все должны быть довольны.