Re[15]: Немножко о С# 3
От: Cyberax Марс  
Дата: 23.03.07 08:27
Оценка:
Здравствуйте, Cyberax, Вы писали:

_FR>>>>Это почему? List<int> — параметризованный примитивным типом List<>

C>>>Нет. Ты параметризуешь ОБЕРТКОЙ для типа int, то есть настоящим полноценным объектом. Просто это скрывают синтаксическим сахаром.
EC>>А можно подробнее? Что понимается под обёрткой?
C>http://msdn.microsoft.com/msdnmag/issues/1200/dotnet/ — см. по слову "boxing".
Можно вопрос? А за что минусы?
Sapienti sat!
Re[16]: Немножко о С# 3
От: _FRED_ Черногория
Дата: 23.03.07 09:03
Оценка: +4
Здравствуйте, Cyberax, Вы писали:

_FR>>>>>Это почему? List<int> — параметризованный примитивным типом List<>

C>>>>Нет. Ты параметризуешь ОБЕРТКОЙ для типа int, то есть настоящим полноценным объектом. Просто это скрывают синтаксическим сахаром.
EC>>>А можно подробнее? Что понимается под обёрткой?
C>>http://msdn.microsoft.com/msdnmag/issues/1200/dotnet/ — см. по слову "boxing".
C>Можно вопрос? А за что минусы?

А ты считаешь, что все так прям должны быть согласны с тобой? С Тем, что создавая тип List<int> я "параметризую его ОБЕРТКОЙ для типа int"?
... << RSDN@Home 1.2.0 alpha rev. 675>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re: Немножко о С# 3
От: _FRED_ Черногория
Дата: 23.03.07 09:08
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>2) Partial methods


AVK>Причем, если во втором файле Foo не описан, то вызов его будет выкинут.

А может ли определение "второго метода" браться из extension-классов? То есть имеем класс
partial class MyClass
{
  public MyClass()
  {
    Foo();
  }
  partial void Foo();
}

Далее создаём (в том же пространстве имён) класс
static class MyClassExtensions
{
  public static void Foo(this MyClass item) { … }
}

И при компиляции в месте вызова Foo в MyClass будет ли использована MyClassExtensions.Foo(MyClass)?
... << RSDN@Home 1.2.0 alpha rev. 675>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re[10]: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 09:29
Оценка: 6 (1) +3 :))) :))) :))) :)))
Здравствуйте, VladD2, Вы писали:

Все таки функциональное программирование страшная вещь — рано или поздно его приверженец объявляет войну старому косному миру.
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[2]: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 09:29
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А может ли определение "второго метода" браться из extension-классов?


Нет. А зачем?
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[18]: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 09:29
Оценка: +1 -1 :))) :)))
Здравствуйте, VladD2, Вы писали:

VD>А то получается идиотизм. С проект созданный под эгидой МС Ресерч не знакомы не только Хейльсберг


Получается действительно идиотизм. На прямо заданный вопрос Хейлсберг дал однозначный ответ — да, он смотрел на Немерле. Но этот факт разрушает стройную теорию мирового заговора против Немерле, так что тем хуже для фактов.
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[3]: Немножко о С# 3
От: _FRED_ Черногория
Дата: 23.03.07 09:38
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_FR>>А может ли определение "второго метода" браться из extension-классов?


AVK>Нет. А зачем?


Есть, например, некий генератор, который создаёт мне несколько классов. Генератор предоставляет мне возможность расширить поведение сгенерированного класса за счёт частичных методов. А если все эти методы должны быть одинаковыми?

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

Кстати, partial metod может быть определён не в том же классе, в в базовом (это опять-таки может пригодиться, когда можно задать базовый тип для сгенерированного класса).
... << RSDN@Home 1.2.0 alpha rev. 675>>
Now playing: «Тихо в лесу…»
Help will always be given at Hogwarts to those who ask for it.
Re: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 09:39
Оценка: 53 (7)
Здравствуйте, AndrewVK, Вы писали:

Продолжу. По поводу Немерле тут уже сказали. Еще я задал вопрос о возможности добавления паттерн-матчинга. Потом мы немножко поговорили о F#, в котором онный есть. Ответа конкретного я так и не получил. Т.е. вопрос добавления обсуждается, но никаких конкретных планов пока нет.
Далее, эти самые кортежи с глобальной доступностью. С очень большой вероятностью они появятся, как только появится оказия с поменянием рантайма. Т.е., ориентировочно, что то появится а .NET 4.0. Но Хейлсберг ничего не обещает.
Потом я задал вопрос — когда компилятор шарпа будет написан на шарпе. В ответ он сказал, что ему никто не даст на это денег, потому что в плане конечного результата это мало что изменит.
По поводу наличия парсера шарпа в составе платформы — крайне сложно создать AST, которое бы подходилодля всех (или большей части) задач. Но какие то работы на эту тему ведуться.
По поводу расширяемости компилятора (в плане кодогенератора прежде всего). Во-первых, (я вам этого не говорил ) код компилятора шарпа весьма грязен и сделать к нему публичный API непросто. Во-вторых Хейлсберг не хочет связывать себе руки необходимостью обеспечения совместимости с monkey code, который напишут прикладники.
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[19]: Немножко о С# 3
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 23.03.07 10:04
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

AVK>Получается действительно идиотизм. На прямо заданный вопрос Хейлсберг дал однозначный ответ — да, он смотрел на Немерле.


это Sinclair сказал — А вообще, конкретно про Nemerle он слышал, но детально не смотрел — не смог, как он говорит, найти внятную документацию.
Автор: Sinclair
Дата: 20.03.07
... << RSDN@Home 1.2.0 alpha rev. 675>>
Re[22]: Немножко о С# 3
От: migel  
Дата: 23.03.07 10:05
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


M>>Я тебе показал что реально быстрее — возражения будут? Или "богатеии копеек не считают"

WH>Ничего ты не показал.
Совсем совсем ничего? жаль
Ну а если по честному то стастистика показывает правильность решения введения двух команд
например на System.dll
частота использования ldc_i4_0...ldc_i4_8 на порядок больше ldc_i4_N (~6.6% против 0.67%)
... << RSDN@Home 1.2.0 alpha rev. 644>>
Re[20]: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 10:55
Оценка: +1
Здравствуйте, Odi$$ey, Вы писали:

OE>это Sinclair сказал — А вообще, конкретно про Nemerle он слышал, но детально не смотрел — не смог, как он говорит, найти внятную документацию.
Автор: Sinclair
Дата: 20.03.07


Т.е. "не смог найти внятную спецификацию" равно "не знаком"?
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[23]: Немножко о С# 3
От: WolfHound  
Дата: 23.03.07 11:12
Оценка:
Здравствуйте, migel, Вы писали:

M>Совсем совсем ничего? жаль

Имеено так.
Откуда берутся тормоза так и небыло показано.
Идинственное место в котором можно получить прирост это уменьшения времени которое нужно для того чтобы считать сборку с винта благодоря тому что ldc.i4.0 компактней чем просто ldc.i4.

M>Ну а если по честному то стастистика показывает правильность решения введения двух команд

Да ничего она не показывает.
Тогоже эффекта можно легко добится не корежа модель системы.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Немножко о С# 3
От: WolfHound  
Дата: 23.03.07 11:12
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Как ты собираешься объединять типы с разной семантикой? У примитивных типов — передача по значению, а у объектов — по ссылке. В этом коренное отличие.

.NET 2 с этим прекрасно справляется.

C>Не ортогонально. Оно у тебя просто прозрачно боксирует value-типы — и "возвращаемся обратно на клетку 1", получая весь оверхед, связаный с объектами.

C>Я как-то уже тут спорил с кем-то об этом. Поискать?
value типы в генерики можно засовывать без боксинга.
Совсем. Это не убогая жаба. Тут все работает как надо.
У нас ведь есть JIT который прекрасно может сгенерить нужный код для value параметров

C>Ничем бы это не помогло. Точно так же, можно было бы для боксирующей обертки просто добавить нужные методы. Это не требует изменения VM, а только стандартной библиотеки.

Нет никакой ложки... вренее боксинга.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Немножко о С# 3
От: WolfHound  
Дата: 23.03.07 11:12
Оценка: 24 (1)
Здравствуйте, Cyberax, Вы писали:

WH>>Не путай .NET и жабу. Это в жабе недогенерики, а в .NET2 все по честному.

C>Что по-честному? Хочешь сказать, что можно параметризовать незабоксироваными VT?
Именно так.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[21]: Немножко о С# 3
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 23.03.07 11:30
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

OE>>это Sinclair сказал — А вообще, конкретно про Nemerle он слышал, но детально не смотрел — не смог, как он говорит, найти внятную документацию.
Автор: Sinclair
Дата: 20.03.07

AVK>Т.е. "не смог найти внятную спецификацию" равно "не знаком"?

ну да, а с чем он тогда знаком
... << RSDN@Home 1.2.0 alpha rev. 675>>
Re[22]: Немножко о С# 3
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.03.07 11:46
Оценка: :)
Здравствуйте, Odi$$ey, Вы писали:

OE>ну да, а с чем он тогда знаком


Однако к чему этот максимализм???
... << RSDN@Home 1.2.0 alpha rev. 675>>
AVK Blog
Re[24]: Немножко о С# 3
От: migel  
Дата: 23.03.07 11:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


M>>Совсем совсем ничего? жаль

WH>Имеено так.
WH>Откуда берутся тормоза так и небыло показано.
WH>Идинственное место в котором можно получить прирост это уменьшения времени которое нужно для того чтобы считать сборку с винта благодоря тому что ldc.i4.0 компактней чем просто ldc.i4.

Зыж дык не надо аргумент с потока считывать ы?
Или сие не аргумент?

И стоило было разводить на десять топиков
... << RSDN@Home 1.2.0 alpha rev. 644>>
Re[25]: Немножко о С# 3
От: WolfHound  
Дата: 23.03.07 12:00
Оценка: :)
Здравствуйте, migel, Вы писали:

M>

M>Зыж дык не надо аргумент с потока считывать ы?
M>Или сие не аргумент?

Тебя похоже гдето заклинило. Ибо ты вобще не читаешь что я пишу.

M>И стоило было разводить на десять топиков

Так я и не знаю зачем ты это развел.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: Немножко о С# 3
От: Klapaucius  
Дата: 23.03.07 13:00
Оценка: 47 (3)
Здравствуйте, Cyberax, Вы писали:

C>Не ортогонально. Оно у тебя просто прозрачно боксирует value-типы — и "возвращаемся обратно на клетку 1", получая весь оверхед, связаный с объектами.


Вообще-то это не так.
Вот доказательство:
Как сделать на c# обобщенную арифметику? Это достаточно просто, хотя и выглядит весьма уродливо. Но работает.
Можно построить целую иерархию "классов типов":
    public interface CComparable<T>
    {
        bool GT(T a, T b);
        bool LT(T a, T b);
        bool Eq(T a, T b, T eps);
    }

    public interface CEq<T>
    {
        bool Eq(T a, T b);
        bool NonEq(T a, T b);
    }

    public interface COrdered<T> : CComparable<T>, CEq<T>
    {
        bool GTorEq(T a, T b);
        bool LTorEq(T a, T b);
    }

    public interface CNumber<T> : CComparable<T>
    {
        T Add(T a, T b);
        T Sub(T a, T b);
        T AddNeutral { get;} // 0
        T Prod(T a, T b);
        T ProdNeutral { get;} // 1
        T Abs(T a);
        T Negate(T a);
        T Signum(T a);
    }

    public interface CFractional<T> : CNumber<T>
    {
        T From(double a);
        T From(float a);
        T Quot(T a, T b);
        T Inv(T a);
    }

    public interface CInteger<T> : CNumber<T>, COrdered<T>
    {
        T From(int a);
        T From(long a);
        T Div(T a, T b);
        T Mod(T a, T b);
    }

    public interface CReal<T> : CFractional<T>
    {
        T Sqr(T a);
        T Sqrt(T a);
    }


А теперь, написать имплементации, например RealDouble:
    public struct RealDouble : CReal<double> // обратите внимание на struct
    {
        #region CFractional<double> Members

        public double From(double a)
        {
            return a;
        }

        public double From(float a)
        {
            return a;
        }

        public double Quot(double a, double b)
        {
            return a / b;
        }

        public double Inv(double a)
        {
            return 1 / a;
        }

        #endregion

        #region CNumber<double> Members

        public double Add(double a, double b)
        {
            return a + b;
        }

        public double Sub(double a, double b)
        {
            return a - b;
        }

        public double AddNeutral
        {
            get { return 0.0; }
        }

        public double Prod(double a, double b)
        {
            return a * b;
        }

        public double ProdNeutral
        {
            get { return 1.0; }
        }

        public double Abs(double a)
        {
            return Math.Abs(a);
        }

        public double Negate(double a)
        {
            return -a;
        }

        public double Signum(double a)
        {
            return Math.Sign(a);
        }

        #endregion

        #region CComparable<double> Members

        public bool GT(double a, double b)
        {
            return a > b;
        }

        public bool LT(double a, double b)
        {
            return a < b;
        }

        public bool Eq(double a, double b, double eps)
        {
            return Math.Abs(a - b) < eps;
        }

        #endregion

        #region CReal<double> Members

        public double Sqr(double a)
        {
            return a * a;
        }

        public double Sqrt(double a)
        {
            return Math.Sqrt(a);
        }

        #endregion
        }


Теперь сделаем комплексные числа:
    public struct Complex
    {
        public Complex(double re, double im)
        {
            Re = re;
            Im = im;
        }
        public double Re;
        public double Im;
        public static Complex operator +(Complex a, Complex b)
        {
            return new Complex(a.Re + b.Re, a.Im + b.Im);
        }
    }

    public struct Complex<T, C>
        where C : struct, CReal<T>
    {
        static C c = new C();

        public Complex(T re, T im)
        {
            Re = re;
            Im = im;
        }
        public T Re;
        public T Im;
        public static Complex<T, C> operator +(Complex<T, C> a, Complex<T, C> b)
        {
            return new Complex<T, C>(c.Add(a.Re, b.Re), c.Add(a.Im, b.Im));
        }
    }


Идея ясна? Если правы Вы, то во втором случае будут виртуальные вызовы (даже хуже, потому что CReal<T> это интерфейс)
Я же утверждаю, что никаких виртуальных вызовов не будет, более того, функция будет заинлайнена JIT.

Теперь пишем вот такой вот тест:
    class Program
    {
        static void Main(string[] args)
        {
                    System.Threading.Thread.Sleep(2000); // дадим время рантайму.
                
            Stopwatch sw = new Stopwatch();

            int count = 100000000;

            Complex c1 = new Complex();
            Complex c2 = new Complex(0, 1);

            Complex<double, RealDouble> gc1 = new Complex<double, RealDouble>();
            Complex<double, RealDouble> gc2 = new Complex<double, RealDouble>(0, 1);

            for (int i = 0; i < count/1000; i++) // это для того, чтобы исключить из замеров JIT-компиляцию.
            {
                c2 = c2 + c1;
            }

            for (int i = 0; i < count/1000; i++)
            {
                gc2 = gc2 + gc1;
            }

            sw.Start();
            for (int i = 0; i < count; i++)
            {
                c2 = c2 + c1;
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            sw.Reset();

            sw.Start();
            for (int i = 0; i < count; i++)
            {
                gc2 = gc2 + gc1;
            }
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
            sw.Reset();

            Console.ReadLine();
        }
    }


Компилируем в Release, запускаем без отладчика.
.NET Framework 2.0.50727
Xeon-A(Prestonia) X2, 2666 MHz
Получаем вот что:
2457
2454


quod erat demonstrandum.
... << RSDN@Home 1.2.0 alpha rev. 655>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[20]: Немножко о С# 3
От: Kisloid Мухосранск  
Дата: 23.03.07 15:55
Оценка:
Задумался вот о чем, а можно ли это сделать на Немерле?

Попробовал сам поковыряться в Немерле и даже попробовать кое-что на написать, вот что получилось:
    public class Vector3D ['a]
    {
        public mutable p : 'a * 'a * 'a;

        public static @+ (a : Vector3D ['a], b : Vector3D ['a]) : Vector3D ['a]
        {
            def res = Vector3D.['a]();
            res.p = (a.p[0].Sum(b.p[0]), a.p[1].Sum(b.p[1]), a.p[2].Sum(b.p[2]));
            res
        }

        public static Sum(this a : 'a, b : 'a) : 'a
        {
            def t = (a, b);

            match (t)
            {
                | (x, y) when (x is int && y is int) => (x :> int + y :> int) :> 'a
                // ... make the same for other types
            }
        }
    }

    public class Test
    {
            public static Main() : void
            {
            def v1 = Vector3D.[int]();
            def v2 = Vector3D.[int]();

            v1.p = (1, 1, 1);
            v2.p = (1, 2, 3);

            def v = v1 + v2;

            printf("(%d, %d, %d)\n", v.p[0], v.p[1], v.p[2]);
        }
    }


Получилось все равно кривовато, т.к. для своих типов надо перегрузив '+' добавить строчку в методе Sum. Ну и само по себе добавлять метод в object я думаю не очень хорошая практика.
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.