Re[4]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 10.09.10 18:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

G>>
G>>var x1 = Method1();
G>>if(x1 == null) return null;
G>>var x2 = x1.Method2();
G>>if(x2 == null) return null;
G>>var x3 = x2.Method3();
G>>if(x3 == null) return null;
G>>return x3.Method4();
G>>

S>Стесняюсь показаться ретроградом, но имхо этот "водопроводный" код менее многословен и более понятен, чем предложенная альтернатива. Можно показать мне, как классно будет записан вызов
S>
S>var x = Method1().Method2().Method3().Method4();
S>

S>так, чтобы в случае возврата null из любого из методов вместо NRE мы получили null в x?
Для честного сравнения надо сначала переписать "водопроводный" код "так, чтобы в случае возврата null из любого мы получили null в x".
Re[5]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 10.09.10 19:01
Оценка:
Здравствуйте, samius, Вы писали:

S>
S>    class Program
S>    {
S>        static IOptionalValue<A> TestV1()
S>        {
S>            return from x1 in Method1().ToOptionalValue()
S>                   from x2 in x1.Method2().ToOptionalValue()
S>                   from x3 in x2.Method3().ToOptionalValue()
S>                   select x3.Method4();
S>        }
S>        static IOptionalValue<A> TestV2()
S>        {
S>            return Method1().ToOptionalValue().SelectMany(x1 =>
S>                x1.Method2().ToOptionalValue().SelectMany(x2 =>
S>                x2.Method3().ToOptionalValue().SelectMany(x3 =>
S>                x3.Method4().ToOptionalValue())));
S>        }
S>    }
S>

S>Я лишь показал. Не настаиваю на том что это понятнее.
Все гораздо проще:
Method1()
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method3());
Re[6]: Optional Value. Уменьшение количества null reference-
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.10 19:05
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

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


S>>
S>>    class Program
S>>    {
S>>        static IOptionalValue<A> TestV1()
S>>        {
S>>            return from x1 in Method1().ToOptionalValue()
S>>                   from x2 in x1.Method2().ToOptionalValue()
S>>                   from x3 in x2.Method3().ToOptionalValue()
S>>                   select x3.Method4();
S>>        }
S>>        static IOptionalValue<A> TestV2()
S>>        {
S>>            return Method1().ToOptionalValue().SelectMany(x1 =>
S>>                x1.Method2().ToOptionalValue().SelectMany(x2 =>
S>>                x2.Method3().ToOptionalValue().SelectMany(x3 =>
S>>                x3.Method4().ToOptionalValue())));
S>>        }
S>>    }
S>>

S>>Я лишь показал. Не настаиваю на том что это понятнее.
AP>Все гораздо проще:
AP>Method1()
AP>    .ProcessValue(_ => _.Method2())
AP>    .ProcessValue(_ => _.Method2())
AP>    .ProcessValue(_ => _.Method3());
AP>


Все не так просто.
На самом деле твой код, как и мой в TestV1 не прекратит вычисления при получении null-а. В MethodX он не зайдет, но ProcessValue будет вызван столько раз, сколько написано (то же касается SelectMany из TestV1).

А TestV2 действительно закончит вычисления при получении null-а.
Re[6]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 10.09.10 19:07
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

Забыл присвоение:
var x = Method1()
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method3());
Re[7]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 10.09.10 19:18
Оценка:
Здравствуйте, samius, Вы писали:

Во-первых, я полагал, что все понимают, что при переходе на OptionalVallue null-ы надо заменять на Nothing.

S>Все не так просто.

S>На самом деле твой код, как и мой в TestV1 не прекратит вычисления при получении null-а. В MethodX он не зайдет, но ProcessValue будет вызван столько раз, сколько написано (то же касается SelectMany из TestV1).
S>А TestV2 действительно закончит вычисления при получении null-а.
А зачем считать количество заходов в метод?

S>... В MethodX он не зайдет...

И это главное .
Re[8]: Optional Value. Уменьшение количества null reference-
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.10 19:27
Оценка: +1
Здравствуйте, Alexander Polyakov, Вы писали:

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


AP>Во-первых, я полагал, что все понимают, что при переходе на OptionalVallue null-ы надо заменять на Nothing.

А для чего тебе тогда SelectMany?

S>>Все не так просто.

S>>На самом деле твой код, как и мой в TestV1 не прекратит вычисления при получении null-а. В MethodX он не зайдет, но ProcessValue будет вызван столько раз, сколько написано (то же касается SelectMany из TestV1).
S>>А TestV2 действительно закончит вычисления при получении null-а.
AP>А зачем считать количество заходов в метод?

S>>... В MethodX он не зайдет...

AP>И это главное .
Когда делали Query синтакс, тоже так посчитали. А по-моему это лажа, заходить в методы, которые не учавствуют в вычислениях.
Re[9]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 10.09.10 20:12
Оценка:
Здравствуйте, samius, Вы писали:

AP>>Во-первых, я полагал, что все понимают, что при переходе на OptionalVallue null-ы надо заменять на Nothing.

S>А для чего тебе тогда SelectMany?
Второй из перегруженных методов SelectMany нужен для query comprehension syntax. А первый вводился уже в дополнение, для полной аналогии с LINQ. В принципе, его можно убрать. Спасибо за замечание.

При всем при этом разноименные методы SelectMany и Select часто менее удобны, чем одноименные методы с такими же сигнатурой и смыслом, поэтому есть два метода ProcessValue. Вариант без ProcessValue и переименование первого SelectMany в Select тоже рассматривался ... .
Re[10]: Optional Value. Уменьшение количества null reference
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.10 20:26
Оценка: +1
Здравствуйте, Alexander Polyakov, Вы писали:

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


AP>>>Во-первых, я полагал, что все понимают, что при переходе на OptionalVallue null-ы надо заменять на Nothing.

S>>А для чего тебе тогда SelectMany?
AP>Второй из перегруженных методов SelectMany нужен для query comprehension syntax. А первый вводился уже в дополнение, для полной аналогии с LINQ. В принципе, его можно убрать. Спасибо за замечание.
Странно, что тебе оказался не нужен класический монадный bind (>>=), а сгодился его странноватый гибрид с проекцией.

AP>При всем при этом разноименные методы SelectMany и Select часто менее удобны, чем одноименные методы с такими же сигнатурой и смыслом, поэтому есть два метода ProcessValue. Вариант без ProcessValue и переименование первого SelectMany в Select тоже рассматривался ... .

Т.е. фактически bind в map? Хотел всех запутать?
Re[11]: Optional Value. Уменьшение количества null reference
От: Alexander Polyakov  
Дата: 10.09.10 21:08
Оценка:
Здравствуйте, samius, Вы писали:

AP>>>>Во-первых, я полагал, что все понимают, что при переходе на OptionalVallue null-ы надо заменять на Nothing.

S>>>А для чего тебе тогда SelectMany?
AP>>Второй из перегруженных методов SelectMany нужен для query comprehension syntax. А первый вводился уже в дополнение, для полной аналогии с LINQ. В принципе, его можно убрать. Спасибо за замечание.
S>Странно, что тебе оказался не нужен класический монадный bind (>>=), а сгодился его странноватый гибрид с проекцией.
Метод нужен, вопрос лишь в его имени и в перегрузке с другими.

AP>>При всем при этом разноименные методы SelectMany и Select часто менее удобны, чем одноименные методы с такими же сигнатурой и смыслом, поэтому есть два метода ProcessValue. Вариант без ProcessValue и переименование первого SelectMany в Select тоже рассматривался ... .

S>Т.е. фактически bind в map? Хотел всех запутать?
Монады монадами, а c OptionalValue удобнее работать через одноименные методы. Из примера выше:
var x = Method1()
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method3())
    .ProcessValue(_ => _.Method4());
Здесь любой из методов MethodX может возвращать как T так и IOptionalValue<T> запись от этого не меняется. И это классно .
Re[12]: Optional Value. Уменьшение количества null reference
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.09.10 21:33
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

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


S>>Странно, что тебе оказался не нужен класический монадный bind (>>=), а сгодился его странноватый гибрид с проекцией.

AP>Метод нужен, вопрос лишь в его имени и в перегрузке с другими.
Я привык отождествлять деятельность метода с названием. Если я знаю что короткий SelectMany это bind, а Select — это map, то любые перемены будут мешать.

S>>Т.е. фактически bind в map? Хотел всех запутать?

AP>Монады монадами, а c OptionalValue удобнее работать через одноименные методы. Из примера выше:
AP>
AP>var x = Method1()
AP>    .ProcessValue(_ => _.Method2())
AP>    .ProcessValue(_ => _.Method3())
AP>    .ProcessValue(_ => _.Method4());
AP>
Здесь любой из методов MethodX может возвращать как T так и IOptionalValue<T> запись от этого не меняется. И это классно .


Не вижу ничего классного. Перемешаны монадные bind-ы с функторами, визуально не отличить что где.

Но самое что интересное, для такой записи не нужны OptionalValue<T>.
static TResult ProcessValue<T, TResult>(this T value, Func<T, TResult> func)
   where T : class
   where TResult : class
{
     return (value != null) ? func(value) : default(TResult);
}
Re[14]: Optional Value. Уменьшение количества null reference
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.09.10 22:39
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

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


G>>>>А на деле не нужна.

AP>>>Ковариантность нужна! Там где обычный полиморфизм + option логика = получаем необходимость ковариантности.
G>>Бред же.
AP>В чем заключается бред, объяснить можешь?
В том что необходимости ковариантности нету. Вообще вариантность заменяется обычным приведением типа.

G>>>>Я собственно и до .NET4 не испытывал проблем из-за отсутствия ковариантности интерфейсов, где надо проделывал приведение типа ручками.

AP>>>Прописывать ковариантность ручками для option логики непозволительный синтаксический оверхед.
G>>Счегобы? Ты даже не смог пример привести где ковариантность была тебе необходима.
AP>Не ври. Я не увидел зачем мне напрягаться. Пример потребует некоторых временных затрат. А ты опять не поймешь суть и прицепишься к несущественным моментам. Поэтому углубляться здесь на форуме в кастомные задачи я смысла не вижу. Если, действительно, есть желание, приходи к нам в офис, я тебе покажу код с моего экрана, а потом поговорим по коду.
Запости код сюда и поговорим здесь. А то пока только голословные утверждения о необходимости ковариантности.
Re[4]: Optional Value. Уменьшение количества null reference-
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.09.10 22:44
Оценка:
Здравствуйте, Sinclair, Вы писали:

G>>
G>>var x1 = Method1();
G>>if(x1 == null) return null;
G>>var x2 = x1.Method2();
G>>if(x2 == null) return null;
G>>var x3 = x2.Method3();
G>>if(x3 == null) return null;
G>>return x3.Method4();
G>>

S>Стесняюсь показаться ретроградом, но имхо этот "водопроводный" код менее многословен и более понятен, чем предложенная альтернатива. Можно показать мне, как классно будет записан вызов
S>
S>var x = Method1().Method2().Method3().Method4();
S>

S>так, чтобы в случае возврата null из любого из методов вместо NRE мы получили null в x?

var x = from x1 in Method1().ToOption()
        from x2 in x1.Method2().ToOption()
        from x3 in x2.Method3().ToOption()
        select x3.Method4();


Естественно куча ифов, как выше — это самый простой случай частичных вычислений. Option<T> позволяет не только чуть более лаконично описывать это безобразие, но и декомпозировать его.
Re[4]: Optional Value. Уменьшение количества null reference-
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.09.10 22:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Стесняюсь показаться ретроградом, но имхо этот "водопроводный" код менее многословен и более понятен, чем предложенная альтернатива.


Монада List (Linq 2 Objects) относится к циклам определенного вида, примерно как монада Maybe (Option) к ифам определенного вида. При грамотном использовании позволяет сделать код более наглядным и не прятать логику под тоннами управляющих конструкций.
Re[13]: Optional Value. Уменьшение количества null reference
От: Alexander Polyakov  
Дата: 11.09.10 00:12
Оценка:
Здравствуйте, samius, Вы писали:

S>Я привык отождествлять деятельность метода с названием.

Это хорошо.

S>Если я знаю что короткий SelectMany это bind, а Select — это map, то любые перемены будут мешать.

А тут как раз идет отождествление названия с названием.

S>Не вижу ничего классного. Перемешаны монадные bind-ы с функторами, визуально не отличить что где.

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

S>Но самое что интересное, для такой записи не нужны OptionalValue<T>.

Ага, я это знаю . Только остается вопрос, когда такой записью пользоваться? Для всех переменных? Нет, спасибо, не буду.
OptionalValue как раз и служит для разделение опциональных и не опциональных переменных. Соответственно, для первых применяем такую запись, а для вторых обычную. А какой будет переменная T или IOptionalValue<T> определяет поставщик переменной. Если мы знаем, что поставщик соблюдает это правило, то для T можно не беспокоиться об NRE. Если поставщик не соблюдает это правило, то все как обычно, т.е. хреново: писать или не писать if, если писать, то, что внутри этого if-а делать и т.д. Глупость заключается в том, чтобы создавать эту хреновую ситуацию и в случае, если вы сами являетесь тем поставщиком.
Re[8]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 11.09.10 00:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>>>>>Проблема этого интерфейса что он не энфорсит контракт, это при том что кроме Some\Just и None реализаций не нужно. Но я могу сколько угодно своих реализаций подсовывать.

AP>>>>>>Это замечание незначительно само по себе,
G>>>>>Да ну? Сломать контракт это фигня?
AP>>>>Какой контракт? Ты вообще о чем? Нет у меня никакого контракта. Ломать нечего!
G>>>
AP>>Что тебя так рассмешило?
G>То что у тебя нет контракта.

G>>>... а все вместе — нет.

AP>>Код в студию.

G>Держи


G>
G>class Ololo<T>: IOptionalValue<T>
G>{
G>    public TResult Process<TResult>(Func<T, TResult> existFunc, Func<TResult> notExistFunc)
G>    {
G>        return default(TResult);
G>    }
G>}
G>

Ответа на мой вопрос:

где, что не работает?
http://rsdn.ru/forum/design/3953905.1.aspx

нету. Поэтому в этой ветке ты молча слил, я правильно понимаю?
Re[9]: Optional Value. Уменьшение количества null reference-
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.09.10 07:08
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

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


G>>>>>>>>Проблема этого интерфейса что он не энфорсит контракт, это при том что кроме Some\Just и None реализаций не нужно. Но я могу сколько угодно своих реализаций подсовывать.

AP>>>>>>>Это замечание незначительно само по себе,
G>>>>>>Да ну? Сломать контракт это фигня?
AP>>>>>Какой контракт? Ты вообще о чем? Нет у меня никакого контракта. Ломать нечего!
G>>>>
AP>>>Что тебя так рассмешило?
G>>То что у тебя нет контракта.

G>>>>... а все вместе — нет.

AP>>>Код в студию.

G>>Держи


G>>
G>>class Ololo<T>: IOptionalValue<T>
G>>{
G>>    public TResult Process<TResult>(Func<T, TResult> existFunc, Func<TResult> notExistFunc)
G>>    {
G>>        return default(TResult);
G>>    }
G>>}
G>>

AP>Ответа на мой вопрос:

AP>где, что не работает?
AP>http://rsdn.ru/forum/design/3953905.1.aspx


AP>нету. Поэтому в этой ветке ты молча слил, я правильно понимаю?
Не веди себя как дите.
При такой реализации IOptionalValue метода HasValue вернет false, а GetValue не бросит исключение. Я еще не проверял как у тебя Linq в таком случае заработает.

Это и есть контракт, который у тебя не энфорсится никак.
Re[9]: Optional Value. Уменьшение количества null reference-
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.09.10 07:16
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

Кстати, ты поставил минус на это сообщение
Автор: gandjustas
Дата: 10.09.10
, но не удосужился написать ответ.
Молча слил?
Re[5]: Optional Value. Уменьшение количества null reference-
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.09.10 07:57
Оценка: +2
Здравствуйте, Alexander Polyakov, Вы писали:
AP>Для честного сравнения надо сначала переписать "водопроводный" код "так, чтобы в случае возврата null из любого мы получили null в x".
Ну давайте перепишем:
Type1 x = null;
var x1 = Method1();
if(x1 != null) 
{ 
  var x2 = x1.Method2();
  if(x2 != null) 
  { 
    var x3 = x2.Method3();
    if(x3 != null) 
    x = x3.Method4();
  }
}

Это что-то принципиально поменяет?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 11.09.10 18:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

AP>>Для честного сравнения надо сначала переписать "водопроводный" код "так, чтобы в случае возврата null из любого мы получили null в x".

S>Ну давайте перепишем:
S>
S>Type1 x = null;
S>var x1 = Method1();
S>if(x1 != null) 
S>{ 
S>  var x2 = x1.Method2();
S>  if(x2 != null) 
S>  { 
S>    var x3 = x2.Method3();
S>    if(x3 != null) 
S>    x = x3.Method4();
S>  }
S>}
S>

S>Это что-то принципиально поменяет?
Опа, вместо просто инициализации переменной получили изменяемое состояние. В исходном “водопроводном” варианте изменяемого состояния не было!

Просто инициализация выглядит так:
Type1 x;
var x1 = Method1();
if (x1 == null)
    x = null;
else
{
    var x2 = x1.Method2();
    if (x2 == null)
        x = null;
    else
    {
        var x3 = x2.Method3();
        if (x3 == null)
            x = null;
        else
            x = x3.Method4();
    }
}


Далее:
  1. Надо ли показывать к каким косякам может привести изменяемое состояние в данном случае?
  2. В каком варианте будем подсчитывать многословность (количество слов)?

Вариант c OptionalValue:
var x = Method1()
    .ProcessValue(_ => _.Method2())
    .ProcessValue(_ => _.Method3())
    .ProcessValue(_ => _.Method4());


При подсчете количества слов у меня получилось, что вариант c OptionalValue побеждает любой из трех вариантов с if-ами. Детали подсчета оформлю в виде текста и запощу, если это потребуется.
Re[2]: Optional Value. Уменьшение количества null reference-
От: Alexander Polyakov  
Дата: 11.09.10 19:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Не очень понятен смысл неиспользования null-ов. Проблема, я так понимаю, в том, что NRE упадёт слишком поздно?

Смысл -- сделать безопасным базовый/основополагающий прием трансформации кода Extract Method. Т.е. избежать катастрофы при использовании Extract Method, которая описана в первом посте.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.