Re[13]: Чего не хватает в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.12.05 03:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

VD>>Лямбды это замена действительно избыточному синтаксису анонимных методов


AVK>Не совсем. Не забывай про expression tree.


Просто уверен, что для компилятора будет пофигу что сувать в expression tree лябду или анонимный метод. Так что expression tree это еще одно расширение. Не более того.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Чего не хватает в C#?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 25.12.05 11:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Просто уверен, что для компилятора будет пофигу что сувать в expression tree лябду или анонимный метод.


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

VD> Так что expression tree это еще одно расширение. Не более того.


Но тем не менее оно работает только с лямбдами, так что линковская лямбда по факту все же не просто упрощенный способ записи анонимного метода.
... << RSDN@Home 1.2.0 alpha rev. 624 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[15]: Чего не хватает в C#?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.12.05 14:19
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Интересно с чего же их больше? По спецификации анонимные методы и лямбды функционально идентичны. Просто в текущей версии компилятора лямбды ограничены выражениями.

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

VD>> Так что expression tree это еще одно расширение. Не более того.


AVK>Но тем не менее оно работает только с лямбдами, так что линковская лямбда по факту все же не просто упрощенный способ записи анонимного метода.


Линковская Лябда ограничена выражениями. Причем это не соотвествует опубликованной спецификации.

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

В любом случае если отбросить возможность преобразования к деревьям выражений разницы между семантической лямбдами и анонимными методами нет.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Чего не хватает в C#?
От: Nose Россия  
Дата: 26.12.05 07:46
Оценка: :)
Здравствуйте, VladD2, Вы писали:

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


N>>пардон, что лямбды делают с делегатами ?


VD>То же что и любые другие методы — что хатят.


да не, меня слово "капеллируют" заинтересовало
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[11]: Чего не хватает в C#?
От: GlebZ Россия  
Дата: 26.12.05 11:57
Оценка:
Здравствуйте, VladD2, Вы писали:

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


GZ>>Внимательнее Влад. Здесь подразумевается свойство, то есть проперть. Никакого нарушения


VD>Я понимаю. О том тебе и говорю. Ты несешь околесицу. Предача свойства по ссыле — это абсурд! Вместо ссылка на свойство можно передать один/два делегата или некий объект-обертку.

Ну да. Правда почему абсурд? Если ссылку реализовать как обращение к переменной, то что тут абсурдного.

VD>Ссылка это фактически типизированный указатель на память повзоялющий менять эту память.

Ссылка или типизированный указатель неважно. Насчет менять память, верно только частично. В терминах процессора, нет понятия ссылки и типа. В менеджед MSIL, нет понятия памяти. Ссылка — это понятие компиляторов. Что тип тебе скажет, то компилятор и сделает. Даже для данных ссылка может быть на константную переменную(что уже не подпадает под твое определение).
Мне интересно иметь возможность сохранять ссылку на любую облать программы. Независимо от того что это, метод, type, field, property или ссылка на экземпляр.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 26.12.05 11:57
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Конструкцию сдалатьт можно
Автор: VladD2
Дата: 24.12.05
.

Здесь я вообще-то имел ввиду методы класса. Но и это тоже. Только в данном случае есть некоторое различие между данной проксей, и желательным результатом. Наличие сеттера и геттера проверяется компилятором при наличии операции присваивания и т.п.
VD>А зачем?
Мне нравится идея что я могу адресовать все и вся в рамках инкапсуляции. Нужно меньше думать о подпорках.


С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[14]: Чего не хватает в C#?
От: vdimas Россия  
Дата: 26.12.05 16:09
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Запомни на будущее. Делегат — это ссылка на метод. Лямбда и анонимные методы — это методы не имеющие имени которые можно объявлять внутри других методов или в местах инициализации делегатов. Ссылаются на лмбду через делегат, но сама лямба оным не яявляется.


Ты Влад опять ударяешься в разъяснение технических моментов, которые все давно знают (тут неоднократно проскакивали листинги декомпиляции анонимных методов)

Оппонент рассуждал об общей природе вещей, что-ли. Какая фиг разница, как они имплементированы прямо сейчас? Ты уверен, что в будущем в том же дотнете не будет расширено понятие "функциональный объект"?

Экземпляр делегата имеет метод Invoke() с параметрами. Я не удивлюсь, если в будущем мы сможем использовать в качестве функциональных объектов не только делегаты.

Я экспериментировал с делегатами, интересные вещи оказались возможны.
Прямо в С# нелья наследоваться от System.Delegate или System.MulticastDelegate, но это можно в IL, либо динамически.

Т.е. представь ситуацию, что вполне возможно типа так:

// тип-хелпер функционального объекта
public class Func1<RET, P1> {

    // интерфейс вызова функционального объекта
    public interface Delegate {
        public RET invoke(P1 param1);
    }

    public static Delegate Create(object target, IntPtr method) {}
    public static Delegate Create(object target, MethodInfo methodInfo) {}
    public static Delegate Create(Type type, MethodInfo methodInfo) {}
    public static Delegate Create(object target, string methodName) {}
    public static Delegate Create(Type type, string methodName) {}
    public static Delegate Create(System.Delegate delegate) {}
}


public class SqrFunc : Func1<double, double>.Delegate {
    public double Invoke(double d) { return d*d; }
}

public class SqrStaticFunc {
    public static double Invoke(double d) { return d*d; }
}

public delegate double Func1D(double p1);

void Main() {
    Func1<double, double> func = new SqrFunc();
    double d1 = func.Invoke(10);
    func = Func1<double, double>.Create(SqrStaticFunc.Invoke); // typeof(SqrStaticFunc), "Invoke"
    d1 = func.Invoke(10);
    func = Func1<double, double>.Create(new Func1D(SqrStaticFunc.Invoke));
    d1 = func.Invoke(10);
}


Т.е. суть в том, что мы можем создавать динамически через Emit типы-делегаты, которые наследуют некоторые интерфейсы и затем мы можем юзать все это совместно, как делегаты, так и сами функциональные объекты.

Я вообще не понимаю, почему компилятор C# генерирует типы делегатов как sealed. Если бы не sealed, можно было бы создавать наследников делегатов, т.е. собственные функциональные объекты, благо метод Invoke у сгенерированного компилятором делегата виртуальный.
Re[3]: Хорошо ли, что свойство нельзя передать по ссылке
От: vdimas Россия  
Дата: 26.12.05 16:21
Оценка:
Здравствуйте, VladD2, Вы писали:

V>>Блин, хотел по-быстрому накатать ссылку на св-во как объект (С# struct) из пары делегатов и переопределенного оператора implicit().


VD>А приведение типов то тут зачем?


а для такого синтаксиса:
int value = propRef;

вместо
int value = propRef.Property;


Хотя это и не обязательно

VD>Да сделать то это можно. Толко подключние будет в ранмайме:


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


VD>Вот только зачем это нужно? Хоть раз в жизни бы такое потребовалось? Нафига нужно искуство ради искуства?



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


Суть в том, что мы будем обращаться единообразно к разным св-вам. Например в RFD у IT аналогичное делается через emmit, т.е. генерируются объекты-дескрипторы-посредники доступа к св-вам сущностей. Так вот, в случае описанного тобой типизированной через дженерики имплементации ссылки на св-во мы можем обойтись БЕЗ emmit для дескрипторов св-в, и не потеряем в быстродействии.

Т.е. создание делегата — это же тоже некий emmit внутренний в run-time, только более шустрый. К тому же — задача одноразовая, т.е. подобные дескрипторы св-в создаются одноразово, а затем просто используются.
Re[3]: Хорошо ли, что свойство нельзя передать по ссылке
От: vdimas Россия  
Дата: 26.12.05 16:22
Оценка: 1 (1)
Здравствуйте, VladD2, Вы писали:

VD>Блни, сегодня что магнитные бури? Ну, как можно передать сылку на два метода? Тут только объект-посредник поможет. Но это не ссылка! Или тогда что по вашему означет "ссылка"?


Да, хотелось бы услышать. Что же такое ссылка?
Неужели только последовательность байт шириной в адрессную шину?
Re[3]: Хорошо ли, что свойство нельзя передать по ссылке
От: stalcer Россия  
Дата: 27.12.05 07:08
Оценка:
Здравствуйте, GlebZ, Вы писали:

S>>Естественно плохо. Сделать такое в принципе можно, но тогда все ссылки тормозить начнут. Так что невозможность передачи свойства по ссылке — это просто решение в пользу производительности.

GZ>Это еще почему?

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

struct VarRef__
{
    void *varptr;
};
struct PropRef__
{
    void *getter;
    void *setter;
};

union RefStruct
{
    bool      isVarRef;
    VarRef__  vref;
    PropRef__ pref;
};


И соответственно постоянно анализировать isVarRef. Можно конечно и для переменной передавать псевдо getter/setter, и таким образом работать однообразно без флага, но вызов метода вместо работы по указателю — это уже тормоза.
Re[11]: Хорошо ли, что свойство нельзя передать по ссылке
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.12.05 07:39
Оценка:
Здравствуйте, Mab, Вы писали:

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

GZ>>Обычный метод? И как его вызвать без рефлекшона простому индийцу?
Mab>Тот факт, что компилятор скрывает от нас его, еще не делает метод необычным Скажем, если объявить на MC++ свойство с параметрами, то из С# его можно (и нужно) будет вызывать через set_XXX.

Mab>То, о чем говорит, Василий -- в код, работающий с ссылками (т.е. с managed pointerами в терминологии MSIL), нельзя передать свойство -- по крайней мере в текущей реализации виртуальной машины.


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

Я считаю, что вполне достаточно было бы иметь возможность легко кастить свойство к двум типам делегатов. Вот простой пример:

public class C1
{
  private int _i;
  public int I1
    {
      get { return GetI(); }
        set    { SetI(value);    }
    }
    
    public int GetI() { return _i; }
    
    public void SetI(int value) 
    { 
        if (_i % 2 == 0) 
            _i = value; 
        else 
            throw new ArgumentException("value must be an odd number", "value"); 
    }
    public int I2;
}

public class C2
{
  public delegate void SetInt(int value);
    public delefate int GetInt(int value);
  public static void Test1(ref int value)
    {
      value++;
      value++;
    }
    public static void Test2(GetInt in, SetInt out)
    {
      out(in()+1);
      out(in()+1);
    }
}

Итак, мы подготовили сцену. В старом шарпе можно было делать вот так:
С1 с1 = new C1();
С2.Test1(ref c1.I2);
C2.Test2(new C2.GetInt(c1.GetI), new C2.SetInt(c1.SetI));

В С# 2.0 мы можем эксплуатировать С2 вот так:
С1 с1 = new C1();
С2.Test1(ref c1.I2);
C2.Test2(c1.GetI, c1.SetI);

Это работает благодаря автоматическому кастингу методов к делегатам. На первый взгляд, можно было бы сделать также автоматический кастинг пропертей к аналогичным делегатам:
С1 с1 = new C1();
С2.Test1(ref c1.I2);
C2.Test2(c1.I1, с1.I1);

Тогда не нужно было бы выносить код свойства в публичные методы. Это уже было бы достаточно удобно. Хотя тут явно есть подводные грабли вот с чем:
public class C3
{
  public C2.SetInt I { get { return SetK; } }
    public void SetK(int k) { Console.Write(k);}
}

...
C3 c3 = new C3();
C2.Test2(c3.I, null); // что мы имели здесь в виду? Вычисляем c3.I или кастим один из его методов к делегату?

Хотя не исключен вариант с тем, что это все можно разрулить.

Стоит отметить, что IL методов C2.Test1 и C2.Test2 существенно отличается. Это означает, что все трюки должны осуществляться на стороне вызывающего кода. В принципе, компилятор шарпа делает некоторые такие трюки. В частности, я нередко пишу код типа:
StringBuilder sb = new StringBuilder();
...
if(sb.Length > 0) 
    sb.Length--; // фактически, я делаю sb.Length = sb.Length - 1;

IL будет существенно отличаться от кода для
int i = 0;
i--;

но об этом заботится компилятор. В принципе, можно было бы сделать и так, чтобы семантика ref и out обеспечивала требуемое поведение автоматически:
// варнинг! Компилируется только под C#8.0!
C1 c1 = new C1();
C2.Test1(ref c1.I);
// компилятор строит следующий код позади сцены:
int temp$$_882133 = c1.I;
C2.Test1(ref temp$$_882133);
c1.I = temp$$_882133;

Есть единственная махонькая грабля, которую я вижу. Если внутри метода производятся множественные обращения к параметру, то семантика кода отличается. В частности, в моем примере сеттер I не пропускает нечетные числа. Честно реализованный метод Test2() упадет сразу же при первом инкременте, а Test1() отработает нормально. Потому что выполнится ровно одно чтение и одно присваивание. В некоторых обстоятельствах это может оказаться важно.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 27.12.05 11:25
Оценка:
Здравствуйте, stalcer, Вы писали:

S>И соответственно постоянно анализировать isVarRef. Можно конечно и для переменной передавать псевдо getter/setter, и таким образом работать однообразно без флага, но вызов метода вместо работы по указателю — это уже тормоза.

Не обязательно. Вводим в JIT новый тип — propertyType. При компиляции в asm — переменная этого типа переводится в реальный адрес.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Хорошо ли, что свойство нельзя передать по ссылке
От: stalcer Россия  
Дата: 27.12.05 11:37
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Не обязательно. Вводим в JIT новый тип — propertyType. При компиляции в asm — переменная этого типа переводится в реальный адрес.


В реальный адрес чего? И какое конкретно содержание у propertyType. И самое главное как метод поймет разницу между тем что ему передали: ссылку на переменную или ссылку на свойство?

class A
{
    public int Var;
    public int Prop { get { return x + y;  } 
                      set { x = value - y; } }

    private int x;
    private int y;
};

class B
{
    public void P(ref int i)
    {
        int j = i; // Читаем.
        i = j * 2; // Пишем.
    }
    public void M()
    {
        A a = new A();
        
        P(ref A.Var);
        P(ref A.Prop);
    }
}

Ы?
Re[6]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 27.12.05 12:03
Оценка:
Здравствуйте, stalcer, Вы писали:

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


GZ>>Не обязательно. Вводим в JIT новый тип — propertyType. При компиляции в asm — переменная этого типа переводится в реальный адрес.

S>В реальный адрес чего? И какое конкретно содержание у propertyType. И самое главное как метод поймет разницу между тем что ему передали: ссылку на переменную или ссылку на свойство?
Сравнивай не с полями. Сравнивай с делегатами. Тогда все на месте.

S>
        
S>        P(ref A.Var);
//Ссылка на проперть - reference type объект. Компилятором должа быть выведена ошибка.
S>        P(ref A.Prop);
S>

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Хорошо ли, что свойство нельзя передать по ссылке
От: stalcer Россия  
Дата: 27.12.05 12:32
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>>
GZ>>    P(ref a.Var);  // Ссылка на проперть - reference 
GZ>>                   // type объект. Компилятором должна 
GZ>>                   // быть выведена ошибка.
GZ>>    P(ref a.Prop);
GZ>>


Чё это ошибка , должно работать!
Re[8]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 27.12.05 12:46
Оценка:
Здравствуйте, stalcer, Вы писали:

S>Чё это ошибка , должно работать!

Не будет работать. ref на reference type применять нельзя.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Хорошо ли, что свойство нельзя передать по ссылке
От: Mab Россия http://shade.msu.ru/~mab
Дата: 27.12.05 12:48
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Не будет работать. ref на reference type применять нельзя.

Что за новости? С чего ты это взял?
Re[9]: Хорошо ли, что свойство нельзя передать по ссылке
От: stalcer Россия  
Дата: 27.12.05 12:58
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Не будет работать. ref на reference type применять нельзя.


Как всегда всё в куче.

Во-первых, где ты увидел "ref на reference type".
Во-вторых, мы обсуждаем как сделать чтобы работало. А ты говоришь "не будет". Дык, значит твой алгоритм не правильный. Так? Тогда чего его обсуждать...
Re[10]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 27.12.05 13:07
Оценка:
Здравствуйте, Mab, Вы писали:

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


GZ>>Не будет работать. ref на reference type применять нельзя.

Mab>Что за новости? С чего ты это взял?
Обломс. Ошибки не будет.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Хорошо ли, что свойство нельзя передать по ссылке
От: GlebZ Россия  
Дата: 27.12.05 13:15
Оценка:
Здравствуйте, stalcer, Вы писали:

S>Во-первых, где ты увидел "ref на reference type".

S>Во-вторых, мы обсуждаем как сделать чтобы работало. А ты говоришь "не будет". Дык, значит твой алгоритм не правильный. Так? Тогда чего его обсуждать...
Вобщем штука примерно получится такая. У нас есть некоторый тип делегат который может ссылаться на несколько методов. Хороший или он плохой — вопрос второй. Делегат сущность типизированная. Вместо типизированного метода, типизируем проперть.(ну информация о типе будет типа есть setter/getter, какой тип). Желательно чтобы компилятор C# делал это сам, как и статическую проверку при использовании. На входе в JIT у нас будет переменная и ее тип(а может так-же как и в делегате объект). Его задача — просто подставить вызов сеттера или геттера. Вот и все.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.