Что нужно добавить в C#?

AndrewVK AndrewVK
Небольшое вступление.
Сейчас сложилась такая ситуация, что для следующего релиза C# нет big thing, т.е. основной фичи, вокруг которой строится весь релиз (типа linq в 3 версии, динамиков в 4 и асинка в 5). Благодаря этому появилась возможность реализовать кучу мелких вещей, которые, с одной стороны, не требуют революций в языке их их можно реализовать сравнительно разумным объемом ресурсов, а с другой способны сильно облегчить жизнь.
Поэтому у меня есть желание сформировать некий документ со списком фич и отдать его дизайнерам шарпа. Гарантии, что хоть что то из него будет реализовано нет никакой, но шансы этого высоки как никогда
Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам. Желательно раскрыть мысль поподробнее. Идеально было бы привести гипотетический пример исходного кода с описанием его семантики, и потом примерный код на текущем шарпе, в который первый пример должен раскрываться.
Проголосовать за конкретные фичи можно здесь.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
kaa.python
kaa.python
19.02.2013 12:00
Все очень и очень просто: Java-way — работа на *NIX-ах из коробки
AndrewVK
AndrewVK
19.02.2013 12:02
Здравствуйте, kaa.python, Вы писали:

KP>Все очень и очень просто: Java-way — работа на *NIX-ах из коробки


При чем тут компилятор шарпа? Это вопрос к CLR.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
kaa.python
kaa.python
19.02.2013 12:05
Здравствуйте, AndrewVK, Вы писали:

AVK>При чем тут компилятор шарпа? Это вопрос к CLR.


Ну, это как сказать. С одной стороны да. С другой стороны, CLR — это в первую очередь C#, так же как JVM это в первую очередь Java. Они неразрывно связанны и обсуждение одного в отрыве от второго бессмысленно.
AndrewVK
AndrewVK
19.02.2013 12:09
Здравствуйте, kaa.python, Вы писали:

KP>Ну, это как сказать.


Как ни говори — в контексте данного вопроса это точно обсуждать смысла нет.

KP>С другой стороны, CLR — это в первую очередь C#


Я бы так не сказал. В любом случае — изменения в CLR это уже точно революция, и это другая команда. И вообще это больше политика, нежели технический вопрос.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
koandrew
koandrew
04.04.2013 04:37
Здравствуйте, kaa.python, Вы писали:

KP>Ну, это как сказать. С одной стороны да. С другой стороны, CLR — это в первую очередь C#, так же как JVM это в первую очередь Java. Они неразрывно связанны и обсуждение одного в отрыве от второго бессмысленно.


Наличие Mono как бы намекает, что вы ерунду говорите
Don Reba
Don Reba
19.02.2013 12:31
Здравствуйте, AndrewVK, Вы писали:

Мне в Шарпе не хватает одной фичи из Немерле: foreach c индексатором, типа:

foreach (var x from collection with i)

Здесь i номер текущей итерации.
VladD2
VladD2
19.02.2013 12:45
Здравствуйте, Don Reba, Вы писали:

DR>
foreach (var x from collection with i)

DR>Здесь i номер текущей итерации.

А... раз пошла такая пьянка, то можно и остальные фичи из Немерла реализовать .
G-Host
G-Host
21.02.2013 01:45
Здравствуйте, Don Reba, Вы писали:

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


DR>Мне в Шарпе не хватает одной фичи из Немерле: foreach c индексатором, типа:


DR>
foreach (var x from collection with i)

DR>Здесь i номер текущей итерации.
в чем существенная польза? не так часто нужно, а если нужно то можно индексировать самому.
или я не так понял идею?
Don Reba
Don Reba
21.02.2013 02:04
Здравствуйте, G-Host, Вы писали:

GH>в чем существенная польза? не так часто нужно, а если нужно то можно индексировать самому.

GH>или я не так понял идею?

Мне не так уж и редко приходится оборачивать foreach в ручную реализацию for. Вот несколько сценариев:

foreach (var x in myEnum with i)
{
    if (i == 0)
        // ...
    else
        // ...
}

foreach (var x in myEnum with i)
    Console.WriteLine("{0,-2}: {1}", i + 1, x);

foreach (var x in myEnumwith i)
    DoSomething(x, myArray[i]);
alexanderfedin
alexanderfedin
01.03.2013 01:07
Здравствуйте, Don Reba, Вы писали:

overquoting

Зачем в языке делать то, что можно сделать в библиотеке?
IEnumerable<Tuple<T, int>> WithIndex(this IEnumerable<T> sequence)
{
    int i = 0;
    foreach (var elem in sequence)
    {
        yield return Tuple.Create(elem, i++);
    }
}
Gollum
Gollum
19.02.2013 12:37
Здравствуйте, AndrewVK, Вы писали:

AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.


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

Вот например, (псевдо)код на питоне (копипаста из документации)

word = 'HelpA'

>>> word[2:4]
'lp'

>>> word[:2]
'He'

>>> word[2:]
'lpA'

>>> word[-1]     # The last character
'A'
>>> word[-2]     # The last-but-one character
'p'
>>> word[-2:]    # The last two characters
'pA'
>>> word[:-2]    # All but the last two characters
'Hel'


Потом можно прицениться к спискам
Цыба
Цыба
19.02.2013 01:24
Здравствуйте, AndrewVK, Вы писали:

AVK>Небольшое вступление.

AVK>Сейчас сложилась такая ситуация, что для следующего релиза C# нет big thing, т.е. основной фичи, вокруг которой строится весь релиз (типа linq в 3 версии, динамиков в 4 и асинка в 5). Благодаря этому появилась возможность реализовать кучу мелких вещей, которые, с одной стороны, не требуют революций в языке их их можно реализовать сравнительно разумным объемом ресурсов, а с другой способны сильно облегчить жизнь.
AVK>Поэтому у меня есть желание сформировать некий документ со списком фич и отдать его дизайнерам шарпа. Гарантии, что хоть что то из него будет реализовано нет никакой, но шансы этого высоки как никогда
AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам. Желательно раскрыть мысль поподробнее. Идеально было бы привести гипотетический пример исходного кода с описанием его семантики, и потом примерный код на текущем шарпе, в который первый пример должен раскрываться.
AVK>Проголосовать за конкретные фичи можно здесь.

Вряд ли скажу big thing, но мелкие доработки были бы очень даже неплохи. Сам начинал с C#, потом судьба забросила на Java, и могу сказать, что оба языка прекрасны, и всё же C#-у стоило бы позаимствовать некоторые Java-фишки.

  • Строгий типизированный "объектный" enum, как в Java 1.5. Здорово решают проблему хранение некоего "регистра" того или иного набора данных. В отличии от примитивных целочисленных констант в шарпе, в Java можно не хило так "полиморфировать" enum-константы, наделяя их реализациями интерфейсов, абстрактных методов, не говоря уже об обычных полях и методах. Небезысвестный Jon Skeet уже как семь лет назад говорил о таком. Компилятор справился бы с перечислениями, я думаю, без изменения CLR.
  • Возможно, пересмотреть всеобъемлющую директиву using, которая открывает иногда слишком много. В этом контексте я бы пересмотрел также импорт методов расширения, которые не пойми откуда появляются, а также добавил бы "статический импорт": после Java, с её возможностью импортирования статических методов и полей, Console.WriteLine() выглядит уродливо. И если с первыми двумя уже, скорее всего, уже ничего не поделать, то третье можно привинтить было бы.
  • Возможно, виртуальные методы расширения, как в Java 8 (единственное поведение по умолчанию для интерфейсов как бы "встраивается" без необходимости открывать методы расширения, реализация поведения которых зависит, в принципе, от того, что открыто). Но, наверно, это сомнительное пожелание в контексте уже существующих методов-расширений C#.
  • После анонимных классов в Java руки автоматически тянутся писать такое же и в C#-коде. Можно, конечно, часто обойтись делегатами, но анонимные классы в Java позволяют инкапсулировать состояние.
  • Сигнатурные ограничения для конструкторов обобщённых типов: не просто конструктор по умолчанию, а возможность указать желаемую сигнатуру конструктора объекта. Например, для инджектирования объекта через конструктор, а не через свойства -- раз и до конца жизни объекта.
  • Лично мне "as" не очень нравится. Может быть, такое:
    cast ( oldVar as Type newVar ) { ... }

    вместо
    var newVar = oldVar as Type;
    if ( newVar != null ) {
        ...
    }

  • Часто работаю с рефлексией на Java, но и там самая крутая возможность ссылаться на что-то без строки с именем, а по имени напрямую -- Type.class (typeof(Type) в C#). Иногда очень хочется такого и для методов (делегаты делают нечто похожее), полей и свойств. Таким образом рефакторинг таких вещей происходил бы менее болезненно.
  • И всякие плюшки в виде интерполированных строк, литералы для регулярок, этц, хотя это уже на любителя...

А если big thing, то, наверное, макросы.
AndrewVK
AndrewVK
19.02.2013 01:32
Здравствуйте, Цыба, Вы писали:

Ц>литералы для регулярок


По поводу этого Мэдс сегодня сказал примерно следующее: You mean literal of the day?
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
Цыба
Цыба
19.02.2013 01:39
Здравствуйте, AndrewVK, Вы писали:

AVK>По поводу этого Мэдс сегодня сказал примерно следующее: You mean literal of the day?


Есть "покруче".
kaa.python
kaa.python
19.02.2013 02:16
Здравствуйте, Цыба, Вы писали:

Ц>Есть "покруче".


ААА! Вот откуда эту идею в Rust притащили
Don Reba
Don Reba
19.02.2013 02:22
Здравствуйте, kaa.python, Вы писали:

KP>ААА! Вот откуда эту идею в Rust притащили


В Немерле было раньше.
VladD2
VladD2
19.02.2013 03:59
Здравствуйте, kaa.python, Вы писали:

Ц>>Есть "покруче".

KP>ААА! Вот откуда эту идею в Rust притащили

Гы-гы (2005-й год). Думаю, что и до этого где-то было.
Roman Odaisky
Roman Odaisky
21.02.2013 09:03
Здравствуйте, VladD2, Вы писали:

Ц>>>Есть "покруче".

KP>>ААА! Вот откуда эту идею в Rust притащили
VD>Гы-гы (2005-й год). Думаю, что и до этого где-то было.

В Perl было еще в прошлом веке.
gravatar
Аноним
19.02.2013 06:54
Здравствуйте, Цыба, Вы писали:

Ц>Небезысвестный Jon Skeet уже как семь лет назад говорил о таком. Компилятор справился бы с перечислениями, я думаю, без изменения CLR.


При всем моем уважении к Скиту, его идея супернавороченных enum'ов мне не нравится. Что чаще всего надо? Парсинг и прочие конвертеры привязать к enum'у, чтобы не болтались в левых классах типа Utils. То есть, если иметь возможность добавить статические методы, этого более чем достаточно. Объявлять enum каким-то class enum совсем не надо. Ну, или, если хочется иметь методы .To(), можно сделать как в мутаторах — в контексте нестатических методов enum'а считать value ключевым словом.

Все остальное решается через наследование. Наследуйся, там добавишь все, что надо. Примерно, как от класса с одним целочисленным полем. Соответственно, доступ к значению через то же самое base.value.
Цыба
Цыба
19.02.2013 12:48
Здравствуйте, Аноним, Вы писали:

А>При всем моем уважении к Скиту, его идея супернавороченных enum'ов мне не нравится. Что чаще всего надо? Парсинг и прочие конвертеры привязать к enum'у, чтобы не болтались в левых классах типа Utils. То есть, если иметь возможность добавить статические методы, этого более чем достаточно. Объявлять enum каким-то class enum совсем не надо. Ну, или, если хочется иметь методы .To(), можно сделать как в мутаторах — в контексте нестатических методов enum'а считать value ключевым словом.


А>Все остальное решается через наследование. Наследуйся, там добавишь все, что надо. Примерно, как от класса с одним целочисленным полем. Соответственно, доступ к значению через то же самое base.value.


Мутно как-то. В Java, кроме того, такие перечисления можно использовать в аннотациях (аттрибутах в терминологии C#).
gravatar
Аноним
19.02.2013 01:21
Здравствуйте, Цыба, Вы писали:

Ц>Здравствуйте, Аноним, Вы писали:


А>>При всем моем уважении к Скиту, его идея супернавороченных enum'ов мне не нравится. Что чаще всего надо? Парсинг и прочие конвертеры привязать к enum'у, чтобы не болтались в левых классах типа Utils. То есть, если иметь возможность добавить статические методы, этого более чем достаточно. Объявлять enum каким-то class enum совсем не надо. Ну, или, если хочется иметь методы .To(), можно сделать как в мутаторах — в контексте нестатических методов enum'а считать value ключевым словом.


А>>Все остальное решается через наследование. Наследуйся, там добавишь все, что надо. Примерно, как от класса с одним целочисленным полем. Соответственно, доступ к значению через то же самое base.value.


Ц>Мутно как-то. В Java, кроме того, такие перечисления можно использовать в аннотациях (аттрибутах в терминологии C#).


Я не понимаю, что значит "мутно".

Я исхожу из реальной проблемы: часто встречаешь набор функций, которые относятся только к enum'у, но хостятся в классе Utils, Converters и т.п. Если их можно было бы засунуть в сам enum, было бы понятно:

public enum LengthUnit
{
    Millimeter = 1,
    Meter = 1000,
    Inch = 25400;

    public static LengthUnit Parse(string text)
    {
        if (text == "mm") return LengthUnit.Millimeter;
        if (text == "m") return LengthUnit.Meter;
        if (text == "\"") return LengthUnit.Inch;
    }

    public string GetSystem()
    {
        switch (value)
        {
            case LengthUnit.Millimeter:
            case LengthUnit.Meter:
                return "Metric";
            case LengthUnit.Inch:
                return "US";
            default: return string.Empty;
        }
    }
}

...

var system = LengthUnit.Parse("mm").GetSystem();


Какие проблемы у Скита решаются с помощью class enum мне понять вообще не удалось.

То есть, я боюсь, что если и сделают енамы более объектными, то вместо маленького нужного инструмента зафигачат большой и ненужный. Если кому-то нужен класс и enum в одном флаконе, пусть пишет, как в PHP, то есть, класс с константами, с методами, конструкторами и прочим. А чтобы не копипастить код, когда уже есть enum, а свой такой класс надо построить на его базе, вполне достаточно поддержать наследование. И наследование самих enum'ов, конечно. Тоже не хватает, чтобы, допустим, от enum'а с секундой унаследовать как СИ, так и грамм-секундную систему. И чтобы секунда там и там была одной и той же.
Цыба
Цыба
21.02.2013 02:22
Здравствуйте, Аноним, Вы писали:

А>Я исхожу из реальной проблемы: часто встречаешь набор функций, которые относятся только к enum'у, но хостятся в классе Utils, Converters и т.п. Если их можно было бы засунуть в сам enum, было бы понятно:


Решение не менее реальной проблемы на Java:

                             // V - для своего lookupIndexedEnumValue() в ответ на жирный аналог в LengthUnit.Parse
public enum RoleType implements IIndexable<String>, IRoleAuthorizationContextFactory  {

    ADMINISTRATOR("admin") {
        @Override
        public IRoleAuthorizationContext createRoleAuthorizationContext(Request request) {
            return new AdministratorRoleAuthorizationContext();
        }
    },

    EDITOR("editor") {
        @Override
        public IRoleAuthorizationContext createRoleAuthorizationContext(Request request) {
            return new EditorRoleAuthorizationContext(request);
        }
    };

    private final String alias;

    RoleType(String alias) {
        this.alias = alias;
    }

    @Override
    public final String getIndexKey() {
        return alias;
    }

}


И внезапно в аннотациях/аттрибутах:

public interface IService {

    @Role(ADMINISTRATOR)
    void foo();

    @Role(EDITOR)
    void bar();

}


Что здесь плохого?
gravatar
Аноним
22.02.2013 10:47
Здравствуйте, Цыба, Вы писали:

Ц>Что здесь плохого?


Не уверен, что я все понял правильно, и если нет, сразу простите дурака. Но если да, то это типичный пример ява-стайл ОООП'а (Over-engineered OOP), который меня просто убивает.

Плохо в этом примере то, что он скрывает неявное множественное наследование от System.Attribute и System.Enum.

Вообще, я за ООП в целом и множественное наследование в частности в каждом УЯП, но МН нужно таааааак редко... и это явно не тот случай. Пусть котлеты будут отдельно, а мухи — отдельно:

public enum RoleType
{
    ADMINISTRATOR,
    EDITOR;

    public IRoleAuthorizationContext ToContext(Request request)
    {
        switch (value)
        {
            case ADMINISTRATOR: return new AdministratorRoleAuthorizationContext(); break;
            case EDITOR:        return new EditorRoleAuthorizationContext(request); break;
            default:            throw new Exception("A new role was added with no converting code."); break;
        }
    }
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RoleTypeAttribute : System.Attribute
{
    ...
}

public interface IService
{
    [RoleTypeAttribute(RoleType.ADMINISTRATOR)]
    void foo();

    [RoleTypeAttribute(RoleType.EDITOR)]
    void bar();
}


Обратите внимание на выделенное. Где ему место в вашем примере?

И раз уж речь зашла о нововведениях и Ските, то вот тут:

http://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types

Скит пишет следующее:

Well, I can't answer why it's not available, but I can confirm that it's not a CLI issue. The CLI spec doesn't mention it (as far as I can see) and if you use IL directly you can create a generic attribute. The part of the C# 3 spec that bans it — section 10.1.4 "Class base specification" doesn't give any justification.

The annotated ECMA C# 2 spec doesn't give any helpful information either, although it does provide an example of what's not allowed.

My copy of the annotated C# 3 spec should arrive tomorrow... I'll see if that gives any more information. Anyway, it's definitely a language decision rather than a runtime one.

EDIT: Answer from Eric Lippert (paraphrased): no particular reason, except to avoid complexity in both the language and compiler for a use case which doesn't add much value.


Так что, если бы они ЭТО пофиксили, то ваш пример (именно ваш, без привязки к методам и с потенциальной неоднозначностью ролей) мог бы выглядеть так:

public enum RoleType
{
    ADMINISTRATOR,
    EDITOR;

    public IRoleAuthorizationContext ToContext(Request request)
    {
        switch (value)
        {
            case ADMINISTRATOR: return new AdministratorRoleAuthorizationContext(); break;
            case EDITOR:        return new EditorRoleAuthorizationContext(request); break;
            default:            throw new Exception("A new role was added with no converting code."); break;
        }
    }
}

public interface IService
{
    [System.EnumAttribute<RoleType>(RoleType.ADMINISTRATOR)]
    void foo();

    [System.EnumAttribute<RoleType>(RoleType.EDITOR)]
    void bar();
}


P.S. Чего мне в дотнете всегда не хватало, это набора стандартизированных интерфейсов, чтоб не пилить самому каждый раз, особенно в ремотных системах. System.EnumAttribute<T> это как раз из этой оперы.
Цыба
Цыба
22.02.2013 11:30
Здравствуйте, Аноним, Вы писали:

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

А>Не уверен, что я все понял правильно, и если нет, сразу простите дурака. Но если да, то это типичный пример ява-стайл ОООП'а (Over-engineered OOP), который меня просто убивает.


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

А>Плохо в этом примере то, что он скрывает неявное множественное наследование от System.Attribute и System.Enum.


Тут нет множественного наследования и не может такового быть. Перечисления неявно наследуются исключительно от java.lang.Enum<E>, хотя и имплементирует интерфейс. Пожалуй, я неудачно выбрал имена Role и RoleType? То, что вы, возможно, посчитали за наследование от System.Attribute -- аннотация @Role, аналог [RoleAttribute] (укажу ниже). Я здесь имел в виду то, что элемент такого перечисления может появляться в качестве значения аннотации. В .NET такое невозможно, насколько мне известно, и поэтому приходится довольствоваться только тем, что может быть константой (по поводу typeof не знаю, то в Java это считается константой, как и элемент перечисления). Могу ошибаться.

А>Обратите внимание на выделенное. Где ему место в вашем примере?


Я тогда просто хотел показать, что полноценный объект, хоть и с ограничениями enum и @interface на типы, а не простая целочисленная константа, может указываться в аннотации (аттрибута). Собственно, тогда уж и недостающий пример:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Role { // аналог аттрибута; аналога AllowMultiple не существует

    RoleType value();    // RoleType - само перечесление, которое можно использовать в качестве значения анотации (value можно опускать)

}


А>И раз уж речь зашла о нововведениях и Ските, то вот тут:

А>http://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types
А>Скит пишет следующее:
А>...

@interface в Java тоже не может быть generic, как и enum. В моём случае перечисление просто обязуется реализовать параметризированный generic-интерфейс (для поиска члена перечисления не по имени, а по алиасу). Мне, честно говоря, сложно подобрать случай, в котором нужны generic-аттрибуты, когда из доступных значений аттрибутов могут быть только примитивы и строки.
alexanderfedin
alexanderfedin
01.03.2013 01:20
Здравствуйте, Аноним, Вы писали:

overquoting
А>Какие проблемы у Скита решаются с помощью class enum мне понять вообще не удалось.

А>То есть, я боюсь, что если и сделают енамы более объектными, то вместо маленького нужного инструмента зафигачат большой и ненужный. Если кому-то нужен класс и enum в одном флаконе, пусть пишет, как в PHP, то есть, класс с константами, с методами, конструкторами и прочим. А чтобы не копипастить код, когда уже есть enum, а свой такой класс надо построить на его базе, вполне достаточно поддержать наследование. И наследование самих enum'ов, конечно. Тоже не хватает, чтобы, допустим, от enum'а с секундой унаследовать как СИ, так и грамм-секундную систему. И чтобы секунда там и там была одной и той же.


public enum LengthUnit
{
    Millimeter = 1,
    Meter = 1000,
    Inch = 25400;
}

public static class LengthUnitExtensions
    public static LengthUnit Parse(this string text)
    {
        if (text == "mm") return LengthUnit.Millimeter;
        if (text == "m") return LengthUnit.Meter;
        if (text == "\"") return LengthUnit.Inch;
    }

    public string GetSystem(this LengthUnit value)
    {
        switch (value)
        {
            case LengthUnit.Millimeter:
            case LengthUnit.Meter:
                return "Metric";
            case LengthUnit.Inch:
                return "US";
            default: return string.Empty;
        }
    }
}

...

var system = "mm".Parse().GetSystem();
xorets
xorets
19.02.2013 07:53
Ц>* Сигнатурные ограничения для конструкторов обобщённых типов: не просто конструктор по умолчанию, а возможность указать желаемую сигнатуру конструктора объекта. Например, для инджектирования объекта через конструктор, а не через свойства -- раз и до конца жизни объекта.

Очень поддерживаю. Нужна возможность декларировать интерфейс создания семейства объектов.
Цыба
Цыба
19.02.2013 08:09
Здравствуйте, xorets, Вы писали:

X>Очень поддерживаю. Нужна возможность декларировать интерфейс создания семейства объектов.


Это просто идея, и я не уверен в её состоятельности. Я на самом деле очень люблю неизменяемые типы, но таким образом даже от левого класса нужна поддержка такого специфического конструирования объекта, хотя это забота уже самого типа. Поведение принято решать через методы интерфейсов. Быть может, здесь лучше использовать фабрику объектов, которая знает как создать неизменяемый объект?
gravatar
Аноним
21.02.2013 05:56
Здравствуйте, Цыба, Вы писали:

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


X>>Очень поддерживаю. Нужна возможность декларировать интерфейс создания семейства объектов.


Ц>Это просто идея, и я не уверен в её состоятельности. Я на самом деле очень люблю неизменяемые типы, но таким образом даже от левого класса нужна поддержка такого специфического конструирования объекта, хотя это забота уже самого типа. Поведение принято решать через методы интерфейсов. Быть может, здесь лучше использовать фабрику объектов, которая знает как создать неизменяемый объект?


Фабрика в этом случае — это лишний класс на пустом месте. Все правки шарпа как раз и нацелены на уменьшение количества "лишнего" кода.Так что считаю, что идея очень правильная. Сам тоже об этом думал: http://blogs.byte-force.com/xor/archive/2004/11/04/333.aspx


У меня еще была идея, что в лженериках был бы полезен thistype: http://blogs.byte-force.com/xor/archive/2009/09/15/thistype-for-generics.aspx
Qbit86
Qbit86 Лженерики
21.02.2013 05:59
Здравствуйте, Аноним, Вы писали:

А>У меня еще была идея, что в лженериках был бы полезен thistype: http://blogs.byte-force.com/xor/archive/2009/09/15/thistype-for-generics.aspx


О, хорошее слово «лженерики». «Лженерики» — это дженерики в Джаве.
xorets
xorets
21.02.2013 07:31
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, Аноним, Вы писали:


А>>У меня еще была идея, что в лженериках был бы полезен thistype: http://blogs.byte-force.com/xor/archive/2009/09/15/thistype-for-generics.aspx


Q>О, хорошее слово «лженерики». «Лженерики» — это дженерики в Джаве.


На планшете вечно мимо кнопок промахиваюсь. Иногда — удачно.
Sinix
Sinix
19.02.2013 05:48
Здравствуйте, AndrewVK, Вы писали:

AVK>Небольшое вступление.

AVK>Сейчас сложилась такая ситуация, что для следующего релиза C# нет big thing, т.е. основной фичи, вокруг которой строится весь релиз (типа linq в 3 версии, динамиков в 4 и асинка в 5). Благодаря этому появилась возможность реализовать кучу мелких вещей, которые, с одной стороны, не требуют революций в языке их их можно реализовать сравнительно разумным объемом ресурсов, а с другой способны сильно облегчить жизнь.
AVK>Поэтому у меня есть желание сформировать некий документ со списком фич и отдать его дизайнерам шарпа. Гарантии, что хоть что то из него будет реализовано нет никакой, но шансы этого высоки как никогда

Последнее, что я слышал — все по уши застряли в Рослине, сильно сомневаюсь, что у них хватит сил на что-то ещё. Из мелочей в голову приходит только вот это:

1. По аналогии с [CallerMemberName] и прочими — [ArgExpression]: текст выражения в заданном атрибуте:
public static void AssertFileExists(string filePath, [ArgExpression("filePath")] argName = "")
{
  if (!File.Exists(filePath))
    throw new ArgumentException(argName, "...");
}

// ...
  AssertFileExists(someClass.SomePath); // throws ArgumentException, argument name = "someClass.SomePath"


2. Явный duck typing, что то вида
  class A { SomeMethod(); } // Чужая сборка.
  interface IB { SomeMethod(); }

// ...
  var a = new A()
  var b = a mapas IB; // синтаксис - первый пришедший в голову. Всё разруливается в compile time - генерится обёртка, строчка превращается в b = new <>c__Wrapper_A_IB(a).

Для скриптов (раз уж у нас шарп в ближайшем будущем можно будет хостить) можно дополнить анонимные типы до того, что есть в яве и добавить возможность передавать анонимные типы шарпа за границы метода (пускай и только для internal/protected-методов).

Но, опять-таки, если рослин допилят, такие мелочи можно будет сделать и самому, благо возможностей выше крыши. Code rewrite, AOP, рефакторинг, code analysis, script hosting — имхо, вполне тянет на big thing.

Ещё, судя по полунамёкам Липперта (сейчас не найду, но было ещё в паре статей), compiler team периодически думает над добавлением явного маппинга "ключевое слово — вызов подходящего метода", как это сделано для linq/foreach/await. Выглядит интересно, но насколько оно будет полезно на практике —
AndrewVK
AndrewVK
20.02.2013 12:16
Здравствуйте, Sinix, Вы писали:

S>Последнее, что я слышал — все по уши застряли в Рослине, сильно сомневаюсь, что у них хватит сил на что-то ещё


Я не могу озвучивать конкретики, но ситуация несколько иная сейчас.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
Sinix
Sinix
20.02.2013 05:51
Здравствуйте, AndrewVK, Вы писали:

S>>Последнее, что я слышал — все по уши застряли в Рослине, сильно сомневаюсь, что у них хватит сил на что-то ещё

AVK>Я не могу озвучивать конкретики, но ситуация несколько иная сейчас.

Ок, значит отстал от жизни. Удачи им
Qbit86
Qbit86 Let/where
19.02.2013 05:59
Здравствуйте, AndrewVK, Вы писали:

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

AVK>Поэтому у меня есть желание сформировать некий документ со списком фич и отдать его дизайнерам шарпа. Гарантии, что хоть что то из него будет реализовано нет никакой, но шансы этого высоки как никогда
AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам. Желательно раскрыть мысль поподробнее. Идеально было бы привести гипотетический пример исходного кода с описанием его семантики, и потом примерный код на текущем шарпе, в который первый пример должен раскрываться.

Хочу какой-нибудь синтаксический сахар для let/where: http://bik-top.livejournal.com/50984.html
IT
IT
19.02.2013 06:10
Здравствуйте, AndrewVK, Вы писали:

AVK>Проголосовать за конкретные фичи можно здесь.


— Вывод типов при вызове констркуторов.
— nameof/infoof и т.п.
— приделать к query comprehensions to list, to array, first, single, top, skip и т.п.
— ПМ и АТД.
k0st1x
k0st1x
19.02.2013 06:29
Здравствуйте, IT, Вы писали:

IT>- Вывод типов при вызове констркуторов.

+100
k0st1x
k0st1x
19.02.2013 06:52
Здравствуйте, IT, Вы писали:

IT>- ПМ и АТД.


дико извиняюсь, что такое "ПМ" и что такое "АТД"?
gravatar
Аноним
19.02.2013 07:08
K>дико извиняюсь, что такое "ПМ" и что такое "АТД"?
по всей видимости, паттерн матчинг и алгебраические типы данных.
VladD2
VladD2
19.02.2013 04:10
Здравствуйте, k0st1x, Вы писали:

K>дико извиняюсь, что такое "ПМ" и что такое "АТД"?


Агебраические типы данных (ака Варианты или ограниченные объеденения) и сопоставление по ним.

http://nemerle.org/wiki/Grok_Variants_and_matching
Gollum
Gollum
19.02.2013 05:51
Здравствуйте, IT, Вы писали:

IT>- Вывод типов при вызове констркуторов.

IT>- приделать к query comprehensions to list, to array, first, single, top, skip и т.п.

+1

IT>- nameof/infoof и т.п.

IT>- ПМ и АТД.

Ну у вас и мелочи
IT
IT
19.02.2013 07:17
Здравствуйте, Gollum, Вы писали:

IT>>- ПМ и АТД.

G>Ну у вас и мелочи

На самом деле если разобраться, то и то и другое — это сахар. АТД — это плоская иерархия, по типу Linq.Expressions только с информацией о соответствии полей/свойст класса с их позиционированием в паттернах для ПМ. Немерле, кстати, умеет задавать такую информацию в том числе и для обычных классов. ПМ — это всего лишь навороченный switch/if с максимально компактным синтаксисом, включающим распаковку структур данных, и умным алгоритмом оптимизации перебора условий.

Единственное чем ПМ может не вписаться в C# — так это то, что в том же Немерле всё есть выражение и все языковые конструкции могут возвращать значение.
AndrewVK
AndrewVK
20.02.2013 12:26
Здравствуйте, IT, Вы писали:

IT>- ПМ и АТД.


Основная проблема с ПМ, как озвучил Мэдс, в АТД. Это новый first class citizen, который отчасти дублирует существующие сущности в языке. Так что АТД ака discriminated unions на данный момент однозначно no way. Теоретически можно обойтись без АТД существующими типами с какими то дополнительными доработками, но тут нужно говорить более конкретно.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
IT
IT
20.02.2013 06:23
Здравствуйте, AndrewVK, Вы писали:

IT>>- ПМ и АТД.


AVK>Основная проблема с ПМ, как озвучил Мэдс, в АТД. Это новый first class citizen, который отчасти дублирует существующие сущности в языке.


И чего оно такого дублирует?
AndrewVK
AndrewVK
20.02.2013 06:53
Здравствуйте, IT, Вы писали:

IT>И чего оно такого дублирует?


Обычные классы с виртуальными методами.
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
samius
samius
20.02.2013 07:00
Здравствуйте, AndrewVK, Вы писали:

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


IT>>И чего оно такого дублирует?


AVK>Обычные классы с виртуальными методами.


А какая проблема в дублировании? В F# и Nemerle есть и обычные классы и АлгТД
VladD2
VladD2
23.02.2013 08:32
Здравствуйте, samius, Вы писали:

S>А какая проблема в дублировании? В F# и Nemerle есть и обычные классы и АлгТД


Это не объектно-ориентированно! Вот то ли дело энумы в Яве?!

Хомечкам порвет мозг от возможности сделать что-то двумя путями. Пусть лучше паттернами проектирования пользуются и is/as-ами. А то не дай бок прострелят себе ногу не в том мести, а МС отвечать за это.
IT
IT
20.02.2013 03:27
Здравствуйте, AndrewVK, Вы писали:

IT>>И чего оно такого дублирует?

AVK>Обычные классы с виртуальными методами.

Так можно договориться до того, что любой класс дублирует функциональность object.
VladD2
VladD2
23.02.2013 08:29
Здравствуйте, AndrewVK, Вы писали:

IT>>И чего оно такого дублирует?


AVK>Обычные классы с виртуальными методами.


А чё ж с виртуальными то? Без них было бы проще?

А is/as их не дублирует? А то я тут много кода видел с is/as вместо "обычных виртуальных методов".

Об остальном я уже рядом написал.
VladD2
VladD2
23.02.2013 08:20
Здравствуйте, AndrewVK, Вы писали:

AVK>Основная проблема с ПМ, как озвучил Мэдс, в АТД. Это новый first class citizen, который отчасти дублирует существующие сущности в языке. Так что АТД ака discriminated unions на данный момент однозначно no way. Теоретически можно обойтись без АТД существующими типами с какими то дополнительными доработками, но тут нужно говорить более конкретно.


Перевожу на русский язык — "Нам хочется еще лет 5-10 по-вредничать.", потому как в ином случае объяснить подобные утверждения можно только недостатком знаний и не желанием смотреть на то что валяется под ногами.

Начнем с того, что ПМ не имеет никакого отношения к АлгТД (АлгТД потому как АТД принято расшифровывать как Абстрактный Тип Данных, что из другой оперы).

Две основные фичи ПМ, которые делают его мощной штукой это:
1. Рекурсивность.
2. Динамические проверки типов.

Вот пример ПМ по классам из N2:
match (RuleSymbol)
{
  | ExtensibleRuleSymbol => ()
  | ExtentionRuleSymbol(BaseRule = RuleRef.Some(baseRuleSymbol), ExtentionType = Prefix) =>
    defineExtentionRuleMethods(baseRuleSymbol)

  | ExtentionRuleSymbol(BaseRule = RuleRef.Some(baseRuleSymbol), ExtentionType = Postfix(bindingPower, _)) =>
    defineExtentionRuleMethods(baseRuleSymbol);
    _descriptorTb.DefineConditional(<[decl: public override BindingPower : int { get { $(bindingPower : int) } } ]>);

  | SimpleRuleSymbol  => defineNewParserMethod(<[ N2.Internal.SimpleRuleParser ]>);
  | RegularRuleSymbol => ()
  | _       => assert(false)
}

Здесь BaseRule и ExtentionType — это поля имеющие вариантный тип (АлгТД), а все остальное — это классы.
RuleSymbol — это свойство типа RuleDefSymbol, а ExtensibleRuleSymbol, ExtentionRuleSymbol, SimpleRuleSymbol и RegularRuleSymbol его наследники. Причем непрямые.

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

Кстати, закрытость набора можно обеспечить банальным seled.

Есть только одна фича МП которая упирается в возможности АлгТД — описание паттерна в виде конструктора. Это позволяет несколько сократить синтаксис описывая состояние объекта в виде параметров его конструктора. Чтобы это было возможно нужно иметь соответствие между полями типа и параметрами конструктора.

Так вот, во-первых можно обходиться несколько более длинным синтаксисом в котором внутри паттерна явно указывается имя члена который нужно проверить. Зачастую это даже оказывается более удобным, так как позволяет не перечислять все параметры конструктора забивая большую часть вилдкардами (знаком _ в ФЯ).

Во-вторых, соответствие между аргументами конструктора и полями можно задать и способами отличными от тех что используются в АлгТД. Например, можно обратиться к опыту Скалы. В ней можно объявлять конструкторы прямо в синтаксисе объявления классов (синтаксис псевдошарпа):
class C(int firstField, string secondField)
{
}
...
var c = C(42, "wow");
Console.WriteLine(c.firstField);


Здесь firstField и secondField это одновременно и поля класса С и параметры его единственного конструктора. Прибавляем сюда наследование и получаем все что нужно для классических конструкторных паттернов. Для старых типов можно использовать аннотацию задаваемую кастом-атрибутами.

В общем, если у них проблемы с дизайном, могу за скромную сумму (ну, скажем 10К зеленых) спроектировать поддержку ПМ для шарпа, что называется под ключ (с грамматикой и описанием семантики).
IT
IT
23.02.2013 10:28
Здравствуйте, VladD2, Вы писали:

VD>В общем, если у них проблемы с дизайном, могу за скромную сумму (ну, скажем 10К зеленых) спроектировать поддержку ПМ для шарпа, что называется под ключ (с грамматикой и описанием семантики).


Могу за 20K в аналогичной валюте сделать ревью дизайна Влада. Если оно окажется типа "Всё OK", то всё равно бабки вперёд.
VladD2
VladD2
23.02.2013 11:40
Здравствуйте, IT, Вы писали:

IT>Могу за 20K в аналогичной валюте сделать ревью дизайна Влада. Если оно окажется типа "Всё OK", то всё равно бабки вперёд.


Я не против. Все равно по сравнению с их затратами это демпинговые цены. Они же фичу рожают по два года и коллективно.
Sinclair
Sinclair
28.02.2013 04:15
Здравствуйте, VladD2, Вы писали:

IT>>Могу за 20K в аналогичной валюте сделать ревью дизайна Влада. Если оно окажется типа "Всё OK", то всё равно бабки вперёд.

VD>Я не против. Все равно по сравнению с их затратами это демпинговые цены. Они же фичу рожают по два года и коллективно.
Работая в продуктовой конторе, могу вас, пацаны, разочаровать. В нужную работу, помимо проектирования и review, входит также мейнтенанс на пять лет вперёд (т.е. участие в дизайне всех будущих фич с учётом наличия этой существующей) и саппорт на десять лет вперёд (то есть помощь несчастным хомячкам, выстрелившим себе в ногу при помощи вашей фичи).
Стоимостью реализации при таких раскладах можно смело пренебречь. А запрошенные вами 30к на двоих эти две активности сожрут уже к концу 2014. Дальше вы будете работать себе в убыток.

А если вы откажетесь от этих "обременений" — то Редмонд ваше предложение никак не заинтересует. У них и своих проектировщиков хватает; с учётом ихних зарплат, проект+ревью им обойдётся тыщи в четыре, от силы в пять.
VladD2
VladD2
28.02.2013 04:40
Здравствуйте, Sinclair, Вы писали:

S>Работая в продуктовой конторе, могу вас, пацаны, разочаровать. В нужную работу, помимо проектирования и review, входит также мейнтенанс на пять лет вперёд


Ты видимо кем-то не тем работаешь. Любой работник отдела кадров и директор знает, что есть разные специалисты отвечающие за разные задачи. По идее не нужно быть курицей чтобы понимать толк в яичнице, но чем черт не шутит?
IT
IT
28.02.2013 10:47
Здравствуйте, Sinclair, Вы писали:

S>А если вы откажетесь от этих "обременений" — то Редмонд ваше предложение никак не заинтересует. У них и своих проектировщиков хватает; с учётом ихних зарплат, проект+ревью им обойдётся тыщи в четыре, от силы в пять.


Убедил. Я отказываюсь от своего предложения.
Ikemefula
Ikemefula
03.03.2013 06:27
Здравствуйте, Sinclair, Вы писали:

существующей) и саппорт на десять лет вперёд (то есть помощь несчастным хомячкам, выстрелившим себе в ногу при помощи вашей фичи).
S>Стоимостью реализации при таких раскладах можно смело пренебречь. А запрошенные вами 30к на двоих эти две активности сожрут уже к концу 2014. Дальше вы будете работать себе в убыток.

Скорее к концу 2013.
Jack128
Jack128
19.02.2013 06:47
Здравствуйте, AndrewVK, Вы писали:

если из мелких фич, то
1) сплайс строк

var i = 10;
$"Int = $i";



2) чуть по продвинутей вывод дженерик аргументов


TResult Method<TArg, TResult>(TArg arg)  { return default(TResult); }
...
var res = Method<, string>(10); // TArg выведется.



var list = new List<>{10};




А если покупнее, то ПМ
Jack128
Jack128
19.02.2013 06:56
Здравствуйте, Jack128, Вы писали:

А, и еще не знаю насколько это "крупно", но очень хочется возможность комбинирования expression-trees


Expression<Func<int?, string>> ToStr = i => i.HasValue ? i.ToString() : "null";
var q = db.MyTables.Select(rec => rec.StrField + ToStr(rec.IntField));



если не ошибаюсь в F# есть такая фича.
k0st1x
k0st1x
19.02.2013 06:48
- Expression Substitution вместо string.Format
var x = 5;
Console.WriteLine("x = #{x}"));


— extension метод .ForEach для IEnumerable
— просто ради красоты — возможность писать код без ";" в конце каждой строчки : )

и, как уже указал "IT" в http://www.rsdn.ru/forum/dotnet/5074746.1
— Вывод типов при вызове констркуторов
Mihas
Mihas
20.02.2013 05:32
Здравствуйте, k0st1x, Вы писали:

K> — просто ради красоты — возможность писать код без ";" в конце каждой строчки : )

Тогда придется спилить безымянный палец. Чтоб не стучал по клавише ;
k0st1x
k0st1x
20.02.2013 05:47
Здравствуйте, Mihas, Вы писали:

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


K>> — просто ради красоты — возможность писать код без ";" в конце каждой строчки : )

M>Тогда придется спилить безымянный палец. Чтоб не стучал по клавише ;

как временное решение или workaround,
можно примотать мизинец к безымянному пальцу, ну или приклееть суперклеем.
Qbit86
Qbit86
20.02.2013 07:42
Здравствуйте, k0st1x, Вы писали:

M>>Тогда придется спилить безымянный палец. Чтоб не стучал по клавише ;

K>как временное решение или workaround,
K>можно примотать мизинец к безымянному пальцу, ну или приклееть суперклеем.

Я использовал более радикальный вариант: ездил на велосипеде по городу без гарда на руле. В итоге на три недели мизинец пригипсовали к безымянному.
Санёк81
Санёк81
21.02.2013 10:00
Здравствуйте, k0st1x, Вы писали:

K>как временное решение или workaround,

K>можно примотать мизинец к безымянному пальцу, ну или приклееть суперклеем.

Пиши на VB
k0st1x
k0st1x
22.02.2013 06:05
Здравствуйте, Санёк81, Вы писали:

Сё>Здравствуйте, k0st1x, Вы писали:


K>>как временное решение или workaround,

K>>можно примотать мизинец к безымянному пальцу, ну или приклееть суперклеем.

Сё>Пиши на VB


прискорбно, что смена языка — единственное решение неудобства
AK85
AK85
19.02.2013 07:07
Здравствуйте, AndrewVK, Вы писали:

AVK>те фичи, которых не хватает лично вам.


r = a.?b.?c;

вместо
if (a != null && a.b != null)
    r = a.b.c;
else
    r = null;


Это кажется называется Maybe monad.
Синтаксис подсмотрен у Bart de Smet.
Jack128
Jack128
19.02.2013 07:35
Здравствуйте, AK85, Вы писали:

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


AVK>>те фичи, которых не хватает лично вам.


AK>
AK>r = a.?b.?c;
AK>

AK>вместо
AK>
AK>if (a != null && a.b != null)
AK>    r = a.b.c;
AK>else
AK>    r = null;
AK>


AK>Это кажется называется Maybe monad.

AK>Синтаксис подсмотрен у Bart de Smet.

Туда же NotNull ссылки. Но это уже CLR -(
AndrewVK
AndrewVK
20.02.2013 12:26
Здравствуйте, Jack128, Вы писали:

J>Туда же NotNull ссылки.


Боюсь, для этого нужно написать CLR с нуля
... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
neFormal
neFormal
22.02.2013 11:01
Здравствуйте, AK85, Вы писали:

AK>
AK>r = a.?b.?c;
AK>

AK>Это кажется называется Maybe monad.
AK>Синтаксис подсмотрен у Bart de Smet.

а если бы дальше первого fail-by-null не выходило, цены бы ему не было
в groovy такое было реализовано, имхо люто неудобно.
k0st1x
k0st1x
19.02.2013 07:08
было бы здорово иметь возможность писать

interface IFoobar { void DoWork(); }
...
object value;
if(value is IFoobar) {
  value.DoWork(); // не надо делать "cast" или "as"
}
Jack128
Jack128
19.02.2013 01:08
Здравствуйте, k0st1x, Вы писали:

K>было бы здорово иметь возможность писать


K>
K>interface IFoobar { void DoWork(); }
K>...
K>object value;
K>if(value is IFoobar) {
K>  value.DoWork(); // не надо делать "cast" или "as"
K>}
K>


Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.


interface IMyIntf 
{
    void IntfMethod();
}
class MyClass: IMyIntf
{
   public void ClassMethod() {}
   void IMyIntf.IntfMethod() {}
}


IMyIntf o = ...;
if (o is MyClass)
{
    o.IntfMethod(); // сейчас работает, а если o скастится к MyClass, то перестанет компилиться.
}
k0st1x
k0st1x
19.02.2013 01:19
Здравствуйте, Jack128, Вы писали:

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


K>>было бы здорово иметь возможность писать


K>>
K>>interface IFoobar { void DoWork(); }
K>>...
K>>object value;
K>>if(value is IFoobar) {
K>>  value.DoWork(); // не надо делать "cast" или "as"
K>>}
K>>


J>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.


вообще, идею увидел в проекте Kotlin.
jetbrains как-то живет с такой фичей
k0st1x
k0st1x
19.02.2013 01:21
Здравствуйте, k0st1x, Вы писали:

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


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


K>>>было бы здорово иметь возможность писать


K>>>
K>>>interface IFoobar { void DoWork(); }
K>>>...
K>>>object value;
K>>>if(value is IFoobar) {
K>>>  value.DoWork(); // не надо делать "cast" или "as"
K>>>}
K>>>


J>>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.


K>вообще, идею увидел в проекте Kotlin.

K>jetbrains как-то живет с такой фичей

кстати, здесь описание этой фичи
до этой минуты даже не догадывался, что это называется "Pattern matching" )
hardcase
hardcase
19.02.2013 01:26
Здравствуйте, k0st1x, Вы писали:

K>вообще, идею увидел в проекте Kotlin.

K>jetbrains как-то живет с такой фичей

У Kotlin проблема обратной совместимости ещё не стоит, и до первого официального релиза можно синтаксисом крутить и вертеть как угодно.
VladD2
VladD2
19.02.2013 04:19
Здравствуйте, k0st1x, Вы писали:

K>вообще, идею увидел в проекте Kotlin.

K>jetbrains как-то живет с такой фичей

Там язык с нуля проектировался и другого поведения нет. Кроме того там оно не для всех случаев работает, вроде как. Потому как для изменяемых переменных поведение будет кривым.
k0st1x
k0st1x
19.02.2013 08:21
Здравствуйте, Jack128, Вы писали:

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


K>>было бы здорово иметь возможность писать


K>>
K>>interface IFoobar { void DoWork(); }
K>>...
K>>object value;
K>>if(value is IFoobar) {
K>>  value.DoWork(); // не надо делать "cast" или "as"
K>>}
K>>


J>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.



я тут подумал и не смог придумать, какой сценарий поломает обратную совместимость?
Jack128
Jack128
19.02.2013 08:44
Здравствуйте, k0st1x, Вы писали:

J>>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.



K>я тут подумал и не смог придумать, какой сценарий поломает обратную совместимость?


а тебе придумывать не нужно, я уже придумал. И даже написал этот пример, но ты при цитировании почему то удалил его.
Ziaw
Ziaw
20.02.2013 01:36
Здравствуйте, Jack128, Вы писали:

J>а тебе придумывать не нужно, я уже придумал. И даже написал этот пример, но ты при цитировании почему то удалил его.


В принципе это решаемо эвристиками в компиляторе. Так что если очень хочется, то можно.
k0st1x
k0st1x
20.02.2013 05:49
Здравствуйте, Jack128, Вы писали:

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


J>>>Уже существующим синтаксисом не обойтись, нужно новый придумывать, иначе такая фича поломает обратную совместимость.



K>>я тут подумал и не смог придумать, какой сценарий поломает обратную совместимость?


J>а тебе придумывать не нужно, я уже придумал. И даже написал этот пример, но ты при цитировании почему то удалил его.


извиняюсь, действительно упустил.
btw, проверил этот сценарий в котлине — он ругается и не дает скомпилить.
VladD2
VladD2
23.02.2013 08:26
Здравствуйте, k0st1x, Вы писали:

K>извиняюсь, действительно упустил.

K>btw, проверил этот сценарий в котлине — он ругается и не дает скомпилить.

В котлике есть неизменяемые локальные переменные. Для них этот прокатывает. Хотя, все равно дизайн спорный выходит. В немерле можно использовать стандартный ПМ:
when (x is Y as y)
{
  ...
}

"y" имеет тип "Y" и является неизменяемой переменной. В "x" по прежнему можно присваивать новое значение (если она изменяемая) и тип у него прежний.
k0st1x
k0st1x
19.02.2013 07:13
Здравствуйте, AndrewVK

еще вот на ходу вспоминаю, чего не хватает
— default value для auto property

: )
AlexRK
AlexRK
19.02.2013 07:48
Здравствуйте, AndrewVK, Вы писали:

1. Not null ссылки, желательно по умолчанию.
2. Алгебраические типы данных.
3. Паттерн-матчинг — в том числе по обычным типам.
xorets
xorets
19.02.2013 07:50
Мне кажется, полезна будет возможность использовать initializer block после любого выражения, возвращающего объект, а не только после операции new. Это особенно полезно при использовании DI-контейнеров, которые, вроде как, логически замещают new, но полного синтаксиса не предоставляют.

Например, так:

var o = container.Resolve<MyObject>() 
   {
      Field1 = 7,
      Field2 = "hello world"
   };
_FRED_
_FRED_
19.02.2013 01:33
Здравствуйте, AndrewVK, Вы писали:

Порядок значения не имеет, что вспомнилось.

  • Уточнение типа не хватает. Сейчас:
    // Тип переменной - массив, а хотелось бы иметь IList<int> или даже IReadOnlyCollection<int>.
    var list1 = new int[] { 0, };
    
    // Явное указание типа переменной - выход, но смотрится не симпатично когда кругом (выше и ниже по коду) var-ы,
    // а так же не возможно в выражении let внутри query
    IList<int> list2 = new int[] { 0, };
    
    // Приведение типа не выглядит как безопасная операция.
    // Внимание при чтении концентрируется на типе, а не на выражении, которое важнее.
    var list3 = (IList<int>)new int[] { 0, };


    С уточнением типов:
    var list = new int[] { 0, } : IList<int>;
    var predicate = item => item > 3 : Func<int, bool>; // Можно ещё и так использовать, да.


  • Как уже скзали, расширение query для возможности естественного вызова Aggregate/Skip/etc (например как в VB) + поддержка пользовательских расширений.
    Например сейчас:
    var temp =
      from item in collection
      where item.Some > 3
      select item;
    var x1 = new MyCollection<X>(temp, someAdditionalParameter: 42);
    var x2 = temp.ToMyDictionary(item => item.Key, item => item.Data);
    var x3 = temp.Percentile(0.95);


    Хотелось бы:
    // Вызов конструктора
    var x1 =
      from item in collection
      where item.Some > 3
      select item into temp as new MyCollection<X>(temp, someAdditionalParameter: 42);
    
    // Просто вызов некоего метода
    var x2 =
      from item in collection
      where item.Some > 3
      select item into temp as MyExtensions.ToMyDictionary(temp, item => item.Key, item => item.Data);
    
    // Вызов метода-расширения
    var x3 =
      from item in collection
      where item.Some > 3
      select item into temp as temp.Percentile(0.95);

    Тип переменной "х" — это тип выражения после "as". Так же получится удобное использование First[OrDefault] и т.п. если не придумают, как эти методы более естественно внедрить в query.

  • Так же реквестую nameof/infoof и "ПМ и АТД"

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

  • Лямбда и моджификаторы параметра (ref/out)
    private delegate bool TryParse<T>(string text, out T result);
    // Так можно
    TryParse<int> parse1 = (string text, out int result) => Int32.TryParse(text, out result);
    // А хотелось бы и так
    TryParse<int> parse2 = (text, out result) => Int32.TryParse(text, out result);


  • Полная поддержка компилятором Expression, в ветвлениями и прочим. Поддержка в выражениях подстановок. Хотя бы так:
    Expression<Func<int, int>> temp = value => value + 10;
    Expression<Func<int, int>> lambda = value => {
      if(value % 2 == 0) {
        return 10;
      } else if(value < 100) {
        return 20;
      } else {
        return #temp(value); // тут компилятор встраивает под-дерево temp.
      }//if
    };


  • using-директива c открытыми дженерик-типами:
    using MyMap<TKey, TValue> = IDictionary<TKey, IList<TValue>>;

    а так же using-директива внутри класса (для использования там объявленных в классе дженерик-типов).

  • Контракты на декларативном уровне а-ля Spec# http://research.microsoft.com/en-us/projects/specsharp/
  • _FRED_
    _FRED_
    19.02.2013 01:35
    Здравствуйте, _FRED_, Вы писали:

    _FR>Порядок значения не имеет, что вспомнилось.


    Да, за оператор .? тоже громко реквестую.
    koodeer
    koodeer
    19.02.2013 01:41
    Здравствуйте, AndrewVK.

    Хотелось бы иметь ограничение дженериков как простых типов, чтобы можно было реализовывать быстрые вычисления.
    Что-то вроде:

    T Calc<T>(T a, T b) where T : simple // позразумеваются int, byte, double, etc
    {
        T result = a + b; // разрешено использовать + - * /
    
        return result;
    }


    Но это нужна доработка CLR.
    AndrewVK
    AndrewVK
    20.02.2013 12:26
    Здравствуйте, koodeer, Вы писали:

    K>Хотелось бы иметь ограничение дженериков как простых типов, чтобы можно было реализовывать быстрые вычисления.


    Это уже несколько лет как одна из самых востребованных фич к рантайму, и про это команде CLR известно, но пока ничего конкретного нет.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    Andir
    Andir
    07.04.2013 07:47
    Здравствуйте, koodeer, Вы писали:

    K>Хотелось бы иметь ограничение дженериков как простых типов, чтобы можно было реализовывать быстрые вычисления.

    В эту же кучу ограничение дженериков на параметризованный конструктор типа.

    --
    С Уважением, Andir!
    using(<< RSDN@Home 1.2.0 alpha 5 rev. 67>>) { /* Работаем */ }
    Ilya81
    Ilya81
    08.04.2013 02:00
    Здравствуйте, Andir, Вы писали:

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


    K>>Хотелось бы иметь ограничение дженериков как простых типов, чтобы можно было реализовывать быстрые вычисления.

    A>В эту же кучу ограничение дженериков на параметризованный конструктор типа.

    A>--

    A>С Уважением, Andir!
    Вот это точно! А ещё ограничение на отсутсвие управляемых указателей, чтоб можно было писать
    T* pT1= (T*)Marshal.AllocHGlobal(n*Marshal.SizeOf(typeof(T)));



    А самое желательное, то что вообще-то есть, но не в пользовательской версии, а в Singularity — восклицательные знаки для запрета пустых указателей.
    ionoy
    ionoy
    19.02.2013 03:19
    Здравствуйте, AndrewVK, Вы писали:

    1. АТД и ПМ
    2. Довести поддержку локальных функций до уровня Немерле
    3. Туплы, встроенные в язык
    agat50
    agat50
    19.02.2013 03:50
    Мнение ламера. Как мейнстримовый язык шарп почти идеален, Roslyn видимо позволит фишек по части синтаксиса добавить. А вот по части кроссплатформенности\оперсорса джавe проигрывает конечно. На много серверов винду не поставишь увы, и под себя не перепишешь то, что не особенно нравится\баг пофиксить быстро. И имхо, для этого нужно более активное участие самой Microsoft. За код спасибо, но WPF, например, могли сделать не на directx, а на том же opengl, и всё стало бы чуть проще по части GUI. Ну и вообще какой-то бред, когда в Mono приходится переписывать то, что уже написано в MS.
    Aлeкceй
    Aлeкceй
    19.02.2013 04:00
    Здравствуйте, agat50, Вы писали:

    A>Мнение ламера. Как мейнстримовый язык шарп почти идеален, Roslyn видимо позволит фишек по части синтаксиса добавить. А вот по части кроссплатформенности\оперсорса джавe проигрывает конечно. На много серверов винду не поставишь увы, и под себя не перепишешь то, что не особенно нравится\баг пофиксить быстро. И имхо, для этого нужно более активное участие самой Microsoft. За код спасибо, но WPF, например, могли сделать не на directx, а на том же opengl, и всё стало бы чуть проще по части GUI. Ну и вообще какой-то бред, когда в Mono приходится переписывать то, что уже написано в MS.


    А что мешает моно на сервер поставить?

    А по теме: ПМ, АТД, кортежи, встроенные в язык и индексаторы в foreach.
    agat50
    agat50
    19.02.2013 05:11
    Здравствуйте, Aлeкceй, Вы писали:

    A>А что мешает моно на сервер поставить?


    Мешает то, что банальнейшая прога на winforms .net4.0 c mysql коннектором (который специально под mono) на убунте с 2.10.8.1 вылетает при запуске с замечательной ошибкой " Could not load file or assembly 'MySql.Data, Version=6.5.5.0, ...", которая валяется в той же папке. И какая тут "Yes, Mono is binary compatible with Windows."? Не тянет писать под Mono с его приколами, а не под .net как единую платформу аля java. В принципе всё решаемо, опять-таки java либы через ikvm можно на крайний случай для кроссплатформенности использовать. MS мог бы выпустить CLR под линукс, мб и с покоцанным функционалом типа wpf, хоть серваки гонять, но чтобы работало всё так же как на винде.
    alexanderfedin
    alexanderfedin
    03.03.2013 10:07
    Здравствуйте, agat50, Вы писали:

    A>Здравствуйте, Aлeкceй, Вы писали:


    A>>А что мешает моно на сервер поставить?


    A>Мешает то, что банальнейшая прога на winforms .net4.0 c mysql коннектором (который специально под mono) на убунте с 2.10.8.1 вылетает при запуске с замечательной ошибкой " Could not load file or assembly 'MySql.Data, Version=6.5.5.0, ...", которая валяется в той же папке. И какая тут "Yes, Mono is binary compatible with Windows."? Не тянет писать под Mono с его приколами, а не под .net как единую платформу аля java. В принципе всё решаемо, опять-таки java либы через ikvm можно на крайний случай для кроссплатформенности использовать. MS мог бы выпустить CLR под линукс, мб и с покоцанным функционалом типа wpf, хоть серваки гонять, но чтобы работало всё так же как на винде.

    Зачем Майкрософту рубить сук, на котором он сидит?
    Компания зарабатывает деньги не на продаже .NET, а на продаже операционной системы Windows. .NET — это средство для облегчения создания программ под Windows сторонним производителям, а не способ облегчить перенос этих программ на другие платформы.
    Именно поэтому компания поддерживает платформу Mono ровно настолько, чтобы её не обвинили в монополизме, и ни на грамм больше.
    agat50
    agat50
    03.03.2013 10:55
    Здравствуйте, alexanderfedin, Вы писали:

    A>Зачем Майкрософту рубить сук, на котором он сидит?

    A>Компания зарабатывает деньги не на продаже .NET, а на продаже операционной системы Windows. .NET — это средство для облегчения создания программ под Windows сторонним производителям, а не способ облегчить перенос этих программ на другие платформы.
    A>Именно поэтому компания поддерживает платформу Mono ровно настолько, чтобы её не обвинили в монополизме, и ни на грамм больше.

    Спасибо кэп, открыли глаза Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды. Как отдельный продукт. Ну естественно по другим ценам, но по 10 баксов за лицензию бессрочную на систему можно было бы за него платить. Ну а с виндой вроде как бесплатно бы шёл. Как это сделать вопрос второй. В принципе да, особых надежд не питаю. Если бы было бесплатно, то это скорее уже была бы java с её недостатками из-за отсутствия централизации.
    AndrewVK
    AndrewVK
    04.03.2013 12:10
    Здравствуйте, agat50, Вы писали:

    A>Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды.


    На фоне бесплатной джавы?
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    agat50
    agat50
    04.03.2013 12:17
    Здравствуйте, AndrewVK, Вы писали:

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


    A>>Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды.


    AVK>На фоне бесплатной джавы?


    Ну винда же продаётся на фоне бесплатной убунты. Мне, например, шарп нравится весьма как язык, почему бы и не платить. Естественно, если это будет удобно осуществимо.
    Евгений Акиньшин
    Здравствуйте, AndrewVK, Вы писали:

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


    A>>Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды.


    AVK>На фоне бесплатной джавы?


    Ксамарин для Андроида продается на фоне бесплатной явы.
    alexanderfedin
    alexanderfedin
    15.03.2013 08:28
    Здравствуйте, agat50, Вы писали:

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


    A>>Зачем Майкрософту рубить сук, на котором он сидит?

    A>>Компания зарабатывает деньги не на продаже .NET, а на продаже операционной системы Windows. .NET — это средство для облегчения создания программ под Windows сторонним производителям, а не способ облегчить перенос этих программ на другие платформы.
    A>>Именно поэтому компания поддерживает платформу Mono ровно настолько, чтобы её не обвинили в монополизме, и ни на грамм больше.

    A>Спасибо кэп, открыли глаза Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды. Как отдельный продукт. Ну естественно по другим ценам, но по 10 баксов за лицензию бессрочную на систему можно было бы за него платить. Ну а с виндой вроде как бесплатно бы шёл. Как это сделать вопрос второй. В принципе да, особых надежд не питаю. Если бы было бесплатно, то это скорее уже была бы java с её недостатками из-за отсутствия централизации.

    Видимо, открыл не до конца
    Windows & Office — это две cash cows компании. Наибольший доход от их продажи компания получает не из розничных продаж, а от всяких DELL/HP/ACER/etc., которые предустанавливают этих дойных коров на продаваемые компы.
    Отношение количества девелоперов в мире к количеству остальных юзеров, я думаю, даже не в сотни раз. Поэтому предустанавливать Visual Studio или даже .NET SDK на все компы смысла ноль — затраты не отобъёшь.
    Если компания сделает средство разработки многоплатформенным среди не своих платформ, то тем самым она своими собственными руками выпилит сук, на которых сидит — заложит основу для перевода пользователей на нругие платформы. И вот представьте: за средство разработки денег больших не поднять, а платформа больше не приносит того огромного бабла. А виноват в этом тот, кто решил "дать людЯм свободу, равенство и братство" в выборе платформы для разработки.
    agat50
    agat50
    16.03.2013 10:27
    Здравствуйте, alexanderfedin, Вы писали:

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


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


    A>>>Зачем Майкрософту рубить сук, на котором он сидит?

    A>>>Компания зарабатывает деньги не на продаже .NET, а на продаже операционной системы Windows. .NET — это средство для облегчения создания программ под Windows сторонним производителям, а не способ облегчить перенос этих программ на другие платформы.
    A>>>Именно поэтому компания поддерживает платформу Mono ровно настолько, чтобы её не обвинили в монополизме, и ни на грамм больше.

    A>>Спасибо кэп, открыли глаза Момент в том, что dotnet и C# как пророк его возможно мог бы продаваться "лучше" винды. Как отдельный продукт. Ну естественно по другим ценам, но по 10 баксов за лицензию бессрочную на систему можно было бы за него платить. Ну а с виндой вроде как бесплатно бы шёл. Как это сделать вопрос второй. В принципе да, особых надежд не питаю. Если бы было бесплатно, то это скорее уже была бы java с её недостатками из-за отсутствия централизации.

    A>Видимо, открыл не до конца
    A>Windows & Office — это две cash cows компании. Наибольший доход от их продажи компания получает не из розничных продаж, а от всяких DELL/HP/ACER/etc., которые предустанавливают этих дойных коров на продаваемые компы.
    A>Отношение количества девелоперов в мире к количеству остальных юзеров, я думаю, даже не в сотни раз. Поэтому предустанавливать Visual Studio или даже .NET SDK на все компы смысла ноль — затраты не отобъёшь.
    A>Если компания сделает средство разработки многоплатформенным среди не своих платформ, то тем самым она своими собственными руками выпилит сук, на которых сидит — заложит основу для перевода пользователей на нругие платформы. И вот представьте: за средство разработки денег больших не поднять, а платформа больше не приносит того огромного бабла. А виноват в этом тот, кто решил "дать людЯм свободу, равенство и братство" в выборе платформы для разработки.

    http://pics.livejournal.com/spydell/pic/00275585/s640x480
    Намёк понятен?

    Причём тут средство разработки, я не предлагаю сделать студию портируемой, только CLR с классами. Как и sql server, axapta, directx и т.п. Пусть они останутся привязаны к винде, нет вопросов. Но имхо dotnet весьма страдает как серверная платформа из-за ограничений этих, ну не могу я на 5 виртуалок винду лицензии поставить. Не говоря про отсутствие лёгких дистрибутивов винды типа ubuntu server. Вообще забейте, надо будет, с моно разберусь конечно.
    matumba
    matumba
    05.04.2013 08:44
    Здравствуйте, alexanderfedin, Вы писали:

    A>Если компания сделает средство разработки многоплатформенным среди не своих платформ, то тем самым она своими собственными руками выпилит сук, на которых сидит


    Не совсем всё так однозначно. Сейчас вот что мы имеем? Сидит какой-нть прыщавый виндо-хэйтер и решает — и винда вроде нужна, и сишарпить под ней можно, но внутренний кретин голос говорит — "а мы уйдём на север!". Причём полностью уйдём — на линупс+пестон, например. И получается, что вместо придержания "многоплатформенного" хэйтера, который мог бы делать софт ДЛЯ ОБЕИХ платформ, мелкософт ПОЛНОСТЬЮ теряет отдельного специалиста!
    Когда выбор "или-или" — теряют все. Просто дебилам в руководстве проще изображать из себя властелина платформы, чем думать мозгами и грести бабло экскаваторами. А с планшетно-мобильной волной вообще вымывает все стойки под виндоофисом: если раньше выбор был "мак или вынь" (причём сильно в пользу последней), то сейчас уже задумываются "а нужен ли мне десктопный виндовоз вообще?".
    gravatar
    Аноним
    19.02.2013 04:13
    Сделайте union наконец (хотя бы для ссылочных типов)
    Я думаю, что это могло бы быть С# 1.0, но до сих пор почему-то нет...
    Aлeкceй
    Aлeкceй
    19.02.2013 04:14
    Здравствуйте, Аноним, Вы писали:

    А>Сделайте union наконец (хотя бы для ссылочных типов)

    А>Я думаю, что это могло бы быть С# 1.0, но до сих пор почему-то нет...

    Зачем?
    Ziaw
    Ziaw
    19.02.2013 05:12
    Здравствуйте, Аноним, Вы писали:

    А>Сделайте union наконец (хотя бы для ссылочных типов)

    А>Я думаю, что это могло бы быть С# 1.0, но до сих пор почему-то нет...

    FieldOffsetAttribute доступен с первого фреймворка.
    VladD2
    VladD2
    28.02.2013 03:04
    Здравствуйте, Ziaw, Вы писали:

    Z>FieldOffsetAttribute доступен с первого фреймворка.


    Попробуй, ради хохмы, таким образом совместить ссылочный тип и какой-нибудь long. Узнаешь много нового.
    Ziaw
    Ziaw
    01.03.2013 02:44
    Здравствуйте, VladD2, Вы писали:

    VD>Попробуй, ради хохмы, таким образом совместить ссылочный тип и какой-нибудь long. Узнаешь много нового.


    А какой в этом смысл в мире управляемых указателей?
    VladD2
    VladD2
    01.03.2013 04:40
    Здравствуйте, Ziaw, Вы писали:

    VD>>Попробуй, ради хохмы, таким образом совместить ссылочный тип и какой-нибудь long. Узнаешь много нового.


    Z>А какой в этом смысл в мире управляемых указателей?


    Смысл может быть любой. Он задачей определяется. Это же просто объединение двух величин. Например, строки и целого. А вот работать не будет, так как CLR не позволяет совместить указатель и значение. GC тупо упадет.
    Flammable
    Flammable
    01.03.2013 05:23
    Здравствуйте, VladD2, Вы писали:
    VD>А вот работать не будет, так как CLR не позволяет совместить указатель и значение. GC тупо упадет.
    Указатель и значение CLR позволяет "совместить". Не допускается перекрытие типов-ссылок с типами-значениями.
    Ziaw
    Ziaw
    02.03.2013 07:13
    Здравствуйте, VladD2, Вы писали:

    VD>Смысл может быть любой. Он задачей определяется. Это же просто объединение двух величин. Например, строки и целого. А вот работать не будет, так как CLR не позволяет совместить указатель и значение. GC тупо упадет.


    Ты про то, что GC следит за всеми указателями и падает если испортить один из них? Есть такая проблема, да, нельзя смешать value и cсылку. Два значения смешать нет проблем, а две ссылки смешивать нет смысла (можно просто хранить один object).
    WolfHound
    WolfHound
    13.03.2013 01:01
    Здравствуйте, Ziaw, Вы писали:

    Z>Ты про то, что GC следит за всеми указателями и падает если испортить один из них? Есть такая проблема, да, нельзя смешать value и cсылку. Два значения смешать нет проблем, а две ссылки смешивать нет смысла (можно просто хранить один object).

    Такая проблема есть в реализации .НЕТного ГЦ, а не ГЦ вообще.
    Ибо ни что не мешает сделать ГЦ, который понимает, в каком состоянии находится объединение.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
    matumba
    matumba
    19.02.2013 05:50
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Сейчас сложилась такая ситуация, что для следующего релиза C# нет big thing


    Их не было и в 5 релизе — ну не async же — революция программазма!

    AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.


    Забавно — т.е. к народу обращаются только когда ИМ нужно? Я думал, MS просто завален предложениями на десятилетие вперёд! И предложения совсем не обязательно должны быть big thing — даже элементарные вещи могут делать жизнь прогера намного легче. Ладно, раз уж дали высказаться, нате вам:

    1. Авто-инициализация авто-проперти:
      int a {get;set;} = 7;
      Это мелочи, но без них ШАРП БЕСИТ!
    2. Автопроперть тоже сократить до: prop int a; // паблик проперть для r/w; куча приложений идёт именно с таким дефолтом, почему б его не сократить? Заодно ускорится компиляция.
    3. Мультиприсвоение: var (a, b) = GetCoords(); // в a и b попадают отдельные числа. Т.е. типа кортежа, но без кортежа. Перл это умеет на раз-два. Сишарп ждём уже 10 лет....
    4. Ещё один вид мультистрочных каментов (а-ля D): /+ это отладочный коммент /* скрывающий рабочий коммент */ и нужный только временно +/
    5. Раз уж строки являются "немного встроенным" и широко используемым типом, нельзя ли упростить дебилизм типа if (!string.IsNullOrWhiteSpace(бла-бла...)) на что-то типа if (^string_var) — это сократило бы целую кучу кода.
    6. Вывод типов для филдов: var SomeField = 6; // знаю, есть проблемы, но они трясут в 0.000001% случаев — так не лучше ли сделать жизнь большинства легче?!
    7. Если тип переменной уже известен, пересоздавать её простым способом:
      File f; ...где-то позже... f = new();
      — бенефит очевиден при использовании всяких трёхэтажных генериков.
    8. .ToString() бесит. Можно как в Руби: obj.ToS ? (заметьте — без скобок)
    9. Синонимы функций. Console.WriteLine задолбал — хочу типа так:
      using Out = Console.WriteLine; Out(bzbz);

    10. Зачем в switch(SomeEnumVar) пишут в case SomeDamnBigEnumName.EnumValue: ? нельзя ли просто switch(SomeEnumVar) case EnumValue: — тип-то везде один и тот же!
    11. Приведение типов неуклюжее. Вместо
      double z = (double)IntVar;
      можно было б писать
      double z := IntVar;
      , т.е. := — это "присвоить с приведением типа к lvalue". Словесный понос надо искоренять — пусть паскалисты его тыркают.

    Фичи из голосовалки, к которым +100:
    • Сиськи!
    • Expression Substitution вместо string.Format
    • Синтаксис для кортежей с поддержкой везде: foreach(var (x, y) in seq)

    Хочется, чтобы офигевшие от своей крутости шарподелы спустились на землю и не выпежонивались "суперфичами", а слушали тех, кто РЕАЛЬНО использует шарп — это МЫ ежедневно колдыбасимся с их компилером и это нам виднее, что есть "мелочи". А если ради мелочей надо переписывать компилер, то.... в топку такие компилеры.
    Jack128
    Jack128
    19.02.2013 06:44
    Здравствуйте, matumba, Вы писали:

    M>*Раз уж строки являются "немного встроенным" и широко используемым типом, нельзя ли упростить дебилизм типа if (!string.IsNullOrWhiteSpace(бла-бла...)) на что-то типа if (^string_var) — это сократило бы целую кучу кода.

    ну сделай экстеншн метод if (string_var.A) и кол-ву символов, и по читабельности примерно одинаково.

    M>*Приведение типов неуклюжее. Вместо
    double z = (double)IntVar;
    можно было б писать
    double z := IntVar;
    , т.е. := — это "присвоить с приведением типа к lvalue". Словесный понос надо искоренять — пусть паскалисты его тыркают.

    чем те var z = (double)IntVar не устраивает?
    matumba
    matumba
    19.02.2013 07:01
    Здравствуйте, Jack128, Вы писали:

    J>чем те var z = (double)IntVar не устраивает?


    Тем, что это абсолютно левый пример. Я хочу избавиться от _приведения_типа_, а не замены double на var.
    Jack128
    Jack128
    19.02.2013 07:08
    Здравствуйте, matumba, Вы писали:

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


    J>>чем те var z = (double)IntVar не устраивает?


    M>Я хочу избавиться от _приведения_типа_, а не замены double на var.

    нет, ты предлагаешь заменить один синтаксис приведения другим.
    AndrewVK
    AndrewVK
    20.02.2013 12:26
    Здравствуйте, matumba, Вы писали:

    AVK>>Сейчас сложилась такая ситуация, что для следующего релиза C# нет big thing

    M>Их не было и в 5 релизе — ну не async же — революция программазма!

    Под революциями я имел в виду масштабные изменения конкретно в C#, а не новые открытия в computer science.

    AVK>>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.


    M>Забавно — т.е. к народу обращаются только когда ИМ нужно?


    Здесь к народу обращаюсь я, и я в МС не работаю, не переживай.

    M>Хочется, чтобы офигевшие от своей крутости шарподелы спустились на землю и не выпежонивались "суперфичами", а слушали тех, кто РЕАЛЬНО использует шарп — это МЫ ежедневно колдыбасимся с их компилером и это нам виднее, что есть "мелочи". А если ради мелочей надо переписывать компилер, то.... в топку такие компилеры.


    Ты продолжай в таком тоне общаться, и тебя вообще никто слушать не будет.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    matumba
    matumba
    20.02.2013 08:38
    Здравствуйте, AndrewVK, Вы писали:

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


    Извиняюсь, поторопился. Как в анеке: "Да пошла она со своей солью!". Просто язык как был низкоуровневой "си-подобной" фигнёй, так за 10 лет и не вырос. И главное, разрабы думают о каких-то "киллер-фичах", хотя у языка хватает и "обычных" улучшений — посмотри сколько в ветке собралось "мелочей". Уверен, никто их даже читать не будет — они, видите ли, не подходят для маркетоидных испражнений. Вот так яснее моё негодование?
    AndrewVK
    AndrewVK
    20.02.2013 10:32
    Здравствуйте, matumba, Вы писали:

    M>Уверен, никто их даже читать не будет


    Ты не прав. Я вчера утром про этот топик рассказал Мэдсу, и позже он говорил, что ждет когда я скомпилирую суммарный документ.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    Aлeкceй
    Aлeкceй
    21.02.2013 01:41
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Ты не прав. Я вчера утром про этот топик рассказал Мэдсу, и позже он говорил, что ждет когда я скомпилирую суммарный документ.


    Вообще есть шанс, что хоть какие-нибудь наши хотелки реализуют?
    AndrewVK
    AndrewVK
    21.02.2013 04:24
    Здравствуйте, Aлeкceй, Вы писали:

    A>Вообще есть шанс, что хоть какие-нибудь наши хотелки реализуют?


    Шанс есть. А вот какой — этого я сказать не могу.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    alexzz
    alexzz
    21.02.2013 01:13
    Здравствуйте, matumba, Вы писали:

    M>Приведение типов неуклюжее. Вместо
    double z = (double)IntVar;
    можно было б писать
    double z := IntVar;
    , т.е. := — это "присвоить с приведением типа к lvalue". Словесный понос надо искоренять — пусть паскалисты его тыркают.



    Я не понял, почему нельзя так написать?

    double z = intVar;
    matumba
    matumba
    19.02.2013 06:49
    Пробежался по треду и собрал ещё фич, которые поддерживаю (почему-то в голосовалке — мусор вместо дельных пунктов):

    1. Упрощённая работа с атрибутами. Какой смысл рассуждать об их пользе, если работа с ними осущ. через анус? Хочется изящной простоты, типа: foreach(PropInfo pi in WindowType.class.GetProperties(Attr1, attr2, ..)); Или PropInfo.HasAttribute(AttrClass); Вообще, у C# довольно помоечный синтаксис работы с классами: вместо элегантных конструкций с именами типов приходится влезать чуть ли не в ассемблер: Класс.ДайСвойТип().ШаманскиеФункции.... отстой полнейший. Нужен синтаксис сразу на уровне "Класс", типа "Класс.ДайПропертиСАтрибутом(Атрибут)". Это мелочи, но без них код загромождается фуфлом — хорошо бы девелоперам сишарпа заботиться не только "предоставить доступ к фиче", но и о элегантности кода с этими фичами.
    2. Оператор .?
    3. Улучшить оператор AS: нечасто, но изрядно упрощает бойлерплэйт a = b as SomeType; if (a != null) ....; Вариант: when(b = a as SomeType) { юзаем b }
    4. Упрощ. иниц. объекта помимо new: var z = GetObject() <= { filed = 4, field2 = 5 }
    5. Duck typing ака MapAs: приводить объект к интерфейсу, если он совместим по методам. Уж лучше в рантайме всё **нётся, зато в коде можно очень элегантно обруливать всякое гетерогенное фуфло из разных иерархий.
    Sinclair
    Sinclair
    20.02.2013 04:23
    Здравствуйте, matumba, Вы писали:

    M>Пробежался по треду и собрал ещё фич, которые поддерживаю (почему-то в голосовалке — мусор вместо дельных пунктов):


    M>Упрощённая работа с атрибутами. Какой смысл рассуждать об их пользе, если работа с ними осущ. через анус? Хочется изящной простоты, типа: foreach(PropInfo pi in WindowType.class.GetProperties(Attr1, attr2, ..)); Или PropInfo.HasAttribute(AttrClass);


    При чём тут C#?
    public static IEnumerable<PropInfo> GetProperties<A1, A2>(this Type type) where A1: Attribute, A2: Attribute { ... }
    public static bool HasAttribute<A1>(this PropInfo pi) where A: Attribute {...};
    foreach(var pi in typeof(WindowType).GetProperties<Attr1, attr2>())
      if (pi.HasAttribute<Attr1>())
        ...


    M>Вообще, у C# довольно помоечный синтаксис работы с классами: вместо элегантных конструкций с именами типов приходится влезать чуть ли не в ассемблер: Класс.ДайСвойТип().ШаманскиеФункции.... отстой полнейший. Нужен синтаксис сразу на уровне "Класс", типа "Класс.ДайПропертиСАтрибутом(Атрибут)". Это мелочи, но без них код загромождается фуфлом — хорошо бы девелоперам сишарпа заботиться не только "предоставить доступ к фиче", но и о элегантности кода с этими фичами.

    M>Оператор .?
    M>Улучшить оператор AS: нечасто, но изрядно упрощает бойлерплэйт a = b as SomeType; if (a != null) ....; Вариант: when(b = a as SomeType) { юзаем b }
    public static void WhenIs<T>(this object o, Action<T> action) { 
      if (Typeof(T).IsAssignableFrom(o.GetType()))
        action((T)o);
    }
    a.WhenIs<SomeType>{b=>юзаем b }


    M>Упрощ. иниц. объекта помимо new: var z = GetObject() <= { filed = 4, field2 = 5 }

    Зачем?
    M>Duck typing ака MapAs: приводить объект к интерфейсу, если он совместим по методам. Уж лучше в рантайме всё **нётся, зато в коде можно очень элегантно обруливать всякое гетерогенное фуфло из разных иерархий.
    Реализовано в библиотеках — BLToolkit смотрели?
    matumba
    matumba
    20.02.2013 08:27
    Здравствуйте, Sinclair, Вы писали:

    S>При чём тут C#?


    Чуть ниже я объяснил причём:

    M>>Вообще, у C# довольно помоечный синтаксис работы с классами: вместо элегантных конструкций с именами типов приходится влезать чуть ли не в ассемблер: Класс.ДайСвойТип().ШаманскиеФункции.... отстой полнейший. Нужен синтаксис сразу на уровне "Класс", типа "Класс.ДайПропертиСАтрибутом(Атрибут)".


    Без поддержки языка это не делается в принципе.
    Путь C# будет "чуть более бейсиком" — упрощать низкоуровневый код. Сей и Сипипей мы уже наелись, пора как-то подымать уровень!

    M>>Улучшить оператор AS: нечасто, но изрядно упрощает бойлерплэйт a = b as SomeType; if (a != null) ....; Вариант: when(b = a as SomeType) { юзаем b }


    S>a.WhenIs<SomeType>{b=>юзаем b }


    Костыли не интересны ввиду своей неэлегантности. Тот же ?: тоже выражается через if'ы, тем не менее, его ввели в язык.
    И потом, можно провести анализ кода — поискать наиболее употребимые конструкции и решить как их можно упростить.

    M>>Упрощ. иниц. объекта помимо new: var z = GetObject() <= { filed = 4, field2 = 5 }

    S>Зачем?

    Можно не вводить, если реализуют паскалевский with.
    Синклер, если следовать логике Смоллтока, можно вообще оставить две вещи — присвоение и посылка сообщения. Но люди почему-то хотят иметь более "читаемый" код.

    M>>Duck typing ака MapAs: приводить объект к интерфейсу, если он совместим по методам.

    S>Реализовано в библиотеках — BLToolkit смотрели?

    эээ... Я БЛТ юзаю только для БД. Надо будет глянуть, пасип
    gravatar
    Аноним
    21.02.2013 07:59
    Здравствуйте, matumba, Вы писали:


    M>Можно не вводить, если реализуют паскалевский with.


    Паскалевский with скорее зло, чем благо. Особенно когда они вложены друг в друга.
    Реально что в паскале удобнее, чем в c#:
    1. это явное приведение типов не (Type)exp, а Type(exp)
    2. очень не хватает множеств set и операций с ними в приятном синтаксисе, а не вызове методов класса.
    Цыба
    Цыба
    21.02.2013 08:02
    Здравствуйте, Аноним, Вы писали:

    А>Паскалевский with скорее зло, чем благо. Особенно когда они вложены друг в друга.


    Как и в JavaScript, потому что к with нет явной привязки к контексту. В VB.NET, как я понимаю, привязка есть.
    aloch
    aloch
    19.02.2013 09:45
    Здравствуйте, AndrewVK, Вы писали:

    Оператор with

    with (node)
    {
       .name = "QQ";
       .index = 10;
       .DoSome();
    }



    (именно с точкой перед именем метода или свойства, как в VB)
    Философ
    Философ
    20.02.2013 05:13
    заголовочного раздела в классе.

    хотелось бы сразу после открытия файла видеть, какие public и protected методы в нём описаны.
    HowardLovekraft
    HowardLovekraft
    20.02.2013 06:09
    Здравствуйте, AndrewVK, Вы писали:

    AVK>skipped


    Добавлю свои 5 копеек:

    1) switch по всему, чему угодно, очень надоело писать костыли в виде словарей. Т.е., вместо, например, этого:

        class A
        {
            private readonly Dictionary<Type, Action> helpers;
    
            public A()
            {
                this.helpers = new Dictionary<Type, Action>
                {
                    // инициализация какими-то значениями
                };
            }
    
            public void Foo()
            {
                var type = someObject.GetType();
    
                helpers[type]();
            }
        }


    писать так:

        class A
        {
            public void Foo()
            {
                var someVar = //...
                var type = someObject.GetType();
    
                switch (type)
                {           
                    case typeof(string):
                        break;
                    case typeof(A):
                        break;
                    case someVar.GetType():
                        break;
                }
            }
        }


    Пусть это все разворачивается в тот же Dictionary, но типовым и однообразным способом.

    2) [PropertyChanging] и [PropertyChanged] для автосвойств искаропки:

            [PropertyChanging]
            [PropertyChanged]
            public int MyProperty { get; set; }


    3) Разрешить инициализатору поля ссылаться на экземплярный метод, поле или свойство, сейчас вместо этого приходиться городить конструктор:

            private readonly Lazy<string> someLazy = new Lazy<string>(SomeLazyFactory);
    
            private string SomeLazyFactory()
            {
                return string.Empty;
            }


    4) Разрешить использовать экземплярный метод, поле или свойство при вызове конструктора базового класса:

        class A 
        {
            public A(int i)
            {
            }
        }
    
        class B : A
        {
            public B()
                : base(Foo())
            {
            }
    
            private int Foo()
            {
                return 0;
            }
        }


    5) Разрешить использовать значения свойств объекта в инциализаторе этого же объекта. Вместо:

                var value = 1;
                var a = new A
                {
                    MyIntProperty = value,
                    MyStringProperty = value.ToString()
                };


    писать:

                var a = new A
                {
                    MyIntProperty = 1,
                    MyStringProperty = MyIntProperty.ToString()
                };


    Если в текущем контексте уже есть MyIntProperty, разруливать неоднозначность в пользу уже существующего идентификатора, либо считать это ошибкой.

    6) Убрать неоднозначность при явном задании размера массивов (для явно типизированных — можно, для неявно типизированных — почему-то нельзя, http://stackoverflow.com/questions/14597522/implicitly-typed-arrays-why-we-cant-set-array-size-explicitly).
    xvost
    xvost
    20.02.2013 07:50
    Здравствуйте, AndrewVK, Вы писали:

    Сецчас язык настолько опережает рантайм, что дальнейшие "мажорные" фичи — это рост колосса на глиняных ногах.
    С точки зрения людей, не знакомых с кухней MS, C# и .NET CLR — даже не муж и жена, а вообще один человек.

    Так что все силы надо пускать на CLR — многоплатформенность, нормальные оптимизации, наконец-таки нормальный x64, внятный и предсказуемый GC
    Tom
    Tom
    20.02.2013 08:19
    X>Так что все силы надо пускать на CLR — многоплатформенность, нормальные оптимизации, наконец-таки нормальный x64, внятный и предсказуемый GC
    А что не так с x64 если не секрет? Ну и чем GC не предсказуем?
    Просто интересуюсь
    xvost
    xvost
    20.02.2013 08:37
    Здравствуйте, Tom, Вы писали:

    Tom>А что не так с x64 если не секрет?


    Полное отсутствие оптимизаций

    Tom>Ну и чем GC не предсказуем?


    Тут я не могу строго сформулировать... Но общее ощущение что он "живет своей жизнью", в отличии от jvm. Ну и захлебывается на гораздо меньших объемах кучи.
    Что надо и хочется чтоб было сделано —
    1) инкрементальная фоновая сборка в gen2 БЕЗ релокации до определенного % наполнения кучи
    2) сборка в LOH с релокацией
    3) раздельные (конфигурябельно) GEN0 кучи для тредов для устраниния эффекта "кризиса среднего возраста"
    и т.д.
    k0st1x
    k0st1x
    20.02.2013 09:37
    Здравствуйте, xvost, Вы писали:

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


    Tom>>А что не так с x64 если не секрет?


    X>Полное отсутствие оптимизаций


    я не знаток во внутренних оптимизациях .net'а, но мне казалось, что TCO работает только в x64;
    чем не оптимизация?
    Tanker
    Tanker
    20.02.2013 12:08
    Здравствуйте, xvost, Вы писали:

    X> 2) сборка в LOH с релокацией


    А в 4.5 разве это не появилось ?
    AndrewVK
    AndrewVK
    20.02.2013 04:15
    Здравствуйте, Tom, Вы писали:

    Tom>А что не так с x64 если не секрет?


    Он крайне дохлый в плане оптимизации. Поэтому первым будут заменять именно его.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    kkolyan
    kkolyan
    23.02.2013 02:52
    Здравствуйте, AndrewVK, Вы писали:

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


    Tom>>А что не так с x64 если не секрет?


    AVK>Он крайне дохлый в плане оптимизации. Поэтому первым будут заменять именно его.



    попробовал выполнить код(ниже) на жаве и сишарп
    2.9гг
    c# — релиз, nf4.5(64 бита за 1700 млс, 32 — 2044)
    java — jdk 7u15 выполняет за 2000 млс,
    так что вроде с оптимизациями нормально или чтото не так под эклипсом запустил?


    public class Tester {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
    
            long start = System.currentTimeMillis();
            int m = 1024 * 1024;
            Test(100 * m);
            long end = System.currentTimeMillis();
            System.out.println("time" + (end - start));
    
        }
    
        static void Test(int limit_) {
            int limit = limit_;
            int sqr_lim;
            boolean[] is_prime = new boolean[limit + 1];
            int x2, y2;
            int i, j;
            int n;
    
            sqr_lim = (int) Math.sqrt(limit);
            for (i = 0; i <= limit; i++)
                is_prime[i] = false;
            is_prime[2] = true;
            is_prime[3] = true;
    
            x2 = 0;
            for (i = 1; i <= sqr_lim; i++) {
                x2 += 2 * i - 1;
                y2 = 0;
                for (j = 1; j <= sqr_lim; j++) {
                    y2 += 2 * j - 1;
    
                    n = 4 * x2 + y2;
                    if ((n <= limit) && (n % 12 == 1 || n % 12 == 5))
                        is_prime[n] = !is_prime[n];
    
                    // n = 3 * x2 + y2;
                    n -= x2;
                    if ((n <= limit) && (n % 12 == 7))
                        is_prime[n] = !is_prime[n];
    
                    // n = 3 * x2 - y2;
                    n -= 2 * y2; //
                    if ((i > j) && (n <= limit) && (n % 12 == 11))
                        is_prime[n] = !is_prime[n];
                }
            }
    
            for (i = 5; i <= sqr_lim; i++) {
                if (is_prime[i]) {
                    n = i * i;
                    for (j = n; j <= limit; j += n) {
                        is_prime[j] = false;
                    }
                }
            }
    
        }
    
    }



    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    namespace cappTestPrime
    {
        public class Tester
        {
    
    
            public static void Main(String[] args)
            {
    
                var sw = Stopwatch.StartNew();
    
                int m = 1024 * 1024;
    
                Test(100 * m);
    
                var end = sw.ElapsedMilliseconds;
                Console.WriteLine("elapsed=" + end);
    
    
            }
    
            static void Test(int limit_)
            {
                int limit = limit_;
                int sqr_lim;
                bool[] is_prime = new bool[limit + 1];
                int x2, y2;
                int i, j;
                int n;
    
                sqr_lim = (int)Math.Sqrt(limit);
    
                for (i = 0; i <= limit; i++)
                    is_prime[i] = false;
                is_prime[2] = true;
                is_prime[3] = true;
    
                x2 = 0;
                for (i = 1; i <= sqr_lim; i++)
                {
                    x2 += 2 * i - 1;
                    y2 = 0;
                    for (j = 1; j <= sqr_lim; j++)
                    {
                        y2 += 2 * j - 1;
    
                        n = 4 * x2 + y2;
                        if ((n <= limit) && (n % 12 == 1 || n % 12 == 5))
                            is_prime[n] = !is_prime[n];
    
                        // n = 3 * x2 + y2;
                        n -= x2;
                        if ((n <= limit) && (n % 12 == 7))
                            is_prime[n] = !is_prime[n];
    
                        // n = 3 * x2 - y2;
                        n -= 2 * y2; // 
                        if ((i > j) && (n <= limit) && (n % 12 == 11))
                            is_prime[n] = !is_prime[n];
                    }
                }
    
                for (i = 5; i <= sqr_lim; i++)
                {
                    if (is_prime[i])
                    {
                        n = i * i;
                        for (j = n; j <= limit; j += n)
                        {
                            is_prime[j] = false;
                        }
                    }
                }
    
            }
    
        }
    }
    AndrewVK
    AndrewVK
    03.03.2013 12:32
    Здравствуйте, kkolyan, Вы писали:

    K>попробовал выполнить код(ниже) на жаве и сишарп


    При чем тут джава? Ты 32 и 64 бита сравни, да не на синтетике, а на реальном коде.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    IT
    IT
    20.02.2013 03:31
    Здравствуйте, xvost, Вы писали:

    X>Сецчас язык настолько опережает рантайм, что дальнейшие "мажорные" фичи — это рост колосса на глиняных ногах.

    X>С точки зрения людей, не знакомых с кухней MS, C# и .NET CLR — даже не муж и жена, а вообще один человек.
    X>Так что все силы надо пускать на CLR — многоплатформенность, нормальные оптимизации, наконец-таки нормальный x64, внятный и предсказуемый GC

    Не согласен. Тот же Немерле опровергает эту теорию. Например, хвостовая рекурсия в нём работает давно, без поддержки CLR и гораздо более эффективнее. А дженерики, методы расширения, тюплы и аналог динамиков в нём появились раньше, чем это появилось в CLR.
    AndrewVK
    AndrewVK
    20.02.2013 04:15
    Здравствуйте, xvost, Вы писали:

    X>Сецчас язык настолько опережает рантайм, что дальнейшие "мажорные" фичи — это рост колосса на глиняных ногах.


    По рантайму тоже подвижки есть, кроме того, сейчас команда рантайма намного теснее работает с шарповской, нежели раньше. Но подробности пока под NDA.

    X>Так что все силы надо пускать на CLR — многоплатформенность, нормальные оптимизации, наконец-таки нормальный x64, внятный и предсказуемый GC


    Многоплатформенности ждать не стоит, остальное вполне.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 23 on Windows 8 6.2.9200.0>>
    VladD2
    VladD2
    23.02.2013 08:36
    Здравствуйте, xvost, Вы писали:

    X>Так что все силы надо пускать на CLR — многоплатформенность, нормальные оптимизации, наконец-таки нормальный x64, внятный и предсказуемый GC


    Там команды разные. Так что силы перебросить не удастся.

    К тому же 90% хотелок, описанных в этой теме, реализуются без изменения рантайма.
    Tanker
    Tanker
    20.02.2013 08:42
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Небольшое вступление.


    computation expressions, как в F#
    http://msdn.microsoft.com/en-us/library/dd233182.aspx

    Расширеная поддержка туплов, множественное присваивание:
    Tuple<int,string> F();
    
    var (a, s) = F();


    Компайл тайм рефлексия:
    class F<TArg>
    {
     void Method1(TArg arg1);
    }
    ...
    var info = typeOf(new F<string>()).Method1.arg1.Type.Name; // здесь генерится структура компилятором, в которой будет вся инфа о классе
    
    Assert.AreEqual("string",info);


    Расширеная поддержка выражений:
    Expression<Func<IEnumerable<int>>> array = GetValues();
    
    Expression e = `foreach(var item in #array) { DoSomething(item)}`;
    
    e.Compile().Invoke();

    Разворачивается в обычные экспрешны.

    Анонимные классы:
    var b = true;
    using(var f = new IDisposable { void Dispose { b = false; } } )
    {
    
    }

    Здесь по аналогии с лямбдами генерируется класс по описанию.
    k0st1x
    k0st1x
    21.02.2013 07:01
    вот еще вспомнилось, чего нехватает в C#

    сейчас нельзя написать структуру с автопропертями

    struct Foobar {
      public string Name {get; set;}
      public Foobar(string name) {
        Name = name;
      }
    }
    samius
    samius
    21.02.2013 07:29
    Здравствуйте, k0st1x, Вы писали:

    K>сейчас нельзя написать структуру с автопропертями

    Можно
    struct Foobar {
      public string Name {get; set;}
      public Foobar(string name): this() {
        Name = name;
      }
    }
    k0st1x
    k0st1x
    21.02.2013 07:43
    Здравствуйте, samius, Вы писали:

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


    K>>сейчас нельзя написать структуру с автопропертями

    S>Можно
    S>
    S>struct Foobar {
    S>  public string Name {get; set;}
    S>  public Foobar(string name): this() {
    S>    Name = name;
    S>  }
    S>}
    S>


    спасибо : ) не знал про этот странный нюанс.
    но все равно есть, что улучшать : )
    было бы здорово, чтобы вообще без дополнительного вызова.
    hardcase
    hardcase
    21.02.2013 07:52
    Здравствуйте, k0st1x, Вы писали:

    K>спасибо : ) не знал про этот странный нюанс.

    K>но все равно есть, что улучшать : )
    K>было бы здорово, чтобы вообще без дополнительного вызова.

    Этого вызова по факту не существует.
    samius
    samius
    21.02.2013 07:55
    Здравствуйте, k0st1x, Вы писали:

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


    S>>Можно

    S>>
    S>>  public string Name {get; set;}
    S>>  public Foobar(string name): this() {
    S>>    Name = name;
    S>>  }
    S>>


    K>спасибо : ) не знал про этот странный нюанс.

    Ничего странного. Если рассахарить и ввести поле, то компилятор точно так же не дает обращаться к сеттеру свойства, пока не будут проиницилизированы все поля. Либо явно инициализируем введенное поле, либо неявно (вызываем конструктор по умолчанию).
    K>но все равно есть, что улучшать : )
    K>было бы здорово, чтобы вообще без дополнительного вызова.
    Уверен что дополнительного вызова нет.
    nikov
    nikov
    06.03.2013 06:00
    Здравствуйте, k0st1x, Вы писали:

    K>спасибо : ) не знал про этот странный нюанс.


    Хотя о нём явно написано в спеке: 10.7.3 Automatically implemented properties
    Jack128
    Jack128 Ковариантность по возвращаемому значению в виртуальных методах.
    21.02.2013 07:19
    Здравствуйте, AndrewVK, Вы писали:

    Хз, можно ли это красиво сделать без правок в CLR, но фича полезная и логичная была бы.


    class CollectionItem {}
    class Collection 
    {
        protected virtual CollectionItem CreateItem() {...}
    }
    
    
    
    class MyCollectionItem: CollectionItem {}
    class MyCollection 
    {
        protected override MyCollectionItem CreateItem() {...}
    }


    В Java есть, AFAIR.
    k0st1x
    k0st1x
    21.02.2013 07:33
    Здравствуйте, Jack128, Вы писали:

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


    J>Хз, можно ли это красиво сделать без правок в CLR, но фича полезная и логичная была бы.



    J>
    J>class CollectionItem {}
    J>class Collection 
    J>{
    J>    protected virtual CollectionItem CreateItem() {...}
    J>}
    
    
    
    J>class MyCollectionItem: CollectionItem {}
    J>class MyCollection 
    J>{
    J>    protected override MyCollectionItem CreateItem() {...}
    J>}
    J>


    J>В Java есть, AFAIR.


    имхо, для такого кода хорошо подходят дженерики
    Jack128
    Jack128
    21.02.2013 07:39
    Здравствуйте, k0st1x, Вы писали:

    K>имхо, для такого кода хорошо подходят дженерики


    Ну и получится у класс с N дженерик параметрами, N — количество виртуальных не-void методов. Не страшно?
    gandjustas
    gandjustas
    21.02.2013 07:45
    Здравствуйте, Jack128, Вы писали:

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


    J>Хз, можно ли это красиво сделать без правок в CLR, но фича полезная и логичная была бы.



    J>
    J>class CollectionItem {}
    J>class Collection 
    J>{
    J>    protected virtual CollectionItem CreateItem() {...}
    J>}
    
    
    
    J>class MyCollectionItem: CollectionItem {}
    J>class MyCollection 
    J>{
    J>    protected override MyCollectionItem CreateItem() {...}
    J>}
    J>


    J>В Java есть, AFAIR.


    А зачем? Что мешает возвращать MyCollectionItem, там где требуется CollectionItem ? Вариантность вообще-то к дженерикам относится. А тут непонятно что.
    Jack128
    Jack128
    21.02.2013 07:53
    Здравствуйте, gandjustas, Вы писали:

    G>А зачем? Что мешает возвращать MyCollectionItem, там где требуется CollectionItem ?

    Не что не мешает. Точно так же как ничто не мешает в наследнике MyCollection2: MyCollection в CreateItem вернуть CollectionItem. А по идее — компилятор должен мешать.

    G>Вариантность вообще-то к дженерикам относится.

    Перечитал несколько раз. Слова generics — не нашел. Только абстрактное "operation".
    gandjustas
    gandjustas
    21.02.2013 08:04
    Здравствуйте, Jack128, Вы писали:

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


    G>>А зачем? Что мешает возвращать MyCollectionItem, там где требуется CollectionItem ?

    J>Не что не мешает. Точно так же как ничто не мешает в наследнике MyCollection2: MyCollection в CreateItem вернуть CollectionItem. А по идее — компилятор должен мешать.
    Кому должен? Ты же наследование делаешь чтобы обращаться к наследникам через ссылку на базовый класс. Соответственно непонятно зачем в наследнике менять типы, и как сообщить компилятору какой тип правильный.
    Вообще есть вероятность нарушения LSP при таком поведении.

    G>>Вариантность вообще-то к дженерикам относится.

    J>Перечитал несколько раз. Слова generics — не нашел. Только абстрактное "operation".

    http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.
    samius
    samius
    21.02.2013 08:09
    Здравствуйте, gandjustas, Вы писали:

    G>http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.


    object obj = 1;

    вот это уже ковариантность.
    object[] = new int[] { 1 };

    И это тоже. Дженериков нет, ковариантность есть.
    samius
    samius
    21.02.2013 08:12
    S>
    S>object[] = new int[] { 1 };
    S>

    S>И это тоже.
    Тут я немного нагнал, нужны reference типы. Для строк работает, для int-ов — нет.
    gandjustas
    gandjustas
    21.02.2013 12:41
    Здравствуйте, samius, Вы писали:

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


    G>>http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.


    S>
    S>object obj = 1;
    S>

    S>вот это уже ковариантность.
    Да ну? А где здесь функтор?

    S>
    S>object[] = new int[] { 1 };
    S>

    S>И это тоже. Дженериков нет, ковариантность есть.
    Array всегда был недодженериком. И эта ковариантность очень опасна, ведь можно сделать так:
    object[] x = new int[] { 1 };
    x[0] = new object(); //Ахтунг
    samius
    samius
    21.02.2013 12:46
    Здравствуйте, gandjustas, Вы писали:

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


    S>>
    S>>object obj = 1;
    S>>

    S>>вот это уже ковариантность.
    G>Да ну? А где здесь функтор?

    А зачем функтор?

    S>>И это тоже. Дженериков нет, ковариантность есть.

    G>Array всегда был недодженериком. И эта ковариантность очень опасна, ведь можно сделать так:
    G>
    G>object[] x = new int[] { 1 };
    G>x[0] = new object(); //Ахтунг
    G>

    Тем не менее, ковариантность массивов — формальная фича C# 1.0
    Философ
    Философ
    23.02.2013 09:47
    Здравствуйте, gandjustas, Вы писали:

    G>object[] x = new int[] { 1 };


    ЩИТО?
    VladD2
    VladD2
    23.02.2013 09:05
    Здравствуйте, samius, Вы писали:

    S>вот это уже ковариантность.

    S>
    S>object[] = new int[] { 1 };
    S>


    Это просто ошибка. Ковариантность в массивах работает только для ссылочных типов. А лучше бы ее вообще не было, так как для изменяемых типов для ее поддержки требуются рантайм-проверки. Дотент не хило тормозит из-за этого, при работе с массивами.
    Jack128
    Jack128
    21.02.2013 08:34
    Здравствуйте, gandjustas, Вы писали:

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


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


    G>>>А зачем? Что мешает возвращать MyCollectionItem, там где требуется CollectionItem ?

    J>>Не что не мешает. Точно так же как ничто не мешает в наследнике MyCollection2: MyCollection в CreateItem вернуть CollectionItem. А по идее — компилятор должен мешать.
    G>Кому должен?
    программисту.

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

    G>Вообще есть вероятность нарушения LSP при таком поведении.
    "такое поведение" — это поведение MyCollection2? естественно нарушит LSP. И именно этого и поможет избежать предлагаемая фича.


    G>>>Вариантность вообще-то к дженерикам относится.

    J>>Перечитал несколько раз. Слова generics — не нашел. Только абстрактное "operation".

    G>http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.

    а какой реальности идет речь, если вариантность — понятие из абстрактной математики? то что ты в курсе только о вариантности делегатов и интерфейсов не означает, что это понятие нельзя применить к другим "операциям".
    gandjustas
    gandjustas
    21.02.2013 12:09
    Здравствуйте, Jack128, Вы писали:

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

    G>>Вообще есть вероятность нарушения LSP при таком поведении.
    J>"такое поведение" — это поведение MyCollection2? естественно нарушит LSP. И именно этого и поможет избежать предлагаемая фича.
    Как она поможет избежать? Примером кода пожалуйста.


    G>>>>Вариантность вообще-то к дженерикам относится.

    J>>>Перечитал несколько раз. Слова generics — не нашел. Только абстрактное "operation".

    G>>http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.

    J>а какой реальности идет речь, если вариантность — понятие из абстрактной математики? то что ты в курсе только о вариантности делегатов и интерфейсов не означает, что это понятие нельзя применить к другим "операциям".
    Ты прочитал то статью? Как относится вариантность к тому что ты пишешь?
    Jack128
    Jack128
    21.02.2013 01:46
    Здравствуйте, gandjustas, Вы писали:

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


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

    G>>>Вообще есть вероятность нарушения LSP при таком поведении.
    J>>"такое поведение" — это поведение MyCollection2? естественно нарушит LSP. И именно этого и поможет избежать предлагаемая фича.
    G>Как она поможет избежать? Примером кода пожалуйста.

    class CollectionItem {}
    class Collection
    {
    protected virtual CollectionItem CreateItem() {...}
    }



    class MyCollectionItem: CollectionItem {}
    class MyCollection: Collection
    {
    protected override MyCollectionItem CreateItem() {...}
    }

    class MyCollection2: MyCollection
    {
    // protected override CollectionItem CreateItem() {...} так ошибка компиляции, так как CollectionItem не является MyCollectionItem, ковариантность нарушится. Раз не компилируется, то LSP не сможем нарушить.
    protected override MyCollectionItem CreateItem() {...} // а так вполне можно.

    }


    G>>>http://gandjustas.blogspot.ru/2009/11/blog-post.html вот тут посвежее и ближе к реальности.

    J>>а какой реальности идет речь, если вариантность — понятие из абстрактной математики? то что ты в курсе только о вариантности делегатов и интерфейсов не означает, что это понятие нельзя применить к другим "операциям".
    G>Ты прочитал то статью? Как относится вариантность к тому что ты пишешь?

    ну как, твоя статья описывает частные случаи вариантности, реализованные в C#. Какая вариантность бывает в других языках — можно на вики почитать.
    VladD2
    VladD2
    23.02.2013 09:02
    Здравствуйте, gandjustas, Вы писали:

    G>Вообще есть вероятность нарушения LSP при таком поведении.


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

    Ковариантность для возвращаемых значений работает в С++ и Яве.
    Быдлокодер
    Быдлокодер
    21.02.2013 07:33
    Блоки итераторов в лямбда выражениях!!
    SergASh
    SergASh
    22.02.2013 11:42
    Здравствуйте, AndrewVK, Вы писали:

    Нельзя ли сделать так, чтобы enum'ы реализовывали интерфейс IEquatable<> ?
    Sinclair
    Sinclair
    28.02.2013 04:17
    Здравствуйте, SergASh, Вы писали:

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


    SAS>Нельзя ли сделать так, чтобы enum'ы реализовывали интерфейс IEquatable<> ?

    А блоки итераторов — интерфейс ICloneable<>.
    FlevelEx
    FlevelEx
    23.02.2013 06:45
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.




    void Test(object sender)
    {
        if (sender is not Smth1)
        {
        }
    }



    вместо


    void Test(object sender)
    {
        if (!(sender is Smth1))
        {
        }
    }
    alexzz
    alexzz
    23.02.2013 06:52
    Здравствуйте, FlevelEx, Вы писали:

    FE>
    FE>void Test(object sender)
    FE>{
    FE>    if (sender is not Smth1)
    FE>    {
    FE>    }
    FE>}
    FE>


    public static class ObjectExtensions
    {
        public static bool IsNot<T>(this object obj)
        {
            return obj is T == false;
        }
    }
    Xentrax
    Xentrax В C# уже и так многое добавили
    25.02.2013 07:20
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.


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

    На мой взгляд, на данном этапе команду C# надо занять трудоёмкой и полезной работой, которая не приведёт к бесконтрольному росту языка.

    Я бы предложил им переписать компилятор, чтобы намного сильнее увеличить уровень оптимизации. Что-то типа LTCG (именно на уровне байт кода) было бы здорово получить.
    AndrewVK
    AndrewVK
    03.03.2013 12:33
    Здравствуйте, Xentrax, Вы писали:

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


    Основные оптимизации в дотнете производит не компилятор, а джит. И да, компилятор уже переписан.

    X> Что-то типа LTCG (именно на уровне байт кода) было бы здорово получить.


    Жди СТР нового JITа.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    Xentrax
    Xentrax
    03.03.2013 07:37
    Здравствуйте, AndrewVK, Вы писали:

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


    AVK>Основные оптимизации в дотнете производит не компилятор, а джит.


    Вот и я про то же. Основной бич программ на байт коде — время запуска. Конечно, MS очевидно хочет, чтобы в будущем весь софт выгружался с marketplace уже скомпилированный Ngen-ом. Но на ближайшие лет десять могли бы написать универсальный оптимизатор именно байт-кода, который производил бы тот же байт код.

    X>> Что-то типа LTCG (именно на уровне байт кода) было бы здорово получить.


    AVK>Жди СТР нового JITа.


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


    P.S. Поясните, плиз, лучше про компилятор, который "уже" переписали? Уже это когда? И что именно переписали?
    AndrewVK
    AndrewVK
    04.03.2013 01:42
    Здравствуйте, Xentrax, Вы писали:

    X>Конечно, MS очевидно хочет, чтобы в будущем весь софт выгружался с marketplace уже скомпилированный Ngen-ом.


    При чем тут marketplace? Ngen прекрасно работает с любыми дотнетными сборками.

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


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

    AVK>>Жди СТР нового JITа.


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


    Оно уже именно так и работает.

    X>P.S. Поясните, плиз, лучше про компилятор, который "уже" переписали? Уже это когда? И что именно переписали?


    Компилятор. Полностью. На C#. Это одна из составных частей Розлина.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    GlebZ
    GlebZ
    04.03.2013 07:47
    Здравствуйте, AndrewVK, Вы писали:

    AVK>При чем тут marketplace? Ngen прекрасно работает с любыми дотнетными сборками.

    Неверно. Для ngen требуются административные права. Это приводит к невозможности его использования в моих приложениях. Для меня ngen'a — нету.
    AndrewVK
    AndrewVK
    04.03.2013 12:10
    Здравствуйте, GlebZ, Вы писали:

    GZ>Неверно. Для ngen требуются административные права.


    Для инсталляторов обычно тоже.

    GZ> Это приводит к невозможности его использования в моих приложениях.


    Современные фреймворки запускают ngen для часто используемых сборок самостоятельно, в том числе и для твоих продуктов.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    GlebZ
    GlebZ
    04.03.2013 02:24
    Здравствуйте, AndrewVK, Вы писали:

    GZ>>Неверно. Для ngen требуются административные права.

    AVK>Для инсталляторов обычно тоже.
    Ваще-то нет. Всё прекрасно ставится в профайл, и прекрасно работает в терминалках.
    Ладно, я вполне понимаю зачем они требуют для ngen — full trust. На здоровье, мне на это наплевать. Но зачем требовать административных прав для запуска ngen, когда он спокойно компилируется в профайл — мне непонятно.

    GZ>> Это приводит к невозможности его использования в моих приложениях.

    AVK>Современные фреймворки запускают ngen для часто используемых сборок самостоятельно, в том числе и для твоих продуктов.
    Таких эффектов замечено не было. Где почитать?
    sgrape
    sgrape
    13.03.2013 11:03
    Здравствуйте, AndrewVK, Вы писали:

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

    AVK>Основные оптимизации в дотнете производит не компилятор, а джит.

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

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

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

    Очень жаль, если команда дотнета так считает.
    Значит никаких высокоуровневых оптимизаций просто не будет.

    Как джит поможет превратить вот это:

                list.ForEach((item) =>
                    {
                        item.SetValue(1);
                    });


    например в это:

                for (int i = 0; i < list._array.Length; i++)
                {
                    list._array[i]._value = 1;
                }


    последовательно совершив инлайнинг лямбды внутрь ForEach, затем превратив ForEach в for, вытащив массив изнутри списка и выкинув проверки на границы массива в индексаторе?
    А ведь это только одна из элементарных оптимизаций, которые хотелось бы видеть в дотнете.

    Да просто чтобы развернуть цикл или сделать глобальный сквозной инлайнинг (чтобы схлопнуть многоуровневые вызовы мелких фукций) — разве надо знать архитектуру процессора?

    Но очевидно, ничего этого не будет, пока оптимизацией делает вид что занимается джит.

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

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

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

    PS: а по теме — ничего от С# не надо, пока приходится для всех объектов писать самопальную (зато быструю и компактную) сериализацию да переписывать код в стиле С, когда скорость нужна.
    WolfHound
    WolfHound
    13.03.2013 02:45
    Здравствуйте, sgrape, Вы писали:

    S>PS: а по теме — ничего от С# не надо, пока приходится для всех объектов писать самопальную (зато быструю и компактную) сериализацию да переписывать код в стиле С, когда скорость нужна.

    Попробуй немерле. То о чем ты говоришь, на макросах автоматизируется на раз.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
    k0st1x
    k0st1x
    13.03.2013 05:02
    Здравствуйте, sgrape, Вы писали:

    S>Как джит поможет превратить вот это:


    S>
    S>            list.ForEach((item) =>
    S>                {
    S>                    item.SetValue(1);
    S>                });
    
    S>


    S>например в это:


    S>
    S>            for (int i = 0; i < list._array.Length; i++)
    S>            {
    S>                list._array[i]._value = 1;
    S>            }
    
    S>


    S>последовательно совершив инлайнинг лямбды внутрь ForEach, затем превратив ForEach в for, вытащив массив изнутри списка и выкинув проверки на границы массива в индексаторе?

    S>А ведь это только одна из элементарных оптимизаций, которые хотелось бы видеть в дотнете.

    я против "инлайнинга из коробки".
    лично мне важно, чтобы stack trace совпадал с исходниками
    AlexRK
    AlexRK
    13.03.2013 07:59
    Здравствуйте, k0st1x, Вы писали:

    K>я против "инлайнинга из коробки".

    K>лично мне важно, чтобы stack trace совпадал с исходниками

    Для этого давно придуманы debug и release.
    Jack128
    Jack128
    13.03.2013 07:31
    Здравствуйте, sgrape, Вы писали:

    К слову, где то слышал, что ngen и jit оптимизируют абсолютно одинаково. это так??
    Osaka
    Osaka
    28.02.2013 01:23
    Записывать guid без кавычек и прочих выкрутасов, как обычное число.
    Не
    id = new Guid("218a8084-1e3d-4afa-8783-41df0147032d")

    а
    id = g218a80841e3d4afa878341df0147032d

    или ещё лучше в base64 (24 символа)
    Sinclair
    Sinclair
    28.02.2013 04:23
    Здравствуйте, Osaka, Вы писали:
    O>или ещё лучше в base64 (24 символа)
    Стесняюсь спросить — а зачем?
    Я бы ещё понял compile-time checking гуидных констант.
    Но он сам по себе никак не требует переписывания кода — я бы скорее попросил валидации всех выражений new Guid(expr), если expr резолвится в string constant.
    А экономить десяток байт в ущерб читаемости, имхо, нездоровая идея.
    Osaka
    Osaka
    28.02.2013 09:11
    O>>или ещё лучше в base64 (24 символа)
    S>Стесняюсь спросить — а зачем?
    Меньше занимает места на экране.
    Sinclair
    Sinclair
    28.02.2013 12:54
    Здравствуйте, Osaka, Вы писали:
    O>Меньше занимает места на экране.
    Омг. Если вам неважно это значение, схлопните регион, в котором оно.
    Osaka
    Osaka
    28.02.2013 04:42
    S>Если вам неважно это значение, схлопните регион, в котором оно.
    А если важно, и их несколько в строке?
    Sinclair
    Sinclair
    01.03.2013 02:10
    Здравствуйте, Osaka, Вы писали:

    S>>Если вам неважно это значение, схлопните регион, в котором оно.

    O>А если важно, и их несколько в строке?
    Если важно, то base64 — отвратительная идея. Хуже неё — только base64 от gzip от guid.
    Osaka
    Osaka
    28.02.2013 09:45
    S>Стесняюсь спросить — а зачем?
    А вообще идея возникла из неудобного выделения мышью (надо бы как число или слово — dblclick в 1 точке, а приходится вручную выцеливаться в начало и конец).
    Sinix
    Sinix
    28.02.2013 10:50
    Здравствуйте, Osaka, Вы писали:

    S>>Стесняюсь спросить — а зачем?

    O>А вообще идея возникла из неудобного выделения мышью (надо бы как число или слово — dblclick в 1 точке, а приходится вручную выцеливаться в начало и конец).
    Двойной щелчок перед открывающей кавычкой пробовали?
    Osaka
    Osaka
    28.02.2013 04:42
    S>Двойной щелчок перед открывающей кавычкой пробовали?
    Неудобно, нужно точно попадать и кавычки отрезАть потом (чтобы, например, в sql-запрос вписать).
    Sinclair
    Sinclair
    28.02.2013 12:55
    Здравствуйте, Osaka, Вы писали:

    S>>Стесняюсь спросить — а зачем?

    O>А вообще идея возникла из неудобного выделения мышью (надо бы как число или слово — dblclick в 1 точке, а приходится вручную выцеливаться в начало и конец).
    ОМГ. То есть вы предлагаете вместо починки IDE починить язык? Ну-ну.
    Osaka
    Osaka
    28.02.2013 04:42
    S>ОМГ. То есть вы предлагаете вместо починки IDE починить язык? Ну-ну.
    Зачем делать не-интуитивнопонятные выкрутасы в иде, если можно сделать чётко и лаконично в языках?
    Sinclair
    Sinclair
    01.03.2013 02:10
    Здравствуйте, Osaka, Вы писали:

    O>Зачем делать не-интуитивнопонятные выкрутасы в иде, если можно сделать чётко и лаконично в языках?

    Затем, что каждому своё.
    Язык нужен для того, чтобы его было легко читать человеку.
    IDE нужна для того, чтобы на этом легкочитаемом языке было легко писать.
    Don Reba
    Don Reba
    28.02.2013 01:08
    Здравствуйте, Osaka, Вы писали:

    S>>Стесняюсь спросить — а зачем?

    O>А вообще идея возникла из неудобного выделения мышью (надо бы как число или слово — dblclick в 1 точке, а приходится вручную выцеливаться в начало и конец).

    Это элементарно исправляется выкидыванием мыши установкой VsVim. Выделение строки: vi". Всё просто!
    gravatar
    Аноним
    28.02.2013 01:21
    Здравствуйте, Osaka, Вы писали:

    S>>Стесняюсь спросить — а зачем?

    O>А вообще идея возникла из неудобного выделения мышью (надо бы как число или слово — dblclick в 1 точке, а приходится вручную выцеливаться в начало и конец).

    Resharper: Ctrl+W. И несколько раз до расширения выделения до нужных границ.
    Yoriсk
    Yoriсk
    28.02.2013 10:40
    Здравствуйте, Osaka, Вы писали:

    O>
    id = g218a80841e3d4afa878341df0147032d


    И как понять компилятору: это guid или переменная?

    Зарезервируем все guid-ы?
    Osaka
    Osaka
    28.02.2013 04:42
    Y>И как понять компилятору: это guid или переменная?
    По длине
    AndrewVK
    AndrewVK
    03.03.2013 12:42
    Здравствуйте, Osaka, Вы писали:

    O>Записывать guid без кавычек и прочих выкрутасов, как обычное число.


    Еще один literal of the day с применением 1 штука на мегабайт кода?
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    iHateLogins
    iHateLogins
    12.03.2013 08:15
    Здравствуйте, AndrewVK, Вы писали:

    O>>Записывать guid без кавычек и прочих выкрутасов, как обычное число.

    AVK>Еще один literal of the day с применением 1 штука на мегабайт кода?

    Как насчёт 0x синтакса из T-SQL?
    gravatar
    Аноним
    13.03.2013 09:02
    HL>Как насчёт 0x синтакса
    Кстати да. Реализовать поддержку Int128, и не понадобится в языке изобретать ничего нового.
    GlebZ
    GlebZ
    28.02.2013 07:38
    Здравствуйте, AndrewVK, Вы писали:

    Очень хотелось бы Dispose по exception. Пример, примерно такой:


    class MyClass:IDisposableException
    {
       public MyClass(Context c){...}
       public void Dispose(){ context.Commit();}
       public void Dispose(Exception e)
       {
        context.Rollback();
        Log.Exception(e);
        throw;
       }
    }
    
    void main()
    {
       using(new MyClass(new Context()))
       {
    /// do something
       }
    }


    Синтаксический сахар вырождается примерно в структуру:


    void main()
    {
       var myClass=new MyClass(new Context());
       bool bDisposed;
       try
       {
    ///do something
       }
       catch(Exception e)
       {
          myClass.Dispose(e);
          bDisposed=true;
       }
       finally
       {
          if (!bDisposed)
              myClass.Dispose();
       }
    
    }


    Доработка простая как 2 копейки. Но периодически её сильно не хватает.
    GlebZ
    GlebZ
    28.02.2013 08:13
    Да и еще хотелось бы иметь switch по типам. Лучше даже в виде проверки is.

    switch (myObj)
    {
       case typeof(MyClass):....
       case typeof(MyClass2):....
    }


    Ручной полиморфизм иногда пригождается. Кроме того он более управляем, чем перегрузка методов.
    х
    х
    28.02.2013 04:10
    Здравствуйте, AndrewVK, Вы писали:

    Из мелкого мне бы хотелось возможность наследовать парралельные ветки:


        //Base interfaces
        interface IXmlNode
        {
            IList<IXmlNode> Children { get; }
        }
    
        interface IXmlElement : IXmlNode
        {
        }
    
        // Simple implementation
        class XmlNodeBase : IXmlNode
        {
            public IList<IXmlNode> Children
            {
                get { return children; }
            }
            IList<IXmlNode> children = new List<IXmlNode>();
        }
    
        class XmlElementBase : XmlNodeBase, IXmlElement
        {
        }
    
        //Real Implementation
        class MsXmlNode : XmlNodeBase
        {
        }
    
        class MsXml : MsXmlNode, XmlElementBase//Error here!
        {
        }


    Из крупного хочется мочь создавать доменные языки сразу в коде, на пример пусть я хочу чтобы, у Dictionary можно было указывать название свойств вместо Key и Value, для этого делаю свою лексему:

    //создаю лексему, которая ведёт себя как тип
        let dictionary = dictionary<KeyType KeyName, ValueType ValueName> : Type
            where KeyType: Type, KeyName: Identifier, ValueType: Type, ValueType: Identifier
        {
            class @item : KeyValuePair<KeyType, ValueType>
            {
                public KeyType KeyName { get { return base.Key; } set { base.Key = value; }}
                public ValueType ValueName { get { return base.Value; } set { base.Value = value; }}
            }
            class @ : IEnumerable<@item>
            {
            }
        }
    
    //В итоге могу писать так:
    var test = new dictionary<string passport, string fullname>();
    foreach(var i in test)
        Console.WriteLine("{0}->{1}", i.passport, i.fullname);
    Flammable
    Flammable
    01.03.2013 04:07
    Хотелось бы объявлять операторы в интерфейсах.
    И какой-нибудь механизм, позволяющий писать дженерики, принимающие только numeric-типы, например (общем случае реализующие какой-то набор операторов).
    Silver_S
    Silver_S
    01.03.2013 05:03
    Сокращенное написание такого проперти:

    int _prop;
    int Prop
    {
       get{ return _prop; }
       set
       {
         if(_prop!=value)
         {
            _prop=value;
            Update();
         }
       }
    }


    Сокращенная форма того же самого:
    int Prop{ onchange { Update(); } }

    Или существующий keyword приспособить, например, new
    AndrewVK
    AndrewVK
    03.03.2013 12:44
    Здравствуйте, Silver_S, Вы писали:

    S_S>Сокращенное написание такого проперти:


    Эта фича чаще всего запрашивается. Мэдс пару вариантов синтаксиса показывал, но там довольно много всяких побочных вопросов.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    Flammable
    Flammable
    01.03.2013 06:03
    Еще добавить полноценную поддержку MMX/SSE для оптимизации вычислений с плавающей точкой.
    hardcase
    hardcase
    01.03.2013 06:31
    Здравствуйте, Flammable, Вы писали:

    F>Еще добавить полноценную поддержку MMX/SSE для оптимизации вычислений с плавающей точкой.


    Это возможно реализовать только с изменением рантайма, сам язык для поддержки интринзиков менять не нужно. В Mono такое сделали, но я даже не уверен что этим API кто-либо пользуется.
    Flammable
    Flammable
    01.03.2013 06:50
    Здравствуйте, hardcase, Вы писали:
    H>Это возможно реализовать только с изменением рантайма, сам язык для поддержки интринзиков менять не нужно. В Mono такое сделали, но я даже не уверен что этим API кто-либо пользуется.
    Мало ли, вдруг и рантайм обновят. Сравнения производительности вычислений на c++ и c# гуглятся и показывают дикое отставание последнего. Игнорирование MMX/SSE — одна из далеко не последних причин.
    koandrew
    koandrew
    04.04.2013 05:38
    Здравствуйте, hardcase, Вы писали:

    H>Это возможно реализовать только с изменением рантайма, сам язык для поддержки интринзиков менять не нужно. В Mono такое сделали, но я даже не уверен что этим API кто-либо пользуется.

    Однозначно в рантайме. Иначе маршаллинг съест нафиг всё преимущество параллельного вычисления.
    AndrewVK
    AndrewVK
    03.03.2013 12:45
    Здравствуйте, Flammable, Вы писали:

    F>Еще добавить полноценную поддержку MMX/SSE для оптимизации вычислений с плавающей точкой.


    Должно быть в следующей версии JIT.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    QrystaL
    QrystaL
    03.03.2013 01:24
    Здравствуйте, AndrewVK, Вы писали:
    AVK>Должно быть в следующей версии JIT.
    А хотя бы ориентировочные сроки выхода есть? (2013, 2014, ...)?
    AndrewVK
    AndrewVK
    04.03.2013 01:42
    Здравствуйте, QrystaL, Вы писали:

    AVK>>Должно быть в следующей версии JIT.

    QL>А хотя бы ориентировочные сроки выхода есть? (2013, 2014, ...)?

    СТР должен быть скоро. А что касается релиза — у меня никаких данных нет.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 66 on Windows 8 6.2.9200.0>>
    gravatar
    Аноним
    04.03.2013 09:39
    Здравствуйте, AndrewVK, Вы писали:

    1. constraint на enum.
    2. public int MyProp { get; set; } = 10 (задалбался для этого заводить конструктор)
    3. (почти как 2). Дать возможность инициализировать поля как private MyContainer _containter = new MyContainer(this);
    4. var f = x => x + 1; Хочется, чтобы был авто-вывод к Func и Action
    ldarcy
    ldarcy
    05.03.2013 06:15
    Здравствуйте, AndrewVK, Вы писали:

    Partial attributes? Чтобы атрибуты на член класса можно было указывать в разных файлах.
    iHateLogins
    iHateLogins Анонимные классы, модули, вычисляемые строки и пр.
    08.03.2013 07:23
    1) Анонимные классы как в джаве
    2) Модули из CLR
    3) свитчи по типам
    4) кейс-инсенситив свитч (инвариант)
    5) Вычисляемые строки как в повершелле ("@var") — пусть хотя бы и с возможностью использования только переменных и полей в области видимости.
    6) catch нескольких типов сразу catch(IOException, FileNotFoundException){}
    7) internals visible only to на уровне классов (для проектов, у которых одна большая ДЛЛ и не хочется "делиться" внутренностями класса со всеми)
    8) Байндинг одного алиаса к нескольким неймспейсам.
    Евгений Акиньшин
    Здравствуйте, AndrewVK, Вы писали:

    1) Возврат множества значений из функции, что-нибудь типа:


    public (string a, int b) Function()
    {
      return new { a = "text", b  = 1 };
    }


    2) Более мощная система ограничений для дженериков, в частности ограничения на поддержку перегруженных операторов

    3) Дефолтные реализации методов в интерфейсах (что-то типа трейтов)

    4) Null safety — not nullable types.

    Что-то типа


    string! str = null; //compile time error



    Хейлсберг говорил в интервью, что они этого не делают, потому что при использовании в существующих библиотеках это поломает совместимость. Но кто мешает не использовать эту фичу в старых апи?

    5) Упрощенный синтаксис для лямбд без параметров или с одним параметром, по типу того, как сделано в Котлине. Чтобы там, где ожидается лямбда, можно было бы писать ее без лишних скобок

    чтобы вместо

      list.Where(it => it < 5);


    было

      list.Where(it < 5);


    а если еще и позволить использовать операторный синтаксис для методов с одним параметром, то можно даже так:

    
    list where it < 5



    6) Ну и главная хотелка это конечно мета-программирование, хотя бы для простейших случаев:


    
    [RaisesPropertyChanged]
    public string Str {get; set; }


    Но это, как я понимаю, выходит за рамки вопроса о небольших улучшениях.
    Цыба
    Цыба
    08.03.2013 01:10
    Здравствуйте, Евгений Акиньшин, Вы писали:

    ЕА>5) Упрощенный синтаксис для лямбд без параметров или с одним параметром, по типу того, как сделано в Котлине. Чтобы там, где ожидается лямбда, можно было бы писать ее без лишних скобок


    ЕА>чтобы вместо


    ЕА>
    ЕА>  list.Where(it => it < 5);
    ЕА>


    ЕА>было


    ЕА>
    ЕА>  list.Where(it < 5);
    ЕА>


    ЕА>[/c#]


    По-моему, дикость. Что если метод, подобный Where, будет принимать boolean в одной из своих перегрузок?
    Don Reba
    Don Reba
    08.03.2013 01:23
    Здравствуйте, Цыба, Вы писали:

    Ц>По-моему, дикость. Что если метод, подобный Where, будет принимать boolean в одной из своих перегрузок?


    В Немерле решается использованием подчёркивания вместо имени переменной. Причём, работает и для лямбд с несколькими параметрами:

    [2, 3, 5].Aggregate(_ * _) // 30
    Klikujiskaaan
    Klikujiskaaan
    12.03.2013 09:41
    Здравствуйте, Don Reba, Вы писали:

    DR>Здравствуйте, Цыба, Вы писали:


    Ц>>По-моему, дикость. Что если метод, подобный Where, будет принимать boolean в одной из своих перегрузок?


    DR>В Немерле решается использованием подчёркивания вместо имени переменной. Причём, работает и для лямбд с несколькими параметрами:


    DR>
    [2, 3, 5].Aggregate(_ * _) // 30


    Жопа какая-то :D
    gravatar
    Аноним
    01.04.2013 11:31
    Здравствуйте, AndrewVK, Вы писали:

    Что бы можно было написать так.

     public static implicit operator IEnumerable<MyOperator<T>>(IEnumerable<T> src)
            {
                return src.Select(a => MyOperator<T>.Create(a));
            }

    и не получить
    User-defined conversion must convert to or from the enclosing type
    gravatar
    Аноним
    01.04.2013 11:45
    Здравствуйте, Аноним, Вы писали:

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


    А>Что бы можно было написать так.


    хотя бы внутри

    public class MyOperator<T>
        {
    gravatar
    Аноним
    05.04.2013 11:54
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам. Желательно раскрыть мысль поподробнее.

    ...

    исправить наконец компилятор и сделать using abort безопасными. что бы в случае остановки потока abort-ом ресурсы гарантированно освобождались.
     
    using(var res=CreateSomeResource()) {
      // сечас компилятор генерит такой код что возможно вызвать Abort для потока и ресурсу не будет вызван Dispose();
    }


    сделать префиксы по умолчанию что бы короче писать
    class A {
    static public [dllimport(.....)] [SomeAttr] ... {
      void fn1() {}
      void fn2() {}
    }
    или во
    #prefixregion static public [Attr1] [Attr2] ...
    ...
    #endregion
    }


    из тойже оперы. чтобы можно было не уразывать каждый раз название enum
    enum Bits { B0=1,B1=2,B2=4,B3=8 };
    ...
    int r1=(int)( Bits.B0 | Bits.B1 | Bits.B2 | Bits.B3);
    int r2=(int) using(Bits) B0|B1|B2;
    ...
    void fn(Bits bits) {...}
    ...
    fn(using(Bits) B0|B1|B2|B3);
    или чтоб по умолчанию так было
    fn( B0|B1|B2|B3 );


    задание поведения при невозможности вычисления выражения (не только null exception но и например пропускать код)
    по принципу isset из php: isset( $a[1][2][3][4][5][6][7][8] )
      Action a1;
      if (a1!=null) a1();
    
      Action<string> trace
      if (trace!=null) trace( prepare_string_for_trace() );
    
      if (a!=null && a.b!=null && a.b.c!=null && a.b.c.d!=null) a.b.c.d( retrive_some_args() );
    
      // что бы было примерно так
      call a1();
      call trace( prepare_string_for_trace );
      call a.b.c.d( retrive_some_args() );


    подстановка кода например
      bool enable=true;
      after_each_line(enable, source_file => trace( "{0}:{1}", source_file.Name, source_file.Line ), ()=> {
         fn1();
         fn2();
         fn3();
         fn4();
      });
      ...
      bool enable=true;
      Action<SourceFile> fn=!enable ? null : source_file => trace( "{0}:{1}", source_file.Name, source_file.Line);
      fn1(); if (fn!=null) fn(new SourceFile() { Name="src.cs", Line=100, ... });
      fn2(); if (fn!=null) fn(new SourceFile() { Name="src.cs", Line=101, ... });
      fn3(); if (fn!=null) fn(new SourceFile() { Name="src.cs", Line=102, ... });
      fn4(); if (fn!=null) fn(new SourceFile() { Name="src.cs", Line=103, ... });


    сделать обытия для свойств помимо get_ set_ методов еще event_ событие было по изменению
    ...
    public int value=5 { get;set;modify; }
    ...
    value.modify+=()=>{ ... };
    или так
    onchange(value)+=()=> {...};


    иногда хочется вот такой вот порнографии
    for(int a=0;i<N;++a) {
    case first: {}
    case last: {}
    case odd: {}
    case even: {}
    case enter: {}
    case leave: {}
    case if (a%3==2) {}
    // every step
    }
    ...
    foreach(var it in list) {
    case first: {}
    case last: {}
    case odd: {}
    case even: {}
    case enter: {}
    case leave: {}
    case if (cond(it)) {}
    // ordinary
    }


    Не хватает такого синтаксиса в определения методов класса
    class A {
       public event void dyn_fn(object prm) { ... }
    }
    ...
    class A {
       Action<object> dyn_fn=dyn_fn_default;
       void dyn_fn_default(object prm) { ... }
    }


    Дозадание функций (регулярных выражений не прошу)
    class A {
      void fn(int x) switch;
      void fn(int x) case x=0 { ... }
      void fn(int x) case (x>10 && x<100) { ... }
      void fn(int x) case default { ... }
    }
    class B : public A {
      void fn(int x) case (x>200 && x<214) { ... }
    }


    Динамический switch
       class A {
         public switch cases;
         void fn(int cmd) {
            switch(cases(cmd)) {
              case 0: { ... } break;
              case 1: { ... } break;
              default: { ... } break;
            }
         }
       }
       class B : public A {
         void fn(int cmd) {
            switch(cases(cmd)) {
              case 2: { ... } break;
              case 3: { ... } break;
            }
         }
       }
       ...
       var b=new B();
       b.cases.add(4, cmd=> { ... });
       b.cases.add(5, cmd=> { ... });


    Очень не хватает контекста для функций и свойств
       class A {
         public static void fn(string msg) { var ctx=ThreadContext::GetCurrentThreadContext(); var recorder=ctx.Resolve<IRecorder>();  recorder.Record(msg); }
         int x;
         public int X { 
           get { 
             #if AUTOMATIC_DEBUG
             var ctx=ThreadContext::GetCurrentThreadContext(); var bp=ctx.Resolve<IBreakPoints>(); 
             bp.NotifyReadAccess(this,"A.get_X",x)
             #endif
             return x; 
           } 
           set { 
             #if AUTOMATIC_DEBUG
             var ctx=ThreadContext::GetCurrentThreadContext(); var bp=ctx.Resolve<IBreakPoints>(); 
             bp.NotifyWriteAccess(this,"A.set_X",value);
             #endif
             x=value;
           }
       }


    Не хватает простой авто генерации кода
      interface A {
        void f1(int x,int y);
        string f2(int x,int y,param object[] args);
        int X { get;set; }
        ...
      }
      class AWrapper : public A() {
        public A a;
        public void f1(int x,int y) { a.f1(x,y); }
        public string f2(int x,int y,param object[] args) { return a.f2(x,y,args); };
        public int X { get { return a.X; } set { a.X=value; } }
        ...
      }

    Вобщем нехватает макросов как так чтоб можно было генерить исходный текст параметрически.
    Didi
    Didi
    06.04.2013 06:50
    Наконец, хотя этот предмет не из приятных, я должен упомянуть PL/1, язык программирования, документация которого обладает устрашающими размерами и сложностью. Использование PL/1 больше всего напоминает полет на самолете с 7000 кнопок, переключателей и рычагов в кабине. Я совершенно не представляю себе, как мы можем удерживать растущие программы в голове, когда из-за своей полнейшей вычурности язык программирования — наш основной инструмент, не так ли! — ускользает из-под контроля нашего интеллекта. И если мне понадобится описать влияние, которое PL/1 может оказывать на своих пользователей, ближайшее сравнение, которое приходит мне в голову, — это наркотик. Я помню лекцию в защиту PL/1, прочитанную на симпозиуме по языкам программирования высокого уровня человеком, который представился одним из его преданных пользователей. Но после похвал в адрес PL/1 в течение часа он умудрился попросить добавить к нему около пятидесяти новых «возможностей», не предполагая, что главный источник его проблем кроется в том, что в нем уже и так слишком уж много «возможностей». Выступающий продемонстрировал все неутешительные признаки пагубной привычки, сводящейся к тому, что он впал в состояние умственного застоя и может теперь только просить еще, еще, еще... Если FORTRAN называют детским расстройством, то PL/1, с его тенденциями роста подобно опасной опухоли, может оказаться смертельной болезнью.
    Смиренный программист (EWD340) Эдсгер Дейкстра 1972г.

    Ничего не напоминает? Действительно, история развивается по спирали...
    IT
    IT
    06.04.2013 04:48
    Здравствуйте, Didi, Вы писали:

    D>Ничего не напоминает? Действительно, история развивается по спирали...


    Не напоминает. Фичи фичам рознь. Например, в том же PL/1 для того, чтобы сделать возможность вызывать функцию рекурсивно, нужно было помечать её особым ключевым словом. Вот такие там в основном были фичи. Ничего общего с тем что здесь обсуждается.
    AlexRK
    AlexRK
    06.04.2013 05:13
    Здравствуйте, IT, Вы писали:

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


    D>>Ничего не напоминает? Действительно, история развивается по спирали...


    IT>Не напоминает. Фичи фичам рознь. Например, в том же PL/1 для того, чтобы сделать возможность вызывать функцию рекурсивно, нужно было помечать её особым ключевым словом. Вот такие там в основном были фичи. Ничего общего с тем что здесь обсуждается.


    Ну, в C# тоже достаточно революционных фич а-ля partial methods.
    IT
    IT
    06.04.2013 05:21
    Здравствуйте, AlexRK, Вы писали:

    IT>>Не напоминает. Фичи фичам рознь. Например, в том же PL/1 для того, чтобы сделать возможность вызывать функцию рекурсивно, нужно было помечать её особым ключевым словом. Вот такие там в основном были фичи. Ничего общего с тем что здесь обсуждается.


    ARK>Ну, в C# тоже достаточно революционных фич а-ля partial methods.


    Весьма полезная штукенция, если речь идёт о генерации кода. При наличии полноценного МП, конечно, рудимент, но до полноценного МП нам ещё как до Парижу.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 69>>
    gravatar
    Аноним
    06.04.2013 09:10
    Здравствуйте, AndrewVK, Вы писали:

    AVK>Соответственно, от вас хотелось бы получить те фичи, которых не хватает лично вам.


    конструкцию assume такого вида:
      int ret=0;
      assume (res>0) or throw new Exception(GetErrorMessage(res)) {
         ret=DoOp1();
         ret=DoOp2();
         ret=DoOp3();
      }
      ...
      Action<string> action=null;
      ...
      assume (action!=null) or skip {
         ...
         action("some message");
         ...
         action("some message");
         ...
      }
      assume possible or skip {
         a.b.c.d.e.f=1; // проверять возможно ли выполнить такое действие если да то выполнить и ничего не делать если не возможно например a.b.c.d=null
      }
      assume no return {
         ...
         return 1; // ошибку компиляции если встретился return
         ...
      }
      object a=...;
      assume a is Control or skip {
        a.Name="name";
      }
      ...

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

    Что бы не писать так:
      int res=0;
      {
         ret=DoOp1(); if (!(res>0)) throw new Exception(GetErrorMessage(res));
         ret=DoOp2(); if (!(res>0)) throw new Exception(GetErrorMessage(res));
         ret=DoOp3(); if (!(res>0)) throw new Exception(GetErrorMessage(res));
      }
      Action<string> action=null;
      ...
      {
        if (action!=null) action("some message");
        ... 
        if (action!=null) action("some message");
        ...
      }
      // no return - на уровне компилятора (чтоб рефакторить длиныые портянки if-ов или switch-ей)
      {
         if (a!=null && a.b!=null && a.b.c!=null && a.b.c.d!=null && a.b.c.d.e!=null) a.b.c.d.e.f=1;
         // try { a.b.c.d.e.f=1; } catch {}
      }
    
      object a=...;
      if (a is Control) { Control local_a=(Control)a;
        local_a.Name="name";
      }


    Хотелось бы вложенных функций
       void Foo(int x) {
         int Bar(int a) { ... }
         Bar(x);
       }
       // а не только так
       void Foo(int x) {
         Func<int,int> Bar=(a)=>{ ... };
         Bar(x);
       }
    pavel783
    pavel783
    10.04.2013 06:19
    чего не хватает так это множественного наследования, просто за основу программирования взята математическая модель с ее иерархическими цепочками от частного к общему, с другой стороны должны же когдато предоставить возможность множественного кроссовера как например делается с растениями или в генетическом алгоритме — это был бы прорыв
    gravatar
    Аноним
    10.04.2013 07:50
    Здравствуйте, pavel783, Вы писали:

    P>чего не хватает так это множественного наследования, просто за основу программирования взята математическая модель с ее иерархическими цепочками от частного к общему, с другой стороны должны же когдато предоставить возможность множественного кроссовера как например делается с растениями или в генетическом алгоритме — это был бы прорыв


    Я против
    samius
    samius
    10.04.2013 07:51
    Здравствуйте, Аноним, Вы писали:

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


    P>>чего не хватает так это множественного наследования


    А>Я против

    Не беспокойтесь, изменениями в C# этот вопрос не решить. Тут нужно рантайм менять.
    Codechanger
    Codechanger
    10.04.2013 09:45
    Здравствуйте, pavel783, Вы писали:

    P>чего не хватает так это множественного наследования, просто за основу программирования взята математическая модель с ее иерархическими цепочками от частного к общему, с другой стороны должны же когдато предоставить возможность множественного кроссовера как например делается с растениями или в генетическом алгоритме — это был бы прорыв


    Это уже проходили в С++. При среднем уровне программиста вреда от множественного наследования больше, чем пользы, да и ногу отстрелить себе значительно легче. За 10 лет программирования на .Net как-то не возникало задачи, требующей множественное наследование.
    Flammable
    Flammable
    11.04.2013 06:40
    Здравствуйте, pavel783, Вы писали:
    P> возможность множественного кроссовера как например делается с растениями или в генетическом алгоритме — это был бы прорыв
    Кроссинговера, наверное. А вообще, как уже написали — не нужно.
    gravatar
    Аноним
    12.04.2013 02:11
    Автоматические свойства, с возможностью изменения только из конструктора.

    int Property { get; initonly set; }
    hardcase
    hardcase
    12.04.2013 06:00
    Здравствуйте, Аноним, Вы писали:

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


    А>
    А>int Property { get; initonly set; }
    А>


    Два слова тут лишние: initonly и set. Именно так сделано в Nemerle.
    Silver_S
    Silver_S
    23.04.2013 10:23
    Как-то автоматизировать написание wrapper. Хотя синтаксис будет кривоватый, какой ни придумывай, но хоть что нибудь. Иногда нужно.
    Например так:

    class C
    {
      private Cl2 _member;
      ...
      wrappers(_member)
      {
         int Prop1{get;set;}
         int Func1(int p1, ref int p2);
         ...
      }
    }

    В фигурных скобках декларация членов как в описании интерфейса (может с модификаторами доступа public protected private), эти члены появляются в классе, реализуются как обертки над членами _member.
    Т.е раскрываются в такое

    class C
    {
      private Cl2 _member;
      public Prop1{ get{return _member.Prop1;} set{_member.Prop1=value;} }
      public int Func1(int p1, ref int p2){ return member.Func1(p1, ref p2); }
      ...
    }