Re[8]: Вот подумалось
От: reductor  
Дата: 27.11.05 16:06
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>И что? Чем этому мешает break и goto? Прекрасно можно доказывать

C>кооректность программ и с ними.

Можно, но без "прекрасно".
Я даже не хочу повторять за Edsger W. Dijkstra почему так.


>> Что касается выхода из циклов по флагам и отсутствия break, то вообще

>> не понимаю в чем проблема — что мешает вынести цикл в отдельную
>> функцию и выходить исключительно из цикла, делая код более предсказуемым?

C>Слишком много переменных может потребоваться передавать в виде параметров.


Ну наверное может. А может и нет. Или наоборот. О чем вообще мы?

C>Нет уж, сами затеяли спор — сами и показывайте код, который

C>множественный выход делает недоказуемым и вообще отстойным.

Извините, это вы говорите, что у вас есть такой код. Что он есть у меня, я не говорил.
А я такого кода не пишу.

Будем продолжать беседы о том сколько ангелов уместится на острие иголки?
Re[16]: error is not an exception
От: IT Россия linq2db.com
Дата: 27.11.05 16:41
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>В С++ сработавший assert вызывает функцию DebugBreak, так что поймать ее

C>сложно будет.

Not big deal.

#include "stdafx.h"
#include <windows.h>

void main()
{
    __try
    {
        DebugBreak();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    }
}


Все asserts идут лесом. Но дело даже не в этом. Ты собираешься на любую возможную ситуацию в программе писать assert? Этак у тебя на 10 строчек кода должно быть 20 asserts.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Вот подумалось
От: IT Россия linq2db.com
Дата: 27.11.05 17:21
Оценка: :)
Здравствуйте, reductor, Вы писали:

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


Ага, компиляторы оставлены в покое, это уже прогресс

R>А так же между количеством их работы и умственным напряжением того человека, который будет читать наш код.


Не хочешь переписать вот такой код без returns?

private static MemberMapper GetNullableMemberMapper(MapMemberInfo mi)
{
    Type type = mi.MemberAccessor.Type;

    if (type.IsGenericType == false || mi.MapValues != null)
        return null;

    Type underlyingType = Nullable.GetUnderlyingType(type);

    if (underlyingType == null)
        return null;

    if (underlyingType.IsEnum)
    {
        underlyingType = Enum.GetUnderlyingType(underlyingType);

        if (underlyingType == typeof(SByte))    return new NullableSByteMapper. Enum();
        if (underlyingType == typeof(Int16))    return new NullableInt16Mapper. Enum();
        if (underlyingType == typeof(Int32))    return new NullableInt32Mapper. Enum();
        if (underlyingType == typeof(Int64))    return new NullableInt64Mapper. Enum();
        if (underlyingType == typeof(Byte))     return new NullableByteMapper.  Enum();
        if (underlyingType == typeof(UInt16))   return new NullableUInt16Mapper.Enum();
        if (underlyingType == typeof(UInt32))   return new NullableUInt32Mapper.Enum();
        if (underlyingType == typeof(UInt64))   return new NullableUInt64Mapper.Enum();
    }
    else
    {
        if (underlyingType == typeof(SByte))    return new NullableSByteMapper();
        if (underlyingType == typeof(Int16))    return new NullableInt16Mapper();
        if (underlyingType == typeof(Int32))    return new NullableInt32Mapper();
        if (underlyingType == typeof(Int64))    return new NullableInt64Mapper();
        if (underlyingType == typeof(Byte))     return new NullableByteMapper();
        if (underlyingType == typeof(UInt16))   return new NullableUInt16Mapper();
        if (underlyingType == typeof(UInt32))   return new NullableUInt32Mapper();
        if (underlyingType == typeof(UInt64))   return new NullableUInt64Mapper();
        if (underlyingType == typeof(Char))     return new NullableCharMapper();
        if (underlyingType == typeof(Single))   return new NullableSingleMapper();
        if (underlyingType == typeof(Boolean))  return new NullableBooleanMapper();
        if (underlyingType == typeof(Double))   return new NullableDoubleMapper();
        if (underlyingType == typeof(DateTime)) return new NullableDateTimeMapper();
        if (underlyingType == typeof(Decimal))  return new NullableDecimalMapper();
        if (underlyingType == typeof(Guid))     return new NullableGuidMapper();
    }

    return null;
}
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Вот подумалось
От: IT Россия linq2db.com
Дата: 27.11.05 17:51
Оценка:
Здравствуйте, Ракот, Вы писали:

IT>>Избавиться от лишних локальных переменных — задача оптимизатора.


Р>Все, конечно, верно. Только в коде это не уберешь — теряется чистота.


Что-то я начал терять ход мыслей О каких локальных переменных идёт речь?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Что вы предлагаете на замену эксепшенов?
От: IT Россия linq2db.com
Дата: 27.11.05 17:56
Оценка: +1 :)
Здравствуйте, Mamut, Вы писали:

M>Яркий пример — разбор ХМЛя многими библиотеками. Обычно достаточно знать, что ХМЛ невалидный и сразу завершить работу:


M>Например, кусок:


А если так?

bool displayReservationCommand::execute()
{
    QDomDocument xmlDoc;
    xmlDoc.setContent(_params["data"]);

    QDomElement el = xmlDoc.documentElement();
    if(el.isNull()) return false;

    el = el.firstChild().toElement();
    if(el.isNull()) return false;

    QString str;
    QTextStream ts(str, IO_WriteOnly);

    el.save(ts, 0);
    QString attr = el.attribute("guid", "-1");
    iqAdrReservationApplicationForm::displayReservation(attr, str);
    
    return true;
}

Исключений нет, а кода даже на две строчки меньше чем у тебя
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[19]: Что вы предлагаете на замену эксепшенов?
От: IT Россия linq2db.com
Дата: 27.11.05 18:11
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>1) Вот, не надуманный пример.

СГ>2) Следующий ненадуманный пример.

Не надо обобщать косяки в реализации конкретных методов криворукими девелоперами на весь механизм исключений. Этак я могу специально для тебя написать какого-нибудь уродца на Обероне, тем самым дав твоим аппонентам в руки очень "весомые" аргументы поносить его налево и направо.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Вот подумалось
От: Cyberax Марс  
Дата: 27.11.05 18:23
Оценка:
reductor wrote:

> C>И что? Чем этому мешает break и goto? Прекрасно можно доказывать

> C>кооректность программ и с ними.
> Можно, но без "прекрасно".

Замечательно. Теперь рассказать как можно преобразовать AST с multiple
returns в AST с single returns?

> C>Слишком много переменных может потребоваться передавать в виде

> параметров.
> Ну наверное может. А может и нет. Или наоборот. О чем вообще мы?

Не знаю. Кто-то пытается мне зубы заговорить, кажется.

> C>Нет уж, сами затеяли спор — сами и показывайте код, который

> C>множественный выход делает недоказуемым и вообще отстойным.
> Извините, это вы говорите, что у вас есть такой код. Что он есть у
> меня, я не говорил.
> А я такого кода не пишу.

И судите о сложности чтения multiple returns?

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[6]: Вот подумалось
От: GlebZ Россия  
Дата: 27.11.05 19:48
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Нет, это уже религия. Все нормальные программисты уже давно перестали

C>флеймить по поводу GOTO и структурного программирования, так как по
C>нынешним меркам это уже далеко не самый главный вопрос. Все
C>программисты, которых я знаю, думают примерно так: "GOTO это плохо?" —
C>"Плохо". "Структурное программирование хорошо?" — "Да". "Единый return,
C>выход из вложенных циклов по флагам, отсутствие break — оно надо?" — "А
C>нафига?"
Честно говоря кроме структурного программирования есть еще куча стилей где goto не является противоречием. Например — автоматное программирование, на чем он и построен. Или например лисповские continuation.
Что касается множественного выхода, то противоречий я здесь не вижу. В отличие от goto его всегда можно трансформировать в классическую структурную схему.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[17]: error is not an exception
От: GlebZ Россия  
Дата: 27.11.05 19:48
Оценка:
Здравствуйте, IT, Вы писали:

IT>Все asserts идут лесом. Но дело даже не в этом. Ты собираешься на любую возможную ситуацию в программе писать assert? Этак у тебя на 10 строчек кода должно быть 20 asserts.

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

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[18]: error is not an exception
От: IT Россия linq2db.com
Дата: 27.11.05 19:58
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>В некоторых особо жарких местах у меня бывало и такое. И иногда даже помогало.


На плюсах и я таким частенько грешил На шарпе пока как-то надобности не было.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[19]: error is not an exception
От: GlebZ Россия  
Дата: 27.11.05 20:13
Оценка:
Здравствуйте, IT, Вы писали:

IT>На плюсах и я таким частенько грешил На шарпе пока как-то надобности не было.

При отладке windows сервисов вставлял в код даже не assert, а прямой вызов дебаггера.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[20]: error is not an exception
От: IT Россия linq2db.com
Дата: 27.11.05 20:23
Оценка: +1
Здравствуйте, GlebZ, Вы писали:

IT>>На плюсах и я таким частенько грешил На шарпе пока как-то надобности не было.

GZ>При отладке windows сервисов вставлял в код даже не assert, а прямой вызов дебаггера.

Это другой случай. При разработке UI иногда даже два монитора не помогают, если надо с фокусом повозиться, который постоянно уходит в отладчик. Приходится по старинке выводить всё что нужно в лог. Но это всё 5-10% случаев.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[23]: Что вы предлагаете на замену эксепшенов?
От: IT Россия linq2db.com
Дата: 27.11.05 21:12
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Ну, значит, вот так:


А теперь добавь сюда какую-нибудь вменяемую информацию об ошибке, сделай так чтобы TransferMoney возвращала новый баланс счёта и протащи это через 4-5 вызовов.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[25]: Что вы предлагаете на замену эксепшенов?
От: Sergey J. A. Беларусь  
Дата: 27.11.05 21:35
Оценка: 1 (1)
Здравствуйте, Cyberax, Вы писали:

C>так как приложение в ответ на него

C>может удалить часть данных (почистить кэши, например)

Сдаётся мне, что нужно такие объекты держать как Weak Reference, а не чистить по исключению.
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[11]: Вот подумалось
От: reductor  
Дата: 27.11.05 21:53
Оценка: 40 (1)
Здравствуйте, IT, Вы писали:

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


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


IT>Ага, компиляторы оставлены в покое, это уже прогресс


R>>А так же между количеством их работы и умственным напряжением того человека, который будет читать наш код.


IT>Не хочешь переписать вот такой код без returns?


Ок. Только сразу предупреждаю, я вообще не знаю C# (как и .NET), потому пришлось msdn почитать.
Могут быть ошибки (как в оптимальности реализации, так и в понимании логики того, что здесь происходит), но в общем вроде все так.
private static MemberMapper MapperFromTC (TypeCode tc) {
    MemberMapper value;
    switch (tc) {
        case TypeCode.SByte: value = new NullableSByteMapper(); break;
        case TypeCode.Int16: value = new NullableInt16Mapper(); break;
        case TypeCode.Int32: value = new NullableInt32Mapper(); break;
        case TypeCode.Int64: value = new NullableInt64Mapper(); break;
        case TypeCode.Byte: value = new NullableByteMapper(); break;
        case TypeCode.UInt16: value = new NullableUInt16Mapper(); break;
        case TypeCode.UInt32: value = new NullableUInt32Mapper(); break;
        case TypeCode.UInt64: value = new NullableUInt64Mapper(); break;
        case TypeCode.Char: value = new NullableCharMapper(); break;
        case TypeCode.Single: value = new NullableSingleMapper(); break;
        case TypeCode.Boolean: value = new NullableBooleanMapper(); break;
        case TypeCode.Double: value = new NullableDoubleMapper(); break;
        case TypeCode.DateTime: value = new NullableDateTimeMapper(); break;
        case TypeCode.Decimal: value = new NullableDecimalMapper(); break;
        case TypeCode.Guid: value = new NullableGuidMapper(); break;
        default: value = null; break;
    }
    return value;
}

private static MemberMapper GetNullableMemberMapper(MapMemberInfo mi) {
    Type type = mi.MemberAccessor.Type;
    MemberMapper value;
    
    if (type.IsGenericType == true && mi.MapValues == null) {
        Type underlyingType = Nullable.GetUnderlyingType(type);
        if (underlyingType != null) {
            value = MapperFromTC(underlyingType.IsEnum
                    ? underlyingType.GetTypeCode()
                    : Type.GetTypeCode(underlyingType)); 
        } else {
            value = null;
        }
    } else {
        value = null;
    }
    return value;
}


Если интересен был proof-of-concept, то вот. Ничего, что я добавил "лишнюю" функцию? а то читать было сложновато.
В общем-то в case-ах и if'ах можно было и return'ы оставить (вариантов без них не остается), но чтобы лишнего флейма избежать, я сделал с переменной.
Хотя идеально бы конечно было, если бы switch возвращал значение. Но так зато можно дополнительно в выводить в лог mm перед каждым возвратом. и то хлеб. Надеюсь, больше на C# ничего делать не придется.
Re[12]: Вот подумалось
От: IT Россия linq2db.com
Дата: 27.11.05 22:23
Оценка:
Здравствуйте, reductor, Вы писали:

R>Ок. Только сразу предупреждаю, я вообще не знаю C# (как и .NET), потому пришлось msdn почитать.


Совсем не плохо для начала, хотя я просил повторить в точности то что есть, а не самовольничать

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


Тут две проблемы.
1. Для типа Guid не существует TypeCode.
2. Для перечислений создаются другие мапперы, т.е. нужна будет ещё одна функция.

Но даже и в таком виде очень хорошо видно, что наглядность кода не возрасла. К тому же можно было бы предложить вариант для SqlTypes: SqlInt16, SqlInt32 и т.п. для которых нет TypeCodes.

R>Если интересен был proof-of-concept, то вот. Ничего, что я добавил "лишнюю" функцию? а то читать было сложновато.


То-то и оно.

R>Надеюсь, больше на C# ничего делать не придется.


... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: Вот подумалось
От: reductor  
Дата: 27.11.05 22:49
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>reductor wrote:


>> C>И что? Чем этому мешает break и goto? Прекрасно можно доказывать

>> C>кооректность программ и с ними.
>> Можно, но без "прекрасно".

C>Замечательно. Теперь рассказать как можно преобразовать AST с multiple

C>returns в AST с single returns?

при чем здесь AST?
по вашему, исходя из этого:
if (cond) return 1
return 0

можно утверждать, что имелось в виду это:
if (cond) return 1
else return 0
?
а под этим:
if (cond1) 
   if (cond2) return 2
return 0

подразумевалось без сомнения это:
if (cond1)
   if (cond2) return 2
   else return 0
else return 0

?

Или я говорил, что код с несколькими стейтментами return не может работать корректно?
или что его нельзя в AST трансформировать во что-то там? Или что его нельзя скомпилировать?
Я утверждал, что без явной обработки всех условий вероятность ошибки и последующая с этим возня могут возрасти многократно.
Без нее где-нибудь код будет ждать вариант, который функция никогда не возвращает, потому что кто-то написал красивый трансформер для AST, который тем не менее вряд ли умеет еще и проверять возвращает ли функция все возможные значения или только половину из них.


>> C>Слишком много переменных может потребоваться передавать в виде

>> параметров.
>> Ну наверное может. А может и нет. Или наоборот. О чем вообще мы?

C>Не знаю. Кто-то пытается мне зубы заговорить, кажется.


По-моему кто-то не держит себя в руках. Код со многими переменными можно глянуть?.

>> C>Нет уж, сами затеяли спор — сами и показывайте код, который

>> C>множественный выход делает недоказуемым и вообще отстойным.
>> Извините, это вы говорите, что у вас есть такой код. Что он есть у
>> меня, я не говорил.
>> А я такого кода не пишу.

C>И судите о сложности чтения multiple returns?


Да, переубедите меня. Покажите обратное.
Re[13]: Вот подумалось
От: reductor  
Дата: 27.11.05 22:58
Оценка:
Здравствуйте, IT, Вы писали:

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


R>>Ок. Только сразу предупреждаю, я вообще не знаю C# (как и .NET), потому пришлось msdn почитать.


IT>Совсем не плохо для начала, хотя я просил повторить в точности то что есть, а не самовольничать


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


IT>Тут две проблемы.

IT>1. Для типа Guid не существует TypeCode.

ну можно в default там добавить проверку на Guid дополнительно, вроде

IT>2. Для перечислений создаются другие мапперы, т.е. нужна будет ещё одна функция.

А.. точно, я не заметил вызовы .Enum()
Можно передавать вторым параметром флаг и перед возвратом, если true и != null, то вернуть value.Enum()
Или что-нибудь такое. Наверняка есть миллион способов не дублировать кучу кода

IT>Но даже и в таком виде очень хорошо видно, что наглядность кода не возрасла. К тому же можно было бы предложить вариант для SqlTypes: SqlInt16, SqlInt32 и т.п. для которых нет TypeCodes.


Создать свой Enum с необходимым набором?
Re[14]: Вот подумалось
От: IT Россия linq2db.com
Дата: 27.11.05 23:03
Оценка: :)
Здравствуйте, reductor, Вы писали:

R>Создать свой Enum с необходимым набором?


Ну переедут if'ы в другое место. А в том месте делать return или через переменную?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[15]: Вот подумалось
От: reductor  
Дата: 27.11.05 23:11
Оценка:
Здравствуйте, IT, Вы писали:

как-то так. ну или сделать уже свой Enum, чтобы без костылей.

Блин, хотел подредактировать форматирование, а получилось как всегда . IT.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.