Re[9]: недостатки системы типов .NET
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.11.06 15:32
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Я имею в виду, что не нужны для тех целей, для которых используется const.


Еще раз повторюсь — const в С++ используется для разных вещей. Это перегруженное ключевое слово.

C>Естественно, иммутабельные переменные, в частности, значительно упрощают

C> многопоточное программирование.

Это пока только на словах. А в реальной жизни они позволяют количество место в которыхз может появиться ошибока.
Разумно вообще стараться не использовать изменяемые переменные если на то нет реальной необхдимости.

C>Есть мнение, что 100% гарантия не очень нужна.


Я бы все же желал иметь больше гарантий. Гарантии не всегда достижимы, но всегда хочется их иметь.

C> Сейчас посмотрел свой код

C>- на 4Мб исходников на С++ приходится 120 const_cast'ов.

Дык, это же твой код на С++. А ты посмотри мой код на Nemerle:
http://nemerle.org/svn/vs-plugin/trunk/Nemerle.Compiler.Utils
Там как раз mutable встречается намного реже чем неизменяемые переменные. А const_cast нет в принцие, так как язык типобезопасный.

C>Примерно

C>половину из них можно убрать без всяких проблем (там они просто
C>сберегают несколько строк кода), еще часть можно было бы убрать, если
C>хорошо подумать.

Вот ивдишь? А каждый const_cast — это потенциальная ошибка.

C>Но вот что делать с остальными — непонятно.


И как же в других то языках получается без него писать? Загадка ветка.

C>Так что я лучше буду жить с не-100%-ной гарантией, что объект не

C>изменится в const-методе или через const-ссылку.

Давай. А я лучше буду жить без кривого и запутанного С++.
Хотя согласен, что идея помечать методы (да и классы) как неизменяемые — это хорошая идея. И надо будет ее реализовать.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Нет возможности использовать константные ссылки
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.11.06 15:32
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Это должно быть свойством типа. Как value типы и reference типы. Также должно быть еще одно измерение mutable типы и imutable типы.

WH>Те объект либо изменяемый либо нет.

+1
Однако это не должно мешать наличию неизменяемых переменных. Неизменность переменных — это особенность алгоритма текущей функции. А неизменность типа — это особенность конкретного типа.

Например, int принципиально изменяем в любом ИЯ. Но не во всех алгоритмах имеет смысл изменять целочисленные переменные. Декларируя переменную как неизменяемую мы можем защитить себя от ошибок связаннях с неверным применением переменных.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Нет возможности использовать константные ссылки
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.11.06 15:32
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Ну вот мы указали, что класс imutable. А он внутри себя пишет в лог. Как в этом случае должен поступить компилятор?


Очевидно должна быть возможность пометить любой метод как безопасный с точки зрения инварианта типов программы. Так что методы вывода на консоль надо просто пометить таким атрибутом и компилятор будет пропускать его.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: недостатки системы типов .NET
От: Cyberax Марс  
Дата: 12.11.06 15:53
Оценка:
VladD2 wrote:
> C>Я имею в виду, что не нужны для тех целей, для которых используется const.
> Еще раз повторюсь — const в С++ используется для разных вещей. Это
> *перегруженное* ключевое слово.
Не перегружено. Разве что для констант можно было final добавить.

"const" обозначает константные переменные и функции, работающие в
константном контексте. Из константного контекста все переменные (за
исключением mutable) видные тоже как константные.

В С++ном const'е разве что сложны правила его распространения (т.е.
разница между const char* и char const *).

Где тут перегруженность?

> C>Есть мнение, что 100% гарантия не очень нужна.

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

Мое ИМХО — нужно делать так, чтобы гарантии МОЖНО было нарушать, но
чтобы это требовало явных требований со стороны программиста.

> C> Сейчас посмотрел свой код

> C>- на 4Мб исходников на С++ приходится 120 const_cast'ов.
> Дык, это же *твой* код на *С++*. А ты посмотри мой код на Nemerle:
> http://nemerle.org/svn/vs-plugin/trunk/Nemerle.Compiler.Utils
> Там как раз mutable встречается намного реже чем неизменяемые
> переменные. А const_cast нет в принцие, так как язык типобезопасный.
Некорректно сравнивать разные языки. Вот мне лично в C#/Java мешает
иммутабельность строк.

> C>Примерно

> C>половину из них можно убрать без всяких проблем (там они просто
> C>сберегают несколько строк кода), еще часть можно было бы убрать, если
> C>хорошо подумать.
> Вот ивдишь? А каждый const_cast — это потенциальная ошибка.
Бери выше, каждый оператор — потенциальная ошибка. Как раз в случае с
const_cast'ом весьма легко найти потенциальные места ошибок — запустив
поиск по нему.

> C>Но вот что делать с остальными — непонятно.

> И как же в других то языках получается без него писать? Загадка ветка.
Так самый простой вариант — убрать все const. Тогда не нужны будут и
const_cast'ы, но вот только потеряется некоторая доля безопасности.

> C>Так что я лучше буду жить с не-100%-ной гарантией, что объект не

> C>изменится в const-методе или через const-ссылку.
> Давай. А я лучше буду жить без кривого и запутанного С++.
> Хотя согласен, что идея помечать методы (да и классы) как неизменяемые —
> это хорошая идея. И надо будет ее реализовать.
А что это даст?
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[10]: недостатки системы типов .NET
От: AndreiF  
Дата: 12.11.06 16:58
Оценка: 10 (1) :)
Здравствуйте, VladD2, Вы писали:

VD>Вот давича купил я себе память для нового компьютера. На ней написано "пожизненная гарантия". Ну, и что вы думаете? В гарантийном талоне написано — один год.


[offtopic on]
Это старый трюк маркетоидов. "Пожизненная" — производитель обычно имеет в виду срок жизни данной модели на рынке, а совсем не то что подумает нормальный покупатель. Так что как только эту модель перестанут производить, тут гарантии и конец. В штатах, если не ошибаюсь, даже приняли специальный закон, что "пожизненная" гарантия не может длиться меньше чем год (или что-то около того)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: недостатки системы типов .NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.06 19:08
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>Странно только, зачем они сделали этот метод у массивов статическим.


Как раз очень правильно. Потому что утилитный метод лучше делать статическим. Если же тебе просто хочется синтаксиса с точкой, то C# 3 этому горю поможет.
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[4]: недостатки системы типов .NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.06 19:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>interface ICloneable<T>
VD>{
VD>    T Clone();
VD>}

VD>class Test : ICloneable<Test>
VD>{
VD>  public Test Clone() // OK
VD>    {
VD>    ...
VD>    }
VD>}
VD>


Тут попа. ICloneable обычно используется как кто так:
object EditValue(object value)
{
    ICloneable cln = value as ICloneable;
    object editValue = cln != null ? cln.Clone : CloneUtils.CloneViaSerialization(value);
    using (EditForm ef = new EditForm(editValue))
        if (ef.ShowDialog() == DialogResult.OK)
            return editValue;
    return value;
}

Т.е., по сути, ICloneable это такой аналог ISerializable.
Провернуть аналогичный финт ушами с ICloneable<T> конечно можно, но, мягко говоря, не тривиально. Поэтому, кстати, IEnumerable<T> наследуется от IEnumerable.
Не очень красиво, конечно. Но альтернативой, навскидку, мне видится разве что ковариантность дженерик-интерфейсу по type parameter, чтобы ICloneable<SomeObject> можно было прокастить к ICloneable<object>, но это невозможно из-за логических нестыковок (разное направление ковариантности для in и out параметров членов).
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[3]: недостатки системы типов .NET
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.06 19:30
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>Чушь.

AF>
AF>// made by Vasya
AF>class Document : IDisposable
AF>{
AF>....
AF>}

AF>// made by Petya
AF>static class Printer
AF>{
AF>  public static Print(Document doc)
AF>    {
AF>      ...
AF>        doc.Dispose(); // опа!
AF>    }
AF>}
AF>

AF>Ну так что, документ он какой — изменяемый или неизменямый?

Тут, вобще то, архитектурная больше проблема, а не проблема реализации. Обычно в таких случаях делают read only интерфейс IDocument, и его реализацию с возможностью модификации. Одну из реализаций. А другую, вполне возможно, и без таковой.
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[5]: Нет возможности использовать константные ссылки
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.06 19:55
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Только тут есть одна сложность. По настоящему этим воспользоваться нельзя. Есть unsafe режим которому все эти модификаторы по барабану.


А есть рефлекшен, которому по барабану модификаторы доступа. И что, это делает бесполезным эти модификаторы?
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[6]: Нет возможности использовать константные ссылки
От: GlebZ Россия  
Дата: 12.11.06 20:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

GZ>>Только тут есть одна сложность. По настоящему этим воспользоваться нельзя. Есть unsafe режим которому все эти модификаторы по барабану.

AVK>А есть рефлекшен, которому по барабану модификаторы доступа. И что, это делает бесполезным эти модификаторы?
Нет, конечно. Но в данном случае поведение нельзя спрогнозировать. Например почему прикрыли генерацию нескольких строк в StringBuilder

But earlier implementations of StringBuilder actually exposed a security hole when used in this manner. It was possible to create mutable strings, where the result of StringBuilder.ToString could be modified. This was a huge security hole and it was fixed.


здесь
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[7]: Нет возможности использовать константные ссылки
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.11.06 20:31
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Например почему прикрыли генерацию нескольких строк в StringBuilder

GZ>

GZ>But earlier implementations of StringBuilder actually exposed a security hole when used in this manner. It was possible to create mutable strings, where the result of StringBuilder.ToString could be modified. This was a huge security hole and it was fixed.


Это из другой оперы.
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[7]: Нет возможности использовать константные ссылки
От: GlebZ Россия  
Дата: 12.11.06 23:33
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Вот тебе ситуация, объекты А и Б циклически связаны друг с другом:

Это плохо. Нелюблю такого, особенно если нет GC.
C>
C>struct A
C>{
C>     B *b;
C>};
C>struct B
C>{
C>     A *a;
C>};
C>


C>Если я создаю новый A, оставив у него ссылку на старый объект, то

C>получится интересная ситуация:
C>
C>A *oldA;
C>A *newA=doSomething(oldA);

C>assert(newA->b->a == newA); //WTF?????
C>


C>Чтобы ее разрулить нужно будет клонировать еще и объект B. Ну и все

C>связаные с ним объекты.
Да уж. Нехорошо. Обычно такие вещи сравнивают с помощью идентификатора.
Давай я покажу о чем я:
Давай сделаем аналогию работающую на функц. языках. Допустим задача:
Есть список объектов в котором каждый второй мы должны поменять с третьей, а после этого каждый первый с четвертым. Список имеет конструктор и три функции функции — Current(), Next(), Append(). Пишу на императивном псевдоязыке похожем на С++(чтобы было понятно всем).
list<obj> a={...}
list<obj> b=Multiply2(ChangePos23(a))
где
list<obj> ChangePos23(list<obj> a)
{
    obj& l;
    int i=0;
    list<obj> resChange=new list<obj>();
    while (a.Current()!=null)
    {
        if (i%2)
            tmp=a.Current();
        else
        if (i%3)
        { resChange.append(a.Current());
            resChange.append(l);
        }
        else
            resChange.append(a.Current());
        i++;
        a.Next();
    }
}
list<obj> Multiply2(list<obj> a)
{
    list<obj> resMult=new list<obj>();
    while (a.Current()!=null)
    {
        if (a.Current()<10)
            resMult.append(a.Current()*2);
        else
            resMult.append(a.Current());
        j++;
        a.Next();
    }
}

Чудненько и прекрасно если не считать что мы генерим каждый раз новый список. Поэтому сделаем некоторую перетрубацию, заменив в ChangePos32 append() на тело цикла в Mult2less10 и получим эквивалентный код.
list<obj> GetResult(list<obj> a)
{
    obj& l;
    int i=0;
    list<obj> res=new list<obj>();
    while (a.Current()!=null)
    {
        if (i%2)
            tmp=a.Current();
        else
        if (i%3)
        { 
            if (a.Current()<10)
                res.append(a.Current()*2);
            else
                res.append(a.Current());
            if (l<10)
                res.append(l*2);
            else
                res.append(l);
        }
        else
        {
            if (a.Current()<10)
                res.append(a.Current()*2);
            else
                res.append(a.Current());
        }
        i++;
        a.Next();
    }
}

Ну и немного подсократим вышеописанное:
void AppendResult(list<obj>& list, obj& value)
{
    if (value<10) res.append(value*2);
    else res.append(value);
}
list<obj> GetResult(list<obj> a)
{
    obj& l;
    int i=0;
    list<obj> res=new list<obj>();
    while (a.Current()!=null)
    {
        if (i%2)
            tmp=a.Current();
        else
        if (i%3)
        { 
            AppendResult(res, a.Current());
            AppendResult(res, l);
        }
        else
            AppendResult(res, a.Current());
        i++;
        a.Next();
    }
}

И код сократился и получилось что нам не понадобились промежуточные списки. И кстати, если провести аналогию до получения конечного результата, то здесь могут вообще списки не генериться. Например понадобилось на получить сумму списка, то будет:
sum AppendResult(obj sum, obj& value)
{
    if (value<10) return sum+value*2;
    else sum+value;
}
list<obj> GetResult(list<obj> a)
{
    obj& l;
    int i=0;
    obj res=0;
    while (a.Current()!=null)
    {
        if (i%2)
            tmp=a.Current();
        else
        if (i%3)
        { 
            res=AppendResult(res, a.Current());
            res=AppendResult(res, l);
        }
        else
            res=AppendResult(res, a.Current());
        i++;
        a.Next();
    }
}

То есть копирование списка как такового не понадобилось.
В данном случае мы обыграли случай транзитивности операций. Это правда не всегда возможно. Но данный подход вполне подходит и для деревьев и для графов. Просто если помнить что доступ нужно осуществлять через функциональные итераторы, то такие уравнения строятся на ура. В чистых функциональных языках такие оптимизации делаются автоматически. Но для них важно быть immutable и побочные эффекты. Если внутренний объект изменится в результате выполнения функции — то теряется вся математика, и в том числе свойства транзитивности во многих операциях.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[11]: недостатки системы типов .NET
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.11.06 01:00
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> C>Я имею в виду, что не нужны для тех целей, для которых используется const.

>> Еще раз повторюсь — const в С++ используется для разных вещей. Это
>> *перегруженное* ключевое слово.
C>Не перегружено. Разве что для констант можно было final добавить.

const используется для объявления констант, не изменяемых переменных и пометки методов признаком неизменения состояния объекта. Спорить с этим глупо. Извини, но доказывать тебе очевидные прописные истины у меня времени нет.

>> Хотя согласен, что идея помечать методы (да и классы) как неизменяемые —

>> это хорошая идея. И надо будет ее реализовать.
>А что это даст?

Возможность гарантировать, что метод не изменяет объект. Плюс в будущем компилятор может учитывать эти атрибуты чтобы автоматически распараллеливать код.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: недостатки системы типов .NET
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.11.06 01:14
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Тут попа. ICloneable обычно используется как кто так:

AVK>
AVK>object EditValue(object value)
AVK>{
AVK>    ICloneable cln = value as ICloneable;
AVK>    object editValue = cln != null ? cln.Clone : CloneUtils.CloneViaSerialization(value);
AVK>    using (EditForm ef = new EditForm(editValue))
AVK>        if (ef.ShowDialog() == DialogResult.OK)
AVK>            return editValue;
AVK>    return value;
AVK>}
AVK>

AVK>Т.е., по сути, ICloneable это такой аналог ISerializable.

Может для тебя это и обычно. Я вообще с object-ами не работаю. И для меня это не обычно. А вот типизированный Clone использовал часто.

AVK>Провернуть аналогичный финт ушами с ICloneable<T> конечно можно, но, мягко говоря, не тривиально. Поэтому, кстати, IEnumerable<T> наследуется от IEnumerable.


Он для совместимости наследуется. Лично я вообще не применяют IEnumerable.

AVK>Не очень красиво, конечно.


Почему не красиво? Вполне нормально. Все зависит от программиста. Не захочет он с обжектами возиться и не будет.

AVK> Но альтернативой, навскидку, мне видится разве что ковариантность дженерик-интерфейсу по type parameter, чтобы ICloneable<SomeObject> можно было прокастить к ICloneable<object>, но это невозможно из-за логических нестыковок (разное направление ковариантности для in и out параметров членов).


Самое смешное, что коваринтности интерфейсов нет только в Шарпе. Дотнет ее поддерживает. Но в твоем случае это безтолку. Тут дизайн приложения надо менять. Обжекты выбрасывать.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: недостатки системы типов .NET
От: AndreiF  
Дата: 13.11.06 03:46
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Тут, вобще то, архитектурная больше проблема, а не проблема реализации. Обычно в таких случаях делают read only интерфейс IDocument, и его реализацию с возможностью модификации. Одну из реализаций. А другую, вполне возможно, и без таковой.


Это то же самое, что и константная ссылка на объект, только вручную.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: недостатки системы типов .NET
От: AndreiF  
Дата: 13.11.06 03:46
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Как раз очень правильно. Потому что утилитный метод лучше делать статическим.


А почему тогда у List<T> его сделали экземплярным?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Нет возможности использовать константные ссылки
От: prVovik Россия  
Дата: 13.11.06 06:30
Оценка: -1
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, prVovik, Вы писали:


V>>Ну вот мы указали, что класс imutable. А он внутри себя пишет в лог. Как в этом случае должен поступить компилятор?


VD>Очевидно должна быть возможность пометить любой метод как безопасный с точки зрения инварианта типов программы. Так что методы вывода на консоль надо просто пометить таким атрибутом и компилятор будет пропускать его.


Вот именно, я об этом и говорю. Но чем этот подход будет отличаться от const_cast'a? Ну да, чисто с эстетической точки зрения красивее, но суть таже.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
лэт ми спик фром май харт
Re[5]: недостатки системы типов .NET
От: prVovik Россия  
Дата: 13.11.06 07:23
Оценка:
Здравствуйте, AndreiF, Вы писали:

AF>Здравствуйте, AndrewVK, Вы писали:


AVK>>Тут, вобще то, архитектурная больше проблема, а не проблема реализации. Обычно в таких случаях делают read only интерфейс IDocument, и его реализацию с возможностью модификации. Одну из реализаций. А другую, вполне возможно, и без таковой.


AF>Это то же самое, что и константная ссылка на объект, только вручную.


Зато все явно и гибко.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
лэт ми спик фром май харт
Re[6]: недостатки системы типов .NET
От: AndreiF  
Дата: 13.11.06 07:43
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Зато все явно и гибко.


И там тоже явно и гибко, только не надо каждый раз закатывать солнце вручную.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: недостатки системы типов .NET
От: WolfHound  
Дата: 13.11.06 07:59
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Коваринтность будет доступна почти везде. Можно будет отказаться от боксинга. Упростится модель абстракйий. В общем, много чего упростится. А компилятор может скомпенсировать потери в производительности.

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

VD>В общем, я считаю, что когда-то, когда уровень рантаймов и компиляторов выростет до невероятных высот такой дизайн будет самым верным (собственно дизайн Смолтока, от части). Но на время выпуска первого фрэймворка выбор МС был конечно оправдан.

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

VD>Джит уже работает в глобальном масштабе, если таковым считать масштаб процесса.

Тут придется оптимизировать весь код на машине при каждом изменении.

WH>>Ибо если на тойже виртуальной машине сделать межпроцессное общение типа как в сингулярити...

VD>И что будет? Все будет ОК. Там взаимодействие ведется неизменяемыми типами.
Неа. Там используются value типы. Причем не любые, а только те которые не содержат ссылок.
Можно конечно передовать граф объектов по значению но тут могут опять быть грабли с тем что придется тянуть очень много всего в другой процесс. Те могут быть жуткие потери производительности и памяти при безобидных изменениях.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.