Re[20]: C# 6.0
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.12.13 18:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


S>>Да. Но почему компонентные модели должны ломаться от совместимых типов?


AVK>Потому что они про эту совместимость ничего не знают и будут выкидывать TypeCastException.

Мы обсуждаем два варианта. 1) где совместимые типы будут подменены в рантайме, тогда мы получим лишь один тип для всех совместимых. 2) где совместимые типы маппятся. Где тут приведения типов?
Re[7]: C# 6.0
От: AlexRK  
Дата: 28.12.13 18:54
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Вызов метода с побочными эффектами это уже выражение, как-то живем с этим.


Ну, это ничего не значит. Много с чем живем, например с нуллабельными по умолчанию ссылками, что есть бред.

Z>Цикл можно рассмотреть, как частный случай выражения, который возвращает void. Это не тупее, чем отказ от разделения на function и procedure.


На мой взгляд, разделение концептуально гораздо чище.
Re[7]: C# 6.0
От: AlexRK  
Дата: 28.12.13 19:00
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Этот принцип формирует правильную культуру ветвления алгоритма. Сводит к минимуму использование мутабельных переменных


Не понимаю, каким образом.

Z>В таком коде сделать ошибку сложнее, а заметить проще, это большой плюс.


По-моему, ровно наоборот. В выражении пропустить побочный эффект гораздо проще, чем когда он один гордо красуется на одной строке.

Z>Второй вариант о смысле кода говорит больше, чем первый. Во втором варианте сразу видно, что а может иметь два значения в зависимости от условия. В первом варианте мы только строим гипотезы в процессе чтения.


Это-то понятно, и наличие в языке if/switch в виде выражений исключительно полезно. А вот нафига циклы и процедуры в виде выражений?

Z>На закуску попробуй переписать код на языке, в котором using не является выражением:

Z>
Z>var x = using (var db = new Db())
Z>{
Z>  (from a in db.Table1
Z>  from b in db.Table2
Z>  from c in db.Table3
Z>  select new {a.X, b.Y, c.Relation1.GroupBy(x => x.Z)}).ToArray();
Z>}
Z>CallMethodWithArgument(x);
Z>

Z>Типы не важны, можешь взять любые, с которыми код скомпилируется.

MyType x;
using (var db = new Db())
{
  x = (from a in db.Table1
  from b in db.Table2
  from c in db.Table3
  select new {a.X, b.Y, c.Relation1.GroupBy(x => x.Z)}).ToArray();
}
CallMethodWithArgument(x);


Re[23]: C# 6.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.12.13 19:43
Оценка:
Здравствуйте, samius, Вы писали:

AVK>>Так тут чисто логическая проблема — если тип появляется внутри метода, то, естественно, снаруж о нем никто не знает.

S>Это естественно сейчас, и мы обсуждаем как раз способ уйти от такой естественности.

Я не очень понимаю, зачем от нее уходить. Вот зачем нужна инлайн декларация типа — понятно. А вот так чтобы именно сконструированный по использованию тип в контракты тащить — вот тут смысл для меня теряется.

S>Мы сейчас не можем снаружи передать операцию проекции, конструирующую анонимный тип


Ты уверен? Ты то ли как то опять странно объясняешь, то ли почему то считаешь что в обычном линке использовать анонимные типы в предикатах нельзя.

AVK>>Он использует ту самую компонентную модель, которая сейчас ничего не знает про хитрую структурную эквивалентность некоторых типов.

S>Влад предлагает делать подмену типов в рантайме. Потому PropertyGrid-ы не узнают об этих хитростях.

Именно поэтому — узнают.

AVK>>Еще раз — анонимный тип сейчас это абсолютно обычный тип, поэтому и проблем с ним нет.

S>Да, и структурно-эквивалентный тип будет абсолютно обычным типом.

Не будет. Если бы он был обычным, не понадобилось бы менять рантайм.

S>Можно пример, когда не удастся понять, нужно ли меппинг делать?


Можно
var x = new <A int, B string>(1, "1");
var y = Foo(); // вызывает "new <A int, B string>(1, "1")" из другой сборки
Console.WriteLine(x == y); // компилятор знает типы, вызывается меппер, выводится True
Console.WriteLine((object)x == (object)y); // компилятор не знает типы, сравниваются ссылки, выводится False
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[21]: C# 6.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.12.13 19:54
Оценка:
Здравствуйте, samius, Вы писали:

S>Мы обсуждаем два варианта. 1) где совместимые типы будут подменены в рантайме, тогда мы получим лишь один тип для всех совместимых. 2) где совместимые типы маппятся. Где тут приведения типов?


С подменой в рантайме понятно, вопрос только в том как эта подмена будет проводится. В от как ты будешь мапперы вставлять без изменения компонетных моделей, учитывая что у них в качестчве значений сплошь object используется мне непонятно.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[5]: C# 6.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 28.12.13 19:54
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Функционально-императивным кентавром он стал после введения лямбд.


И что такого принципиально нового добавили лямбды по сравнению с анонимными методами?
Функционально-императивным шарп делают не столько его фичи, сколько то как его используют, коммьюнити в том числе. Поэтому очень странно претензии предъявлять МС. Если бы с функциональщиной были какие то серьезные проблемы, она бы просто не использовалась бы особо.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: C# 6.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.12.13 02:39
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Это-то понятно, и наличие в языке if/switch в виде выражений исключительно полезно. А вот нафига циклы и процедуры в виде выражений?


Для концептуальной стройности. Да и на практике это может быть полезно. Вот код на Nemerle:
def result =
  namedBlok : {
    foreach (x when Test(x) in xs)
      namedBlok(x); // нечто типа локального return-а.
    -1 // значение по умолчанию
  };
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[24]: C# 6.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.12.13 02:44
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Можно

AVK>
AVK>var x = new <A int, B string>(1, "1");
AVK>var y = Foo(); // вызывает "new <A int, B string>(1, "1")" из другой сборки
AVK>Console.WriteLine(x == y); // компилятор знает типы, вызывается меппер, выводится True
AVK>Console.WriteLine((object)x == (object)y); // компилятор не знает типы, сравниваются ссылки, выводится False
AVK>


"(object)x == (object)y" — это проверка равенства ссылок. Она всегда false должна дать. Вот если "x.Equals(y)", то другое дело.

Но тут как проблем не будет. Equals и GetHeshCode для структурно эквивалентных типов нужно подменять, а так же реализовывать у них IEquatable<T>.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: C# 6.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.12.13 02:47
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

AVK>И что такого принципиально нового добавили лямбды по сравнению с анонимными методами?


Это странный вопрос для человека который видит огромную разницу между Разером и Т4.

Синтаксис. Писать в функциональном стиле с анонимными методами очень некрасиво. Код получается громоздким.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: C# 6.0
От: Ziaw Россия  
Дата: 29.12.13 12:18
Оценка:
Здравствуйте, AlexRK, Вы писали:

Z>>Этот принцип формирует правильную культуру ветвления алгоритма. Сводит к минимуму использование мутабельных переменных


ARK>Не понимаю, каким образом.


Я приводил пример с if, там мы вынуждены вводить мутабельную переменную, хотя алгоритм этого не требует.

ARK>По-моему, ровно наоборот. В выражении пропустить побочный эффект гораздо проще, чем когда он один гордо красуется на одной строке.


Выражение не обязано быть на одной строке.

ARK>Это-то понятно, и наличие в языке if/switch в виде выражений исключительно полезно. А вот нафига циклы и процедуры в виде выражений?


void это обычная абстракция. Она позволяет не плодить сущности. При разделении на функции и процедуры нам нужны разные механизмы для их передачи в другие функции/процедуры и работы с ними.

Z>>На закуску попробуй переписать код на языке, в котором using не является выражением:

ARK>
ARK>MyType x;
ARK>using (var db = new Db())
ARK>{
ARK>  x = (from a in db.Table1
ARK>  from b in db.Table2
ARK>  from c in db.Table3
ARK>  select new {a.X, b.Y, c.Relation1.GroupBy(x => x.Z)}).ToArray();
ARK>}
ARK>CallMethodWithArgument(x);
ARK>


ARK> :xz

Вот и я хз, как ты умудряешься кастить массив анонимных типов к MyType.
Re[6]: C# 6.0
От: Ziaw Россия  
Дата: 29.12.13 14:55
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>И что такого принципиально нового добавили лямбды по сравнению с анонимными методами?


Сахар, после которого их использование стало массовой практикой.

AVK>Функционально-императивным шарп делают не столько его фичи, сколько то как его используют, коммьюнити в том числе. Поэтому очень странно претензии предъявлять МС. Если бы с функциональщиной были какие то серьезные проблемы, она бы просто не использовалась бы особо.


Я тут с тобой полностью согласен и никаких претензий МС не предъявляю. Тебе показалось.
Re: C# 6.0
От: Albeoris  
Дата: 29.12.13 15:18
Оценка:
Здравствуйте, Аноним, Вы писали:

// Неплохо.
public int X { get; } = x;

// А зачем? о.о
public Point Move(int dx, int dy) => new Point(X + dx, Y + dy);

// Пригодится.
public Point Average(params IEnumerable<Point> points) { }

// О даааааааааааааа! ^____________^
if (points?.FirstOrDefault()?.X ?? -1) { }

// Удобно.
var t = new Tuple(1,2); // infers Tuple<T1, T2>

// Хмммм... А как это работает? С generic-ами всё ясно, а тут...
public void Foo(out var x, out var y) { }
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re[9]: C# 6.0
От: AlexRK  
Дата: 29.12.13 15:58
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Я приводил пример с if, там мы вынуждены вводить мутабельную переменную, хотя алгоритм этого не требует.


Пример с if не является признаком подхода "все есть выражение", он может быть повторен на любом мейнстримовом языке.

Z>Выражение не обязано быть на одной строке.


Я в этом месте говорю как раз про запрет выражений с побочными эффектами — вот это действительно сделало бы проще поиск некоторых типов ошибок. А вот как способствует подход "все есть выражение" тому, что "в таком коде сделать ошибку сложнее, а заметить проще" — это я пока не понял.

Z>void это обычная абстракция. Она позволяет не плодить сущности. При разделении на функции и процедуры нам нужны разные механизмы для их передачи в другие функции/процедуры и работы с ними.


Согласен. Но вот преимущества такого подхода спорные, ИМХО.

Z>>>На закуску попробуй переписать код на языке, в котором using не является выражением:

ARK>>
ARK>>MyType x;
ARK>>using (var db = new Db())
ARK>>{
ARK>>  x = (from a in db.Table1
ARK>>  from b in db.Table2
ARK>>  from c in db.Table3
ARK>>  select new {a.X, b.Y, c.Relation1.GroupBy(x => x.Z)}).ToArray();
ARK>>}
ARK>>CallMethodWithArgument(x);
ARK>>


ARK>> :xz

Z>Вот и я хз, как ты умудряешься кастить массив анонимных типов к MyType.

using MyType = object. Ага?
Кстати, а что там у нас в сигнатуре CallMethodWithArgument(x) в качестве x? Вот такой же тип надо подставить вместо MyType.
Re[10]: C# 6.0
От: rameel https://github.com/rsdn/CodeJam
Дата: 29.12.13 17:00
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>using MyType = object. Ага?

ARK>Кстати, а что там у нас в сигнатуре CallMethodWithArgument(x) в качестве x? Вот такой же тип надо подставить вместо MyType.

Не получится, ибо анонимный тип умеет работать с таким кодом:
private void CallMethodWithArgument<T>(T argument) {
}
... << RSDN@Home 1.2.0 alpha 5 rev. 71>>
Re[11]: C# 6.0
От: AlexRK  
Дата: 29.12.13 17:36
Оценка:
Здравствуйте, rameel, Вы писали:

R>Не получится, ибо анонимный тип умеет работать с таким кодом:

R>
R>private void CallMethodWithArgument<T>(T argument) {
R>}
R>


Пардон, а что с аргументом можно внутри сделать, кроме как вызвать ToString?
В таком случае анонимный тип присваиваем в переменную типа object, эффект будет ровно такой же.
Re[10]: C# 6.0
От: Ziaw Россия  
Дата: 29.12.13 17:37
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Пример с if не является признаком подхода "все есть выражение", он может быть повторен на любом мейнстримовом языке.


Ну да, if в виде выражения уже есть во многих языках. Почему нужно две конструкции вместо одной и нет аналогов для switch, using, try/catch?

ARK>Я в этом месте говорю как раз про запрет выражений с побочными эффектами — вот это действительно сделало бы проще поиск некоторых типов ошибок.


Я не понимаю, что такое запрет выражений с побочными эффектами. О чем ты сейчас говоришь?

ARK>А вот как способствует подход "все есть выражение" тому, что "в таком коде сделать ошибку сложнее, а заметить проще" — это я пока не понял.


Потому, что не захотел.

ARK>Согласен. Но вот преимущества такого подхода спорные, ИМХО.


ИМХО надо как-то раскрывать. А то получается, что на все мои аргументы ты возражаешь "мне кажется, что все не так".

ARK>using MyType = object. Ага?


Ты сам понимаешь, почему это полная ерунда.

ARK>Кстати, а что там у нас в сигнатуре CallMethodWithArgument(x) в качестве x? Вот такой же тип надо подставить вместо MyType.


Там может быть дженерик тип, вместо вызова метода может быть foreach по результату. Как сейчас передать анонимный тип за пределы using/switch/try-catch и далее полноценно с ним работать? Это невозможно в общем случае. Да и работа с любым другим типом выглядит уродливо, для гарантии инициализации переменной нужны подсказки компилятора, а в случае выражения мы точно ее инициализируем и точно сделаем это один единственный раз (только тут еще нужна поддержка иммутабельных переменных).
Re[12]: C# 6.0
От: Ziaw Россия  
Дата: 29.12.13 17:40
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Пардон, а что с аргументом можно внутри сделать, кроме как вызвать ToString?


Много чего. Но я предлагаю отстать от метода. Вместо него может быть любой код, который использует x, обсуждение этого метода уводит разговор в никуда.
Re[11]: C# 6.0
От: AlexRK  
Дата: 29.12.13 18:06
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Ну да, if в виде выражения уже есть во многих языках. Почему нужно две конструкции вместо одной и нет аналогов для switch, using, try/catch?


Для if и switch естественны две формы — в виде выражения и статемента. Для остальных я вижу только statement-форму. В принципе, foreach может быть выражением, если у него вместо тела будет предикат типа "all", "any", "max", "min" и т.п. Это грамотный подход. А "выражение, возвращающее ничто" это какая-то хрень. Конструкции using, try в виде выражений все же не представляю.

Z>Я не понимаю, что такое запрет выражений с побочными эффектами. О чем ты сейчас говоришь?


Это я гипотетически говорю. Что хорошо бы функции с побочными эффектами запрещать использовать в выражениях вообще. Только в виде стейтментов. Понятно, что это не о C#.

Z>ИМХО надо как-то раскрывать. А то получается, что на все мои аргументы ты возражаешь "мне кажется, что все не так".


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

ARK>>Кстати, а что там у нас в сигнатуре CallMethodWithArgument(x) в качестве x? Вот такой же тип надо подставить вместо MyType.

Z>Там может быть дженерик тип

В смысле с двумя (или более) констрейнтами? Ну это кривизна C#, что он не позволяет объявить переменную типа intersection type. Я бы скорее это ввел в язык, чем "все есть выражение".

Z>Как сейчас передать анонимный тип за пределы using/switch/try-catch и далее полноценно с ним работать? Это невозможно в общем случае. Да и работа с любым другим типом выглядит уродливо, для гарантии инициализации переменной нужны подсказки компилятора, а в случае выражения мы точно ее инициализируем и точно сделаем это один единственный раз (только тут еще нужна поддержка иммутабельных переменных).


Может это и не проблема вовсе? Раз уж речь идет о гипотетическом расширении языка, то можно дать возможность объявлять переменные как "var" без инициализации (кстати, непонятно, почему этого не сделали).
Re[24]: C# 6.0
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.12.13 18:12
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


S>>Это естественно сейчас, и мы обсуждаем как раз способ уйти от такой естественности.


AVK>Я не очень понимаю, зачем от нее уходить. Вот зачем нужна инлайн декларация типа — понятно. А вот так чтобы именно сконструированный по использованию тип в контракты тащить — вот тут смысл для меня теряется.

Смысл в том что этот тип объявить проще, чем обычный.
В принципе такая проблема снимается если можно будет делать так:
class MyClass = <A int, B string>;
и использовать его вместо анонимного внутри метода, строящего Linq запрос, возможно с сохранением синтаксиса.
Но пока описать "настоящий" класс с его конструкторами, Equals/ToString/GetHashCode/==/!= в 10 раз сложнее, чем ввести анонимный.

S>>Мы сейчас не можем снаружи передать операцию проекции, конструирующую анонимный тип


AVK>Ты уверен? Ты то ли как то опять странно объясняешь, то ли почему то считаешь что в обычном линке использовать анонимные типы в предикатах нельзя.

Нет, я уверен что в линке использовать анонимные типы в предикатах и проекциях можно, но только если эти предикаты и проекции построены внутри того же метода, где строится линк запрос. Извне передать эти предикаты и проеции нельзя, потому как они используют анонимный тип, который мы не можем указать в сигнатуре.

AVK>>>Он использует ту самую компонентную модель, которая сейчас ничего не знает про хитрую структурную эквивалентность некоторых типов.

S>>Влад предлагает делать подмену типов в рантайме. Потому PropertyGrid-ы не узнают об этих хитростях.

AVK>Именно поэтому — узнают.

Именно поэтому в ратнайме будут экземпляры лишь одного типа и PropertyGrid-ы не увидят экземпляры совместимых типов.

AVK>>>Еще раз — анонимный тип сейчас это абсолютно обычный тип, поэтому и проблем с ним нет.

S>>Да, и структурно-эквивалентный тип будет абсолютно обычным типом.

AVK>Не будет. Если бы он был обычным, не понадобилось бы менять рантайм.

Рантайм меняется лишь для того что бы исключить появление экземпляров других типов. В остальном оставшийся тип будет абсолютно обычным.

S>>Можно пример, когда не удастся понять, нужно ли меппинг делать?


AVK>Можно

AVK>
AVK>Console.WriteLine(x == y); // компилятор знает типы, вызывается меппер, выводится True
AVK>Console.WriteLine((object)x == (object)y); // компилятор не знает типы, сравниваются ссылки, выводится False
AVK>

Тип TwoDPoint из этого гайдлайна с перекрытым оператором == будет вести себя точно так же. Это нормально.
Re[22]: C# 6.0
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.12.13 18:14
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


S>>Мы обсуждаем два варианта. 1) где совместимые типы будут подменены в рантайме, тогда мы получим лишь один тип для всех совместимых. 2) где совместимые типы маппятся. Где тут приведения типов?


AVK>С подменой в рантайме понятно, вопрос только в том как эта подмена будет проводится.

У меня нет ответа
AVK>В от как ты будешь мапперы вставлять без изменения компонетных моделей, учитывая что у них в качестчве значений сплошь object используется мне непонятно.
А мне непонятно, зачем юзать маппер для преобразования к object.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.