Re[4]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 14:40
Оценка:
ANS>Врядли синтаксис тех лямб пойдёт в серию. Там же ни одной скобки нету. Ни круглой ни фигурной. Массы такого абстракционизма не поймут

Наоботор пойдут на ура. К стати, скобки там можно приделать. Более того если у лямбды два и более параметра, то без них не обойтись:
(x, y) => x * y
(x)    => x * x

А учитывая, что нет проблем использовать и более расширенный синтаксис:
(int x, double y) => x * y
(int x) => { return x * x; }

и даже "старый" синтаксис:
delegate(int x, double y) {  return x * y; }
delegate(int x) { return x * x; }

народ поймет, что это просто такая сокращенная форма записи.
А когда он сравнит:
(x, y) => x * y

и
delegate(int x, double y) {  return x * y; }

то вопросы отпадут сами собой.
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: С# 3.0
От: GlebZ Россия  
Дата: 16.09.05 14:45
Оценка:
Здравствуйте, VladD2, Вы писали:

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

По-моему, вся фигня крутится вокруг коллекций. Анонимные делегаты пользуются только в коллекциях. В реале, я ни разу не делал анонимный предикат за пределами коллекций(и не видел его использования). Это некоторый флаг Microsoft, чем удобнее пользовать коллекции, тем лучше С# . Очень сомневаюсь что подобный синтаксис выйдет за пределы этого. IMHO Функциональный стиль и объекты одновременно не очень хорошо живут. Объекты с их состоянием и строгой типизированностью — ограничивают функциональный стиль. И ввод неименованных типов, по моему, как козе баян, а может и еще хуже.
Причина вполне понятна. Microsoft делает язык для серверов приложений. И коллекции немаловажная часть DSL. Если еще при этом, прозрачно связать с персистентностью объектов, то такая реализация DSL будет весьма здоровская. Похоже это и есть цель C# 3.0. За пределами коллекций, => по моему не катит.

С уважением, Gleb.
Re[7]: С# 3.0
От: WolfHound  
Дата: 16.09.05 15:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Такой синтаксис не поддерживается. Откда ты это взял, я не знаю.

Я знаю.
Автор: WolfHound
Дата: 16.09.05

Просто я сделал предположение как это можно реализовать малой кровью.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: С# 3.0
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 16.09.05 16:30
Оценка:
Здравствуйте, VladD2, Вы писали:

ANS>>Врядли синтаксис тех лямб пойдёт в серию. Там же ни одной скобки нету. Ни круглой ни фигурной. Массы такого абстракционизма не поймут

VD>Наоботор пойдут на ура. К стати, скобки там можно приделать. Более того если у лямбды два и более параметра, то без них не обойтись:
VD>народ поймет, что это просто такая сокращенная форма записи.
VD>А когда он сравнит:

Занятно, что "длина" синтаксиса таки имеет значение

VD>
VD>(x, y) => x * y
VD>

VD>и
VD>
VD>delegate(int x, double y) {  return x * y; }
VD>

VD>то вопросы отпадут сами собой.

запись вверху неконсистентна, выбивается из общей массы. Я вроде как за краткость, но нужно же придерживаться некого стиля. Не нравится декларация типов (вот уж от тебя не ожидал ) — убери:
delegate(x, y) {  return x * y; }

в рамках С-шарп (именно в "рамках") понятнее чем
(x, y) => x * y
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[4]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 16:43
Оценка: 6 (1) +1
Здравствуйте, GlebZ, Вы писали:

GZ>По-моему, вся фигня крутится вокруг коллекций. Анонимные делегаты пользуются только в коллекциях. В реале, я ни разу не делал анонимный предикат за пределами коллекций(и не видел его использования).


Дык коллекции, точнее списки — это самый часто используемый механизм в программах. И как раз функциональный стиль (ФС) при обработке списков показывает себя очень и очень хоношо.

Причем ты даже не подозревашь насколько часто могут применяться списки. Дело в том, что большинство структур данных и даже алгоритмов можно представить в виде списков. Даже БД и те можно выразить списками. Так что итераторы и функции высшего порядка добавленные в коллекции во втором фрэймворке — это очень вреное решение.

Но на списках приемущества функционального подхода (ФП) не заканчиваются. Функции высшего порядка позволяеют производить декомпозицию кода там, где средствами ООП это или вообще нвозможно сделать, или можно, но уж очень много кода получается.

GZ> Это некоторый флаг Microsoft, чем удобнее пользовать коллекции, тем лучше С# .


Дык это к любому языку относится. Если ты не в курсе, есть такой язык Лисп, так он вообще изначально предназначался для обработки списков. А на поверку оказался одним из самых интересных языков программирования.

GZ> Очень сомневаюсь что подобный синтаксис выйдет за пределы этого. IMHO Функциональный стиль и объекты одновременно не очень хорошо живут. Объекты с их состоянием и строгой типизированностью — ограничивают функциональный стиль. И ввод неименованных типов, по моему, как козе баян, а может и еще хуже.


Это полноейшее заблцждение. "Сменная функция" позволяет делать код настраиваемым. Конечно можно обходиться интерфейсами или абстрактными классами, но это же ведь неудобно.

ФП же как раз отлично вписывается в ООП. Ведь и сами функции могут быть методами объектов, и объекты параметрами функций. Более того функции высшего порядка позволяют абстрагировать алгоритм от конкретных типов объектов.

GZ>Причина вполне понятна. Microsoft делает язык для серверов приложений.


Microsoft слава богу делает язык общего назначения (GP-язык). А коллекции они и в Африке коллекции. Я еще не видел ЯП который мог бы обходиться без список в том или ином виде.

GZ>И коллекции немаловажная часть DSL.


А где коллекции маловажная вещь? Да и как раз для создания DSL C# подходит не лучшим образом. Будем надеяться, что только пока.

GZ>Если еще при этом, прозрачно связать с персистентностью объектов, то такая реализация DSL будет весьма здоровская. Похоже это и есть цель C# 3.0. За пределами коллекций, => по моему не катит.


Ты просто привык к одному взгляду на мир. А мир более разнообразен.
Как я уже говорил функция является отличной абстракцией. Ну, давай попробую объяснить это на простеньком примере. Предположим у нас есть некоторое вычисление содержащее повторяющиеся части (первое вхождение выделено жирным):
int x = 2;
int y = 3;
int z = 3;

int res1 = (x + 123 + z * z) * y + (x + 321 + z * z) * y 
  + (x + 111 + z * z) * y + (x + 222 + z * z) * y;

Некрасиво, правда?
Что мы может сделать чтобы устранить дублирование? Правильно ввести функцию. Но это приведет к куче лишних действий и к тому, что код станет более большим и не станет сильно понятнее:
int res2 = f1(x, y, z, 123) + f1(x, y, z, 321) 
  + f1(x, y, z, 111) + f1(x, y, z, 222);
...

private static int f1(int x, int y, int z, int a)
{
    return (x + a + z * z) * y;
}

По сути мы избавились от дублирования слишком дорогой ценой. А вот если мы имеем возможность оперировать функциями более вольготно и если этот синтаксис будет более компактным, то мы можем получить куда более приятный результат. Вот как тоже самое можно записать с применением лямбды:
Func<int, int> f2 = a => (x + a + z * z) * y;
var res3 = f2(123) + f2(321) + f2(111) + f2(222);

Согласись это значительно лучше читается и занимает куда меньше места. Ведь функция уложилась в одну строку, да еще и ее применение стало намного компактнее.

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

А проблемой которая будет препятствовать его применению скорее станет не его непонятность, а ухудшение производительности. Дело в том, что в истинно функциональном языке выражения обрабатываются еще во время компиляции. А в C# 2.0/3.0 будет производиться довольно неэффективный косвенный вызов. В данном примере будет 4 вызова. Плюс ко всему прочему будет порожден временный объект (чтобы лямбда могла получить доступ к локальным переменным x, y, z они будет превращены в поля этого объекта).
И это еще легкий случай. А ведь вложенность при функциональной декомпозиции может быть многократной. И это уже может существенно повлиять на производительность.
Я уверен, что все эти проблемы мог бы устранить оптимизирующий компилятор или JIT, но пока что этого никто не делает. А стало быть производительность столь красивых решений будет меньшей нежели аналогичных лобовых.
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 17:22
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Занятно, что "длина" синтаксиса таки имеет значение


Дык ведь линий мусор еще никому не помогал.

ANS>запись вверху неконсистентна, выбивается из общей массы.


Чё?

ANS> Я вроде как за краткость, но нужно же придерживаться некого стиля. Не нравится декларация типов (вот уж от тебя не ожидал


Почему не ожидал? Это наверно ты путашь мое отношение к статической типизации и наличие явной декларации типов.
В приведенных примерах типизация остается строгой и статической. В ней применяется вывод типов. Он столь же логичен для человека как и для компилятора. А стало быть это те подробности которые в большинстве случаев можно опусить.

ANS>) — убери:

ANS>
ANS>delegate(x, y) {  return x * y; }
ANS>

ANS>в рамках С-шарп (именно в "рамках") понятнее чем
ANS>
ANS>(x, y) => x * y
ANS>


Дык мне еще не нравится, что в анонимном методе я не могу использовать выражения (expressions) и вынужден использовать предложения (statments). Все это приводит к довольно сильному удленнению кода, а стало быт и к его замыливанию неважными фрмгментами.
Например, сравни следующие две строки:
list.Sort(delegate(KeyValuePair<string, int> x, KeyValuePair<string, int> y { return x.Value.CompareTo(y.Value); });
и:
list.Sort((x, y) => x.Value.CompareTo(y.Value));

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

ЗЫ

Уверен, что после выхода C# 3.0 синтаксис delegate(...){ ... } быстро будет забыт.
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: С# 3.0
От: GlebZ Россия  
Дата: 16.09.05 18:47
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так что итераторы и функции высшего порядка добавленные в коллекции во втором фрэймворке — это очень вреное решение.

В этом как раз я не сомневаюсь.

VD>Но на списках приемущества функционального подхода (ФП) не заканчиваются. Функции высшего порядка позволяеют производить декомпозицию кода там, где средствами ООП это или вообще нвозможно сделать, или можно, но уж очень много кода получается.

Или попросту ненужно. Дизайн вполне описывается паттернами. И оно самодостаточно(если конечно голова на плечах есть). Иногда там встречается observer, но это все равно к функц. языкам отношения не имеет.

VD>Если ты не в курсе, есть такой язык Лисп,

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

GZ>> Очень сомневаюсь что подобный синтаксис выйдет за пределы этого. IMHO Функциональный стиль и объекты одновременно не очень хорошо живут. Объекты с их состоянием и строгой типизированностью — ограничивают функциональный стиль. И ввод неименованных типов, по моему, как козе баян, а может и еще хуже.


VD>Это полноейшее заблцждение. "Сменная функция" позволяет делать код настраиваемым. Конечно можно обходиться интерфейсами или абстрактными классами, но это же ведь неудобно.

Почему?
А теперь представим такую вещь. Мы делаем какой-то здоровую функциональную функциональность. Но тут у нас произошло изменение. Нам нужно использовать класс с состоянием на чтение — запись. Оптимизация графа, летит к ... маме. След., возможности чистого функционального подхода, здесь становятся практически недоступны. Либо мы юзаем лямбда, либо императив.(я в чем-то ошибаюсь?)

VD>ФП же как раз отлично вписывается в ООП. Ведь и сами функции могут быть методами объектов, и объекты параметрами функций. Более того функции высшего порядка позволяют абстрагировать алгоритм от конкретных типов объектов.

Если методы объектов выполняют ограничения ФП.

VD>А где коллекции маловажная вещь? Да и как раз для создания DSL C# подходит не лучшим образом. Будем надеяться, что только пока.

Лисповцы наступают!!! Метапрограммирование? Честно говоря, все средства есть. Хочешь генери новые классы. Хочешь используй неименованные типы(приводя их к именнованным). Чего тебе не хватает? Да, это не Лисп. Кое что, в построении отдельного языка, будет труднее сделать. Но в рамках C# описать язык вполне можно. Особенно, если это будет C# синтаксис. Он тебе недостаточен?

VD>Ты просто привык к одному взгляду на мир. А мир более разнообразен.

Грешен.
VD>
VD>Func<int, int> f2 = a => (x + a + z * z) * y;
VD>var res3 = f2(123) + f2(321) + f2(111) + f2(222);
VD>

VD>Согласись это значительно лучше читается и занимает куда меньше места. Ведь функция уложилась в одну строку, да еще и ее применение стало намного компактнее.
Чудно, только это слишком простой пример. Это применение возможной только в области видимости данной процедуры. А если решение побольше, то это выливается в обычные методы.

VD>А проблемой которая будет препятствовать его применению скорее станет не его непонятность, а ухудшение производительности. Дело в том, что в истинно функциональном языке выражения обрабатываются еще во время компиляции. А в C# 2.0/3.0 будет производиться довольно неэффективный косвенный вызов. В данном примере будет 4 вызова. Плюс ко всему прочему будет порожден временный объект (чтобы лямбда могла получить доступ к локальным переменным x, y, z они будет превращены в поля этого объекта).

Именно. Не в бровь, а в глаз. delegate — это объект. Притом объект с состоянием. Ты знаешь как его можно сделать без состояния? Реформировать процедуру чтобы сохранять состояние в параметрах? Тогда получается беспредел с рекурсией(если эта шняга работает только в рамках процедуры, а то еще больше интересного).
VD>И это еще легкий случай. А ведь вложенность при функциональной декомпозиции может быть многократной. И это уже может существенно повлиять на производительность.
Absolutly right. Тело функциональной программы — это граф. И его надо оптимизировать.
Что будет если написать так:
Func<int, int> f2 = a => (f2(a) + 1);
var t=f2;


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

Мне интересен вопрос, как они это сделают?

С уважением, Gleb.
Re[3]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.05 20:06
Оценка:
Кё>
Кё>if ( (Root == null || Root.Config == null || Root.Config.User == null ? default_value : Root.Config.User.Age) > 10 )
Кё>...
Кё>


Этот код совсем неэквивалентен примеру, особенно в многопоточном приложении, или в приложении с side-эффектами.
Re[6]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.05 20:11
Оценка:
S>>А если так:
S>>
S>>int x = Root.?Config.?User.?Age;
S>>

WH>В C#2 появились nullable типы.
WH>Те в данном случае будет так

Да, результирующий тип должен быть или тем же самым, для ссылочных,
или Nullable<Type> для value-type-ов.

ps
но еще раз повторяю, что данный код совсем не равносилен исходному примеру, и может выдавать некорректный результат для многопоточного приложения или для кода с side-эффектами.

WH>
WH>int? x = Root.?Config.?User.?Age;
WH>

WH>и приводится это к такому коду
WH>
WH>int? x;
WH>if (Root != null && Root.Config != null && Root.Config.User != null)
WH>    x = Root.Config.User.Age;
WH>else
WH>    x = null;
WH>



генерится код должен такой, как из исходного примера.
Re[3]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.05 20:26
Оценка:
VD>Для вашей проблемы сто лет назад был придуман паттерн NuulObject. То есть объект выполняющий роль того самого null. При этом он предоставлеяет некие значения которые считаются недействительными. Для ссылочных объектов это специальные синглтон-экземлпяры, для вэлью-типов предопределенные значения. Вот пример использования данного паттерна:


NullObject — совсем не тоже самое, что null, т.к. возникают проблемы с преобразованием типов, со сравнениями и т.д.

например:
interface IA{}
interface IB:IA{}
class NullableIA:IA
{
  public static readonly IA Null = new NullableIA();
}
class NullableIB:IB
{
  public static readonly IB Null = new NullableIB();
}

class Program
{
  static void Main()
  {
     IA a = NullableIA.Null;
     CheckForNull(a); //print null
     
     IB b = NullableIB.Null;
     CheckForNull(b); //print null
 
     a = b;
     CheckForNull(a); //print not null     

     
  }
  public static void CheckForNull(IA a)
  {
     if (a == NullableIA.Null)
       Console.WriteLine("null");
     else
       Console.WriteLine("not null");  
  }
  public static void CheckForNull(IB b)
  {
     if (b == NullableIB.Null)
       Console.WriteLine("null");
     else
       Console.WriteLine("not null");  
  }
}


как должны быть написаны методы CheckForNull, чтобы возвращать правильный результат?
ради чего программист должен писать Null-заглушки?
если использовать Null-объекты, то какие операции использовать вместо is, as и (Type)? ведь Null-объект, формально декларируя поддержку интерфейса, на самом деле же нифига не поддерживает.
и т.д.
Re[2]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.05 20:50
Оценка:
iT>Extensions с generic'ами не живут, что в общем, понятно, но обидно:

Extensions с полями работает? или только с методами?

т.е. можно ли через Extension добавить поле?
Re[2]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.09.05 21:10
Оценка:
оператор .? в применении к полям на get выглядит более менее логично
логику использования уже правильно описал wolfhound.
но код должен генериться более страшный, чем у него в примере, чтобы избежать проблем, связанных с повторным доступом к полям.

но также есть еще вопрос, можно ли применять оператор .? к set-полям/свойствам, и к функциям и процедурам.

адекватен ли код:

1.
a.?Value = 5;


2.
a.?Eval(5);


3.
int? v = a.?Execute();


имхо, адекватен, т.к. в случае вызова функции, мы по аналогии с полем на get просто возвращаем null,
а в случае — set-а или процедуры просто не выполняется правая часть.

Резюме:

1. get

код вида
<res> = <primary> ".?" <field-name>


имеет тип результата:
typeof(<primary>.<field-name>) — для ссылочных типов
и
Nullable<typeof<primary>.<field-name> — для value-типов

и код преобразуется в
var q = <primary>;
if (q != null)
  <res> = q.<field-name>;
else
  <res> = null;


2. set
<primary>.?<field-name> = value;

преобразуется в
var q = <primary>;
if (q != null)
  q = value;

значение value не вычисляется, если .? возвращает null.


3. вызов процедуры (void метода)
код вида
<primary>.?<method-name>(<arg-1>, <arg-2>)


преобразуется в
var q = <primary>;
if (q != null)
  q.<method-name>(<arg-1>, <arg-2>);

выражения arg-1 и arg-2 не вычисляются, если <primary> == null


4. вызов функции (метода, возвращающего значение):
<res> = <primary> ".?" ?<method-name>(<arg-1>, <arg-2>)

тип результата такой же как и в случае get

генерируемый код
var q = <primary>;
if (q != null)
  <res> = q.<method-name>(<arg-1>, <arg-2>);
else
  <res> = null;

<arg-1>, <arg-2> также не вычисляются, если <primary> — null.
Re[3]: С# 3.0
От: GarryIV  
Дата: 16.09.05 21:39
Оценка: +2
Здравствуйте, FDSC, Вы писали:

DG>>Особенно это нужно при описании правил бизнес логики, т.к. в бизнес-логики часто мы имеем на руках только частичную информацию о мире


FDS>То же с этим очень мучаюсь. Просто жуть!


Может быть пока не вышел C# 4.0 патерн Special Case (Null Object) поможет?
WBR, Igor Evgrafov
Re[4]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 22:41
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>как должны быть написаны методы CheckForNull, чтобы возвращать правильный результат?


Идея паттерна NullObject заключается в том, чтобы вообще исключить подобные проверки. Для тебя null вообще не существует. Если уж нужно проверять на реальность объекта, то просто сравнивашь с тем самым Null-объектом.

DG>ради чего программист должен писать Null-заглушки?


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

DG>если использовать Null-объекты, то какие операции использовать вместо is, as и (Type)?


А причем тут is и as? Систему типов они не отменяют. Они устранят необходимость постоянно проверять все ссылки на нул.

Тебя, кстати, не угнетает, что в дотнете принят паттерн в соотвествии с которым свойства и методы возвращающие коллекции и массив всегда должны возвращать пустой массив, а не null?

DG> ведь Null-объект, формально декларируя поддержку интерфейса, на самом деле же нифига не поддерживает.


Null-объект поддерживает такой же интферйс как и другие обхекты того же класса. Просто он используется вместо null. Не придумывай лишнего.
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 22:41
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>я в чем-то ошибаюсь?


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

VD>>ФП же как раз отлично вписывается в ООП. Ведь и сами функции могут быть методами объектов, и объекты параметрами функций. Более того функции высшего порядка позволяют абстрагировать алгоритм от конкретных типов объектов.

GZ>Если методы объектов выполняют ограничения ФП.

Какие еще ограничения? Ты о чем?

GZ>Лисповцы наступают!!!


Лисп только один из примеров. С тем же успхом можно привести и ОКамл, и даже С++.

GZ> Метапрограммирование? Честно говоря, все средства есть.


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

GZ> Хочешь генери новые классы. Хочешь используй неименованные типы(приводя их к именнованным). Чего тебе не хватает?


Удобства.

GZ> Да, это не Лисп. Кое что, в построении отдельного языка, будет труднее сделать. Но в рамках C# описать язык вполне можно. Особенно, если это будет C# синтаксис. Он тебе недостаточен?


Я не смог уловить смысла этого абзаца.

VD>>Ты просто привык к одному взгляду на мир. А мир более разнообразен.

GZ>Грешен.

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

GZ>Чудно, только это слишком простой пример.


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

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


Нет, будет проще. Будет кое-как написанная гора кода вообще без декомпозиции. Средств то подходящих нет ведь.

GZ>Именно. Не в бровь, а в глаз. delegate — это объект.


Ну, заявление что делегат — это объект слишком натянуто. Для компилятора это всего лишь ссылка на функцию — примити.

GZ> Притом объект с состоянием.


Что? У самого делегата состояния нет. Это всго лишь указатеь. А в языке вообще ссылка на метод (безтелесная).

GZ> Ты знаешь как его можно сделать без состояния?


У него нет состояния. Состояние может быть у ассоциированного объекта, но это не одно и то же.

GZ> Реформировать процедуру чтобы сохранять состояние в параметрах? Тогда получается беспредел с рекурсией(если эта шняга работает только в рамках процедуры, а то еще больше интересного).


Есть куча работ по комбинаторной логике и по преобразованию функций. Математически доказоно, что функции можно гибко переписывать во время компиляции. Многие ФЯ делают это без проблем и достигают очень нехилой производительности.

Так что производительность упирается в качество реализации компиляторов (как языков, так и джита). И рано или поздно компиляторы дотнета научатся оптимизировать функцональный код.

GZ>Absolutly right. Тело функциональной программы — это граф. И его надо оптимизировать.


Это, извини, чушь. Функциональные программы — это программы. Их моно представить как угодно. Есть стековые машины. Есть основанные на свертке графов, но они тоже по сути используют стэк. Ну, а что до компилируемых ФЯ, то в большинстве случае код после преобразований превращается в машинный (или IL). Так что никаких пробем тут нет.

Еще раз повторюсь. Есть куча научных работ и работающие компиляторы. Возми те же SML.NET и F#. Они показывают очень высокую производительность и полностью компилируются в MSIL. Вот только если компилятор C# преобразует код в MSIL практически 1 в 1, то функциональные компиляторы перед этоим выполняют преобразование АСТ таким образом, чтобы обеспечить масимальную эффективность. Что-то оптимизируется. Какие-то методы сливаются и плучаются новые (невидимые). Где-то все переписывается настолько, что уже вообще нельзя говорить о похожести на исходную программу.

GZ>Что будет если написать так:

GZ>
GZ>Func<int, int> f2 = a => (f2(a) + 1);
GZ>var t=f2;
GZ>


Для шарпа это неверная программа. Но она переписывается так:
Func<int, int> f2 = null;
f2 = a => (f2(a) + 1);
var t = f2;

и будет здесь банальный рекурсивный вызов. Ну, и так как код написан бездумно, то будет переполнение стека в виду вечной рекурсии. Линивых вычислений в Шарпе ведь нет.

А вот на Хаскеле подобная программа порождала бы список чисел. И это был бы совершенно корректной программой.

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

GZ>Мне интересен вопрос, как они это сделают?

Ести тебе серьезно интересен этот вопрос, то советую обратиться к научным работам по этому поводу.

Где их найти можно узнать спросив в форуме Декларативное программирование. Ну, или попытать счастье через гугль "code rewriting" "functional language".
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: С# 3.0
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.09.05 22:41
Оценка:
Здравствуйте, DarkGray, Вы писали:


DG>Extensions с полями работает? или только с методами?


DG>т.е. можно ли через Extension добавить поле?


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

ЗЫ

Пока вообще можно добавлять только методы. Как я понимаю вопрос о свойствах и событиях обсуждается.
... << RSDN@Home 1.2.0 alpha rev. 611>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.05 07:02
Оценка:
DG>>Extensions с полями работает? или только с методами?

DG>>т.е. можно ли через Extension добавить поле?


VD>А подумть? Как ты добавишь поле? Ты же не можешь изменять сам объект. Это только синтаксический сахар.


А самому подумать?

конечно, же я имел ввиду свойства.
Re[5]: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 17.09.05 07:17
Оценка:
VD> Идея паттерна NullObject заключается в том, чтобы вообще исключить подобные проверки. Для тебя null вообще не существует. Если уж нужно проверять на реальность объекта, то просто сравнивашь с тем самым Null-объектом.

ню-ню, посмотрю я как, ты в большом проекте на каждый чих сможешь написать корректный Null-object.

Взять тот же пример с возврастом:

Как должен выглядеть Null-объект, чтобы корректно работали оба варианта:
if (user.Age > 21)
{
  //bla-bla
}
if (user.Age < 16)
{
  //bla-bla
}


Во-вторых:
как написать Null-объект, если исходный интерфейс не подразумевал null-возвраст?
interface IUser
{
  int Age {get;}
}

class NullUser:
  IUser
{
  public int Age {get {return xxx;}}
}

что должно быть написано вместо xxx, чтобы корректно работали вышеприведенные условия.


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


Вообще-то, в бизнес-логике null и пустой массив — это не одно и тоже

null — это "я не знаю, какие есть элементы у этого объекта"
пустой массив — это "я знаю, что элементов у объекта нет".


ps
и, вообще, авторитетом подавил, а не на один из моих вопросов, так адекватного ответа и не дал.
Re[5]: С# 3.0
От: Алексей.  
Дата: 17.09.05 07:24
Оценка:
Здравствуйте, stalcer, Вы писали:

S>1) tmp1 = Root;

S>2) tmp2 = tmp1.?Config;
S>3) tmp3 = tmp2.?User;
S>4) tmp4 = tmp3.?Age;
S>5) tmp5 = tmp4 > 16;
S>6) if (tmp5)

S>Что должно быть на каждом шаге? Какого типа каждое из этих промежуточных выражений?


S>
S>int x = Root.?Config.?User.?Age;
S>


Тип на каждом промежуточном шаге может быть любым. Но эти типы должны неявно приводиться к типу указанному слева от последовательности
Root.?Config.?User.?Age
Специально для if-выражений можно предусмотреть дополнительно преобразование T? -> bool.
Re[5]: С# 3.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 17.09.05 07:29
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>конечно, же я имел ввиду свойства.


Читай мое сообщение или спецификацию, там про это упоминается.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.