Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Возможные фичи C# 5

148 комментариев

Никто толком не знает что будет в следующей версии языка C#. Даже люди в C# Insiders (я в их числе) понятия не имеют, что там Microsoft придумает. Тем не менее, в сети есть очень много действительно хороших предложений, несколько из которых я решил представить ниже. Надеюсь получится хорошая дискуссия.

Замена для IEnumerable<T> — тут идея в том, что мы слишком много букв пишем, и что лучше, как это сделано в Boo, заменить IEnumerable одной буквой, чтобы можно были писать T* или T~. К сожалению, звездочка вполне может запутать тех, кто знает что такое указатель, так что придется поискать другой оператор.

Синтакcический сахар для dependency property. Идея простая – реализация DP на данный момент невменяема, т.е. выглядит как “код с известного полуострова” и мейнтейнить такие нагромождения не хочется. Уж лучше написать следующее:

public Message
{
  get; set;
  default { return "No message"; }
  assign { Console.WriteLine("Just changed message!"); }
}

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

NonNullable типы, то есть типы которые не могут быть null в принципе. Помечаем тип как T! (дуальная аналогия T?, что соответствует Nullable<T>) и всё! Некоторым правда этого мало – они хотят чтобы все типы были ! by default.

yield из анонимных функций – думаю тут все понятно. От себя добавлю, что было бы круто если бы можно было использовать var вместо полного описания прототипа. Например:

var z = (int [] x => { foreach (var y in x.Where(x % 2 == 0)) yield return y; }

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

public IEnumerable<Person> OldPeople(this Person person)
{
  if (person.Age > 80) yield return person;
  // instead of this
  foreach (var result in OldPeople(person.Children))
    foreach (var p in result)
      return p;
  // we write this
  foreach yield OldPeople(person.Children);
}

Sequence-инициализация, чтобы например 1..10 производило то же самое, что Enumerable.Range(1, 10).

Правильная инициализация кортежей. Сейчас метод может вернуть два значения в Tuple<T,U>, но получать их нужно через .Item1 и .Item2. Это нечитабельно, и лучше делать вот так:

(sex,death) = GetMeaningOf(life);

Хотя лучше всего наверное использовать struct-тип для возврата, т.к. иначе подсказки о том что возвращается можно получить только из документации.

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

public static new { T X, T Y } Vector2<T>(this T k)
{
    return new { X = k, Y = k };
}

Оператор цепочной проверки на null. Например, если один из элементов person.Address.PostCode является null, мы получим исключение, а проверять их все—лень. Поэтому хочется получить оператор а-ля ?. чтобы написал вот так person?.Address?.PostCode мы получили null если любой из элементов null.

Extension properties — у нас уже есть методы, а если еще будут свойства (как в F#), то легче будет делать примеси. Это некий аналог multiple inheritance который, насколько я понимаю, есть например в Scala.

Скрытая ленивость — иначе говоря, обертка вокруг Lazy<T> которая позволить переменной быть ленивой без всяких .Value и так далее. Например:

class C
{
  yield int Z;
  public C()
  {
    Z = SomeLazyComputation(); // only done when asked
  }
}

Приватные поля для свойств — еще одна идея как инкапсулировать поля когда объект не является POCO:

class C
{
  public int N
  {
    int n = 0;
    get { return n; }
    set { if (value != n) {
      n = value;
      NotifyPropertyChanged("n");
    } }
  }
}

Если у вас есть еще какие-то идеи насчет новой версии языка – пишите!

Advertisements

Written by Dmitri

28 сентября 2010 в 10:36

Опубликовано в .NET, C#

комментариев 148

Subscribe to comments with RSS.

  1. Хорошая статься Дмитрий.

    Пару фич из приведенного списка я бы использовал. Особенно идея насчет INotifyPropertyChanged. Возможно заменить атрибутом который можно применять к свойству или ко всему классу целиком.

    Sequence-инициализация тоже была бы полезной штукой.

    Насчет Lazy слышу первый раз. Спасибо, что просветили :). Насколько я понимаю эта возможность появилась в 4 версии, а в нашей организации до сих пор на 3.5. Да и причины по которым откладывают переход лично мне не понятны.

    Andrew

    28 сентября 2010 at 11:32

    • Так часто бывают. А некоторые сейчас только переходят с 2.0 :)

      Dmitri

      28 сентября 2010 at 12:24

      • Я вам больше скажу: а некоторые и не переходят. Или ставят МВС 2010, но все равно продолжают писать под 2.0. А почему? А потому что нормальный функционал можно прекрасно реализовать и на старых версиях фреймворка. А все новые плюшки хороши в основном для аутсортинга, ибо под лозунгом новейших технологий легче конкурировать и, стало быть, продаваться.

        Andrew Lassker

        16 октября 2010 at 23:03

        • Лично мне плевать на конкуренцию с аутсорсерами т.к. их рейты мне подавно не нужны. А с тем что все можно сделать на 2.0 не соглашусь — например DLR хорошо развязал нам руки.

          Dmitri

          17 октября 2010 at 0:47

  2. Множество фич есть в F#, ну, кроме относящихся к DP
    ксати, я тут занялся изучением F#, и вот как мне посоветовали апгрейдить ваш пример с DSL http://cs.hubfs.net/forums/thread/16535.aspx

    XuMiX

    28 сентября 2010 at 12:01

    • Класс, спасибо за наводку! Только мне не очень нравятся все эти |> в описании проекта — смахивает на <*> в WebSharper :)

      Dmitri

      28 сентября 2010 at 12:23

      • ну, так там в комментах ниже пишут, как от них можно избавиться

        XuMiX

        28 сентября 2010 at 12:29

      • у меня пока левел не дошел до уровня понимания computation expressions :)

        XuMiX

        28 сентября 2010 at 12:30

  3. Убрать «not nested» ограничение с классов в которых могут быть реалзованы extension methods. Если конечно это возможно, то убрать и обязательность делать это в static типе. Таким образом мы получим возможность писать расширения видимые в контексте только одного типа.
    Сценарий использования — скажем нужно написать приватный метод GetSomeItemsFrom(list), гораздо читабельнее было бы list.GetSomeItems(). Что скажете?

    Restuta

    28 сентября 2010 at 12:24

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

    ilya

    28 сентября 2010 at 13:41

    • Я подозреваю для get { return x; } большую вероятность JIT-inlining, поэтому даже забывая про необоснованность предварительной оптимизации, скорее всего для сборки в Release нет разницы между полем и невиртуальным свойством.

      Andrey Shchekin

      29 сентября 2010 at 1:50

  5. Могу предложить
    1. Сделать типизированный класс WeakReference.
    2. Добавить к классу Lazy функциональность WeakReference, если объекты могут быть легко пересозданы при необходимости.

    Александр

    28 сентября 2010 at 13:45

  6. Так, в порядке ворчания

    — dependency property все же не C# фича :) Но все же дефолтную реализацию нотификации прикрутить стоит.

    — не надо операторов типа «T!» уж лучше NonNullable. Читабельность кода с такими фишками падает. T* туда же. Не надо делать из С# какой-то RegExp :)

    — ну про yeild уже говорили :)

    — насчет цепной проверки на null, мне опять же больше нравиться форма записи в виде функции. Например в PHP есть метод isset() возвращающий true или false в зависимости от существования переменной. Вот как-то так и для null.

    Andrey

    28 сентября 2010 at 14:17

    • А мне нравится Т*, вроде очень удобно. Чисто теоретически. Конечно оператор * наверняка не подойдет.

      Dmitri

      28 сентября 2010 at 14:45

      • Дело не в самом знаке — он может быть любой.

        Есть такой факт — что мы не читаем по буквам, а воспринимаем информацию блоками (есть даже текст с переставленными буквами внутри слова читающийся без проблем). Именно по этому и сейчас легко не заметить «int?»

        Так что я не против фичи, но за читабельность.

        Andrey

        28 сентября 2010 at 14:53

        • Ну, уж не знаю, лично мне тоже нравится. T? / T! было бы весьма удобно.
          >Не надо делать из С# какой-то RegExp :)
          эх) посмотрите на F# — вот там рассадник таких вещей))
          http://msdn.microsoft.com/en-us/library/dd233228.aspx

          XuMiX

          28 сентября 2010 at 15:03

      • В Comega так и было сделано. И + для непустой/неnull последовательности.

        Andrey Shchekin

        29 сентября 2010 at 1:54

  7. Из того, что хочется и не указано выше.

    Аналог #light синтаксиса из F#

    — Возможность убрать {} — и заменить отступами (indentation)

    — Убрать ; если одна инструкция в строке

    — Для статических классов возможность вызывать функции без указания класса
    using System.Console

    в коде после такого можно писать WriteLine(«some»);

    Андрей

    28 сентября 2010 at 15:23

    • > — Возможность убрать {} – и заменить отступами
      > (indentation)
      > — Убрать ; если одна инструкция в строке

      Кладезь для багов :) :) :)

      Andrey

      28 сентября 2010 at 16:30

      • Так это же Python. Или Boo.

        Dmitri

        28 сентября 2010 at 16:41

        • С ними не работал. Видимо к счастью.
          Но не все, что есть в других языках — хорошие фичи.

          Вы еще PHP в пример поставьте. На мой взгляд его возможность просто объявлять переменную фактом использования просто кошмарна. Или считать опечатки ключевых слов за неопознанные константы.

          Andrey

          28 сентября 2010 at 17:02

        • Демагогия — я же ничего не говорил о PHP, а вы его взяли и разгромили.
          Посмотрите на F# — там еще до релиза сделали #light опцией по умолчанию.

          Андрей

          28 сентября 2010 at 17:20

        • Ну зачем так сразу — я просто привел пример известной мне фичи другого языка, которую я бы не хотел видеть в С#.

          А насчет F# — все собираюсь поглядеть, но работа и проекты затягивают. Но все же надо будет время выбрать поглядеть.

          Andrey

          28 сентября 2010 at 20:47

    • А вот штука с using System.Console — это вроде в Nemerle есть. Не назвал бы это огромным плюсом.

      Dmitri

      28 сентября 2010 at 18:04

  8. И как я мог забыть о pattern matching’е, вместе с discriminated union’ами, которые сейчас приходится эмулировать многословным наследованием.

    Андрей

    28 сентября 2010 at 15:27

    • Pattern matching — полезно, конечно. Что касается discriminated unions, так по мне это зло, источник неоднозначности, непонятности и наверняка нарушают что-то из SOLID :)

      Dmitri

      28 сентября 2010 at 16:54

      • В чем неоднозначность и непонятность? Это же обычная закрытая иерархия класов.

        Mike Chaliy

        28 сентября 2010 at 17:17

        • В Scala и Nemerle может быть и открытая ;)

          ControlFlow

          28 сентября 2010 at 17:37

        • Это хорошо что есть. Надо и мне Scalу поглядеть.

          Mike Chaliy

          28 сентября 2010 at 17:40

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

          Это позволяет проверять полноту паттер-матчинга во время компиляции.

          Vlad

          28 сентября 2010 at 20:31

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

        hc

        28 сентября 2010 at 20:04

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

        Утверждение ваще просто смехотворна, так как паттерн-матчинг (ПМ) был разработан совместно с алгебраическими типами и является стройной математической концепцией.

        Только с алгебраическими типами ПМ демонстрирует свою истинную силу, так как только для них есть красивый синтаксис.

        По существу, алгебраические типы — это не более чем семейство типов (в ООП выражается как набор типов с единым предком) которые можно выразить через их конструкторы. Так что бояться тут не чего.

        Vlad

        28 сентября 2010 at 20:36

        • Да я не боюсь. Просто мои попытки выпилить value из паттерн-матчинга кончились ничем. Например, то что для последовательности букв я должен писать | '&' :: 'g' :: 't' :: '&' :: tail вместо | "&gt;" :: tail – это уже огромный минус. Я конечно придираюсь, знаю что парадигма другая и что тот же разбор строк лучше делать парсерами или “по привычке”, просто констатирую тот факт, что даже от паттерн-матчинга я мало чего получаю.
          Что касается алгебраических типов и всяких приколов вроде Option<'t> – бенефиты всего этого весьма сомнительны. Я понимаю что это и как работает, но не знаю – то ли мозг уже проштампован тем что де “легче наследование сделать”, то ли не знаю что еще. По крайней мере, по этой фиче я в C# не скучаю.

          Dmitri

          28 сентября 2010 at 21:53

        • > Просто мои попытки выпилить value из паттерн-матчинга кончились ничем.

          Значит не с того конца подходили.
          Большая часть того что вы описали в своей «хотелке» уже давно реализовано в Nemerle в виде макросов. Макросы же Nemerle просто не мыслимы без алгебраических типов (которые в нем называются вариантными типами).

          Попробуйте написать какой-нибудь не примитивные проект на этом языке. В процессе работы вы освоите основные фичи языка включая варианты и ПМ. Уверяю, Вас что через месяц Вы измените свое мнение об алгебраических типах.

          >Например, то что для последовательности букв я должен писать | ‘&’ :: ‘g’ :: ‘t’ :: ‘&’ :: tail вместо | «>» :: tail – это уже огромный минус.

          Начнем с того, что писать как Вы продемонстрировали можно только если вы работаете со списком. А для списка запись «…» смысла не имеет. Потому она и не применима. Для сравнения попробуйте написать что-нибудь подобное с List. У Вас вообще ничего не получится.

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

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

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

          Например, вот парсер C# 4.0
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpParser/ созданный с помощью макроса PegGrammar.

          В этом http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpParser/Parser.n файле описывается грамматика, а в файлах http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpParser/Parser_*.n находятся обработчики которые генерируют AST (например, следующий файл содержит обработчики для выражений http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpParser/Parser_Expressions.n). AST описывается вариантными типами. Например, вот так описывается выражение: http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpParser/Expr.n

          А вот код из конвертера преобразующего AST выражений C#-а в AST выражений немерла:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/CSharpToNemerle/AstConverter_Expr.n

          Представьте насколько бы разросся код если бы вы описывали AST выражений классами, а анализировали бы его с помощью if-ов. Если не можете представить, то просто поверьте, что объем кода увеличился бы где-то в 5-10 раз. А его понятность уменьшилась бы аналогичным образом.

          Собственно сам макрос PegParser сам использует варианты для внутреннего представления грамматик. Вот как выглядит описание AST грамматики в формате PEG:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/LRPEGCC/Rule.n#199

          Такое представление позволяет резко облегчить анализ и оптимизацию грамматики. Вот как выглядит оптимизация грамматики:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/LRPEGCC/Optimizer.OptimizeRule.n
          Не трудно заметить, что оптимизация почти вся состоит из паттер-матчинга. И возможно это благодаря тому, что грамматика представлена в виде вариантов (т.е. алгебраических типов).

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

          Если хотите понять алгебраические типы и научиться с ними работать, то советую скачать и установить http://code.google.com/p/nemerle/ и прочесть «Язык Nemerle»:
          http://rsdn.ru/article/Nemerle/TheNemerleLanguage.xml
          http://rsdn.ru/article/Nemerle/TheNemerleLanuage-prt-2.xml
          http://rsdn.ru/article/Nemerle/TheNemerleLanuage-prt-3.xml

          И не просто прочесть, а каждый пример скомпилировать и разобрать вдоль и поперек (можно под отладчиком).
          Это позволит ощутить мощь вариантов и ПМ на реальном практическом примере.

          Vlad

          29 сентября 2010 at 0:38

        • Как раз option очень удобен — код с его использованием выглядит нагляднее, нежели банальная проверка на null’ы или значения по умолчанию.

          Утрируя — это встроенный в язык Null object pattern.

          Андрей

          29 сентября 2010 at 0:50

  9. Дмитрий, а что такое «примесь»? А что такое mixin в Scala? А как мне extension-свойства помогут сделать «некий аналог multiple inheritance»?

    ControlFlow

    28 сентября 2010 at 17:18

    • Дык… Класс А, от него наследует класс Б. То есть в Б уже ничего не добавить. А так, объявил специальный БЕкстеншнс и давай в нём нужных методов добавлять. И в зависимости от области видимости у Б магическим образом появляются всякие нужные методы. Вроде как декоратор, только проще.
      Екстеншн свойства позволят расширять интерфейс класса, собственно, свойствами, а не только методами, как сейчас. Вот и всё, вроде бы.

      Maxim Moiseev

      28 сентября 2010 at 17:37

      • Полей нема. А какой mixin без состояния? Понятно что состояние можно емулировать. Но всетаки.

        Mike Chaliy

        28 сентября 2010 at 17:42

      • Очень советую глянуть на Scala mixin. Они могут и состояние добавлять, и реализацию интерфейсов, mixin’ы можно унаследовать от классов и других mixin’ов, mixin’ы могуть override’ить методы.

        Что из этого повзолят extension properties? Как статические методы вне класса, коими они будут являются, позволят сделать «некий аналог multiple inheritance»)?

        ControlFlow

        28 сентября 2010 at 17:50

    • Примесь (mixin) – конструкт который путем множественного наследования (С++), добавляет некий функционал в класс. В языке Scala есть возможность подмешивать функционал к существующим классам. А вот в C# у нас проблемы – мы можем добавлять только поведение, т.к. начинка Extension-классов статична (как и они сами). А вот если бы этого не было, можно было бы классам добавлять поведение и свойства пост-фактум. Кстати: в принципе это можно делать через статический Dictionary<string,WeakReference>, но это очень хрупкое решение.

      Dmitri

      28 сентября 2010 at 17:41

  10. Я предлагал некоторые из этих тем на SO ещё для 4.0 (http://stackoverflow.com/questions/138367/most-wanted-feature-for-c-4-0/426002#426002)

    В принципе я сомневаюсь в:
    1. поддержке dependency property на таком уровне, т.к. too specific
    2. NonNullable (х.з., вроде бы требует хитрого анализа в конструкторе и виртуальных методах, вызванных из конструктора базового класса). Плюс частично покрывается контрактами, хотя и довольно страшно.
    3. sequences (мне кажется это слишком редко нужно, чтобы делать special syntax)

    Пара дополнений:
    1. Правильная инициализация «кортежей» — Miguel de Icaza сделал в mcs —future http://tirania.org/blog/archive/2009/Dec-23.html
    2. Extension properties Eric Lippert вроде обсуждал, говорил что они пытались добавить в 4.0, но не влезло по времени
    3. Есть сильное подозрение, что для C# 4.0 рассматривают immutable types, вроде из блога того же Липперта

    Я лично хотел бы JavaGI, yield foreach, better string.Format, и какой-нибудь AOP. И immutable types. И «.?».

    Что касается скрытой ленивости, хочется обобщения Lazy и Future с возможностью иметь арифметические операции и вызовы методов без потери отложенного вычисления (или будущего вычисления). Особенно хотелось бы магии вроде Lazy(disposable) implicitly implements IDisposable.

    Из невероятного, было бы ещё очень клёво получить quantum superpositions или junctions (http://en.wikipedia.org/wiki/Perl_6#Junctions), но в это я не верю. А, ещё я бы не отказался от 5 <= x <= 10 в качестве встроенной возможности.

    Andrey Shchekin

    28 сентября 2010 at 17:29

    • А можешь в кратце написать про то, что такое Java GI?

      Dmitri

      28 сентября 2010 at 18:03

      • http://homepages.cwi.nl/~ralf/JavaGI/paper.pdf
        Суть примерно следующая: This (ссылка на текущий тип в generic), определение имплементации интерфейса классом отдельно от класса интерфейса (ретроактивная имплементация интерфейса) и таким образом определение мультиметодов/dynamic dispatch:

        interface Count { int count(); }
        implementation Count [BTree] { int count() { return 0; } } // works also for Leaf
        implementation Count [Node] { int count() { return this.left.count() + this.right.count() + 1; }
        } 
        

        статические интерфейсы фабрик (применимы когда есть generic зависимость на фабрику), связанные интерфейсы.

        Andrey Shchekin

        28 сентября 2010 at 18:13

        • Так это ж классы типов, а не JavaGI =)

          Правда при текущей версии VM это можно будет реализовать только через делегирование и неявные преобразования. А именно этим меня пугает scala.

          Rystsov Denis

          28 сентября 2010 at 18:45

        • Ну частично, как я понимаю, да, это type classes, но адаптированные к Java/C# (но это не только type classes). Я не обсуждаю реализцаю, т.к. версию CLR теперь менять не проблема, за счёт side-by-side CLR.

          Andrey Shchekin

          28 сентября 2010 at 19:27

  11. Я за упрощение синтаксиса для частых операций.

    Добавили LINQ в своё время — давайте теперь сделаем comprehensions какие-нибудь.
    Механизму вывода типов есть ещё куда расти.
    Аналог import static из жавы было бы, наверное, классно, но возможны последствия.

    А ещё надо как-то параллельность и прочую конкурентность на уровень языка внести… Но это будет уже другой язык.

    Maxim Moiseev

    28 сентября 2010 at 17:34

    • Я в свой время перешёл с VB.NET в т.ч. из-за отсутствия import static в C# (ну это не главная причина, понятно).

      Andrey Shchekin

      28 сентября 2010 at 17:37

      • Времена были другие. Я когда начал на C# писать, то прямо так радовался, что нет больше «висячих» функций. Всё чётко. А теперь вот опять… История развивается по спирали, говорят.

        Maxim Moiseev

        28 сентября 2010 at 17:39

        • Да, ну просто extension methods вроде как покрывают большую часть случаев, а с остальными хелперами чёрт разберёт потом откуда взялись все эти методы (и на самом деле статических хелперов у меня довольно мало оказывается, большинство через IoC).

          Andrey Shchekin

          28 сентября 2010 at 17:43

        • Да я вот и думаю, что от import static вреда больше чем пользы. Только вот одно не даёт покоя.
          Press(Key.Enter).Then.Wait(20) просто прикольнее выглядит, чем Helper.Press(…) ну и так далее.
          F# зараза… Развращает.

          Maxim Moiseev

          28 сентября 2010 at 17:54

        • Так на С# тоже можно так делать, не?

          Dmitri

          28 сентября 2010 at 17:56

        • Ну для этого скорее нужен with, как показывает опыт JavaScript (Event.Behavior, например). Но в любом случае это возможно, через extension methods или обычный fluent interface.

          Andrey Shchekin

          28 сентября 2010 at 18:02

        • А в чем вред, если не секрет?

          Vlad

          28 сентября 2010 at 20:58

        • Интеллисенс всегда поможет, точно также как и с var

          Андрей

          28 сентября 2010 at 20:05

        • Если честно, то, когда я писал о своем варианте, то, за кадром, подразумевал вариант Nemerle, и не знал, что в java уже есть import static.

          Насколько я понял из первой ссылки в гугле — в java import static работает per namespace. В то время как в Nemerle пример с using System.Console работает в конкретном файле (как и обычный) — и не засоряет другие файлы/пространства имен.

          На самом деле код упрощается, особенно для всяких хелперных классов. Отчасти помогают extension методы, но все равно — попробуйте написать длинную формулу с использованием методов из Math.

          В том же F# это будет выглядеть, в начале, примерно как

          let sin = Math.Sin

          Да и в примерах проще писать WriteLine :)

          Андрей

          29 сентября 2010 at 0:47

  12. О! Я придумал. Надо добавить в язык атомы Ерланговские а.к.а. символы из Руби и ЛИСПов. Ну вы поняли. Чтобы вместо магических строк ими пользоваться. Тут и рефлекшн вам, и NotifyPropertyChanged, и прочие биндинги…

    Maxim Moiseev

    28 сентября 2010 at 17:43

    • Они не менее магические, на само деле. Я пользовался, не вижу отличий от строк (писать чуть короче). Причина Ruby к C# не применима (immutability/interning).

      Andrey Shchekin

      28 сентября 2010 at 17:46

      • Говорят их сравнивать быстрее.

        Maxim Moiseev

        28 сентября 2010 at 17:50

      • Хм.. Это оказывается interning и есть. А почему не применима?

        Maxim Moiseev

        28 сентября 2010 at 17:56

        • Потому что C# уже решает этот вопрос для любых строк, вводить новый тип строк не обязательно. С другой стороны в C# нет gsub! и прочих «!» на строках.

          Andrey Shchekin

          28 сентября 2010 at 18:03

  13. Идея с алиасом для IEnumerable действительно хороша, много языков имеют встроенный неизменяемый тип для коллекций, в C# такого нет и, следовательно, язык не побуждает программиста к правильному коду. Например, я часто возвращаю List только из-за того что его быстрее набрать, чем IEnumerable, но затем мне нужно иметь ввиду когда можно изменять эту коллекцию, а когда нельзя.

    Правильная деинициализация кортежей необходима, если язык поддерживает кортежи, от C# я ожидаю:
    var (sex,death) = GetMeaningOf(life);

    yield из анонимных функций это безусловно правильно и скрытых опасностей в нем, кажется, не больше, чем в замыканиях. Правда я бы добавил возможность объявления функций внутри методов, например, запись
    def add(x, y) { return x + y; }
    где тип x, y выводиться по использованию ниже,
    мне кажется явно лучше
    var add = (int x, int y) => { return x+y; }

    Extension properties не очень желанная мной фича, но, наверное, полезная.

    Думаю, что контракты с run-time/compile-time проверкой более элегантно решают проблему, чем ввод нового типа NonNullable — меньше будет засоряться интерфейс, сохранится совместимость c предыдущей версией фреймворка.

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

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

    Все остальное вредно реализовывать на уровне языка, если C# будет поддерживать метапрограммирование, то эти предложения (сахар для dependency property, sequence-инициализация, цепочная проверка на null, приватные поля для свойств и yield foreach) можно включить в стандартную макро библиотеку.

    Повторю свой коммент на хабре, для меня критично

    Rystsov Denis

    28 сентября 2010 at 18:36

    • Насчет метапрограммирования — согласен. Бесполезно расширять язык если сам пользователь может его расширить.

      Dmitri

      28 сентября 2010 at 22:02

  14. По всей видимости Микрософт однажды «изобретет» Nemerle и назовет этот C#-X.0 — новым революционным языком.

    hc

    28 сентября 2010 at 20:01

    • Вполне возможно :)

      Dmitri

      28 сентября 2010 at 20:50

    • Боюсь, что этого так и не случится. Я уже потерял надежду.

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

      ФП полноценно в C# придет только когда из него уйдет Хейльсберг.

      Vlad

      28 сентября 2010 at 21:03

      • Так это и не нужно толком. Есть F# для всех кто фетишизирует ФП, а для LoB подходит то, что есть в F#. Да, понятное дело что есть очень много сложных страшных фич вроде Pulse & Wait которые не особо мэпятся на аутсорсинг, но мне, собственно, все равно — если кто-то недотягивает, что поделать. А конкретный юзкейс для ФП лично для себя очень сложно вычерпать. Я пытался — честно!

        Dmitri

        28 сентября 2010 at 21:20

  15. Исправьте, пожалуйста, «инкаспулировать» в конце.

    vissi

    28 сентября 2010 at 20:20

  16. Ну всё чуваки, с меня хватит. Я поглядывал в сторону дот нета, но теперь окончательно определился что буду пилить консервативную яву.
    Ну вас нахер братцы с вашими синтаксическими сахарами.

    stokito

    28 сентября 2010 at 20:58

    • Да мы и не заставляем. Только не пытайтесь убедить нас что у вас там в Java лучше — а то мы вам примомним properties, дженерики и еще вагон и маленькую тележку «непиленного консерватизма».

      To each his own…

      Dmitri

      28 сентября 2010 at 21:22

    • Полностью поддерживаю.

      Нафиг этот сахарок не нужен. Я жду того момента, когда C# просто разорвёт от фич. И они ещё говорят, что С++ сложен!

      Ява минимальна, и всем хорошо — и кодерам, и майнтейнерам, и ревьюерам. Ну а программисты пусть балуются плюшками из C# :)

      Dmtiry

      28 сентября 2010 at 22:19

    • «Нафиг синтаксический сахар» для меня звучит как «я хочу писать больше кода чтобы решить ту же самую задачу». В чём суть и польза этой идеи?

      Andrey Shchekin

      29 сентября 2010 at 0:04

      • Польза в том, что несмотря на обилие кода в нём проще разобраться. Когда то министерство обороны США объявило конкурс на создание языка для своих нужд. Победила Ада — прекрасный паскалеподобный язык. Но в нём тоже много сущностей, и это явно опасно.
        Другая крайность — слишком бедный язык, например тупо байт код.

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

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

        То как тут бойко обсуждаются какие то невнятные и ненужные вещи (я без них прекрасно обхожусь, да) мне показало основную тенденцию C# — впитывать всё нужное и ненужное.

        stokito

        20 октября 2010 at 14:55

        • По-моему, если синтаксический сахар прозрачен и интуитивен, то он нужен, если же он усложняет процесс понимания кода новичком (старики и так поймут), то он не продуман и возможно излишен.
          Взять хотя бы инициализацию полей класса инлайн (хоть это немного более чем сахар). Вполне интуитивно и даже более читабельно, чем инициализация в конструкторе.
          Или те же свойства. Намного более прозрачно, чем явное использование функций.
          По мне так лучше убрать дублируемый синтаксис типа инлайн делегат и ламбда. Зачем их двое. Насколько я понимаю они полностью дублируют друг друга. Или такие вещи как встроенные типы: . Вполне можно обойтись системным обозначением и меньше зарезервированных слов необходимо знать.
          Я бы ещё подчистил бы систему и язык от старого мусора. А то так можно до бесконечности возить за собой этот вагон и маленькую тележку. Конечно конвертор старого в новое необходим.

          Urrri

          20 октября 2010 at 16:37

        • Правильно!
          Зачем ведь обратная совместимость :)

          Aleksey Berezan

          20 октября 2010 at 20:25

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

          Urrri

          21 октября 2010 at 9:06

        • Конвертацию для систем, которые уже в продакшине, большинство делать не будут. Потому-что:
          1) после конвертации систему нужно будет перетестировать. А это требует дополнительных человеческих ресурсов(уж далеко не в усех есть авто-тесты);
          2) Понятно, что найденные баги после конвертации нужно будет исправлять, а потом тестировать фиксы.
          * Да, да, я понимаю, современные парсеры очень крутые и переконвертят все так, чтобы новых багов не появится. Да, это так. В идеальном мире. Или парсер должен обладать исскуственным интеллектом чтобы смочь предвитеть все подводные камни, что могут появится после переконвертации кода. Наверное, звучит неубедительно. Привожу пример, буквально на днях столкнулся. Сопровождал систему, которая уже давно в продакшине.
          В класе имеем поле и соотв. свойство:

          private string _name;
          public string Name
          {
          get{return _name;}
          set{_name=value;}
          }

          Поле используется только в свойстве. Хм… Ну так сделаем авто-проперти. Мелочь, но приятно.
          public string Name
          {
          get; set;
          }
          Сказано, сделано, скомпилено :) Для кейса, над которым я занимался, все работало отлично(а с чего бы ему не работать? :) ). Через несколько дней баг вылез совсем в другом месте системы. В том месте, где использовалась бинарная (де)сериализация инстансов этого класса(балы попытка десериализации ранне(до правки) сериализированих обьектов). Вот, а казалось бы, плёвое изменение…
          Ничего не имею против современных парсеров, но по-моему, парсер, который может учитывать подобные тонкости — это уже что-то из Азимова :)

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

          Aleksey Berezan

          21 октября 2010 at 16:49

  17. Лично меня очень сильно раздражает реализация перечислимых типов. Явное объявление поля _value в перечислимом типе это нечто, не говоря уже о том, что для базовых операций над экземпляром перечисления тяжело используется рефлексия. Разработчики .NET могли бы перевести реализацию перечислимых типов на обобщения уже в .NET 2.0, сделав базовый класс Enum. Но собственно реализация то реализацией, но каковы её последствия для разработчика:
    1. Невозможно использовать enum в качестве ограничения на тип специализации шаблонного класса или метода. Где это может пригодится, думаю очевидно.
    2. По причине 1 для Enum нельзя писать методы расширения. Правда можно для производных от Enum классов, т.е. для собственно конечных перечислимых типов. Но расширить функциональность сразу всех перечислений не выйдет.
    3. Вместо вызовов IsFlagSet, SetFlag, ResetFlag, ReadFlag, WriteFlag и т.д. (таких методов в классе Enum не существует, но, думаю, понятно что они должны делать) приходится повсеместно использовать громоздкие конструкции из операторов «==», «|», «~», «&». И по причине 1 и 2 нельзя реализовать методы расширения.

    Вот пример. В моём приложении тяжело используются DependencyProperty перечислимых типов. Было большое желание реализовать универсальный упаковщик перечислимых типов, в котором держались бы упакованные копии элементов перечислений, чтобы избежать созданий сотен тысяч промежуточных объектов, при работе с Binding’ами и значениями Dependency свойств. Т.е. реализация свойства должна была выглядеть как:

    MyEnum MyProperty
    {
    get { return (MyEnum)GetValue(MyPropertyPropery); }
    set { SetValue(MyPropertyProperty, value.Box()); }
    }

    Ну само собой по вышеназванным причинам не вышло :(

    Иван

    28 сентября 2010 at 21:15

  18. Синтактических сахар для dependency property, yield из анонимных функций, Правильная инициализация кортежей и Extension properties было бы неплохо. Всё остальное имхо не нужно.

    Ну и поделюсь своими идеями:
    1. Оператор `A`, который возвращает имя объекта A в виде строки (` — апостроф, а не одинарная кавычка). Пригодится, например, при реализации INotifyProperty + смена имени типа или метода при рефакторинге будет успешно обработана. Примеры:

    int IVar = 0;
    class ACls { public int F {get;set;} }

    `int` == «Int32», `ACls` == «ACls», `IVar` == «IVar», `ACls.F` == «F»

    2. Контракты данных. Описывает доступные операции над объектом.
    Пример:
    class A {
    public void M() {}
    public static A operator+ (A a, A b) { … }
    }

    class B {
    public void M() {}
    public void M2() {}
    public static B operator+ (B a, B b) { … }
    }

    теперь объявляем контракт:
    datacontract Ctr {
    void M();
    static Ctr operator+ (Ctr a, Ctr b);
    }

    После чего получаем следующие возможности:
    а) Некий аналог var
    A a1 = new A();
    A a2 = new A();
    Ctr ctr1 = new B();
    Ctr ctr2 = a1;
    Далее из ctr2 будет доступен метод M() и возможность сложить его с другим объектом: ctr2 + a2
    При этом во время компиляции произойдёт подстановка реальных типов, т.е. Ctr ctr2 = a1; будет заменено на A ctr2 = a1; со всеми вытекающими последствиями. Соответственно во время компиляции ctr1 + ctr2 приведёт к ошибке.

    б) Автоматическое обобщение методов:
    void Method(Ctr a) {…}
    Во время компиляции произойдёт дублирование методов под каждый из типов, т.е. если есть вызовы Method(new A()) и Method(new B()), то будет автоматически выведено 2 метода с именем Method, но разными типами.

    в) Использование в качестве ограничений на тип в шаблонах:
    class GenCls where T: Ctr {}
    Соответственно теперь при реализации GenCls будет доступен интерфейс Ctr на внутренние типы. Работать будет аналогично за счёт генерации нескольких классов с разными типами для T.

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

    Ilya

    28 сентября 2010 at 21:18

    • Фича 1 мне очень нравится, при условии что это значение статически компилируется как константа, а не является shorthand’ом для вызова злотсного reflection- или Expression-ориентированного куска кода.

      Dmitri

      28 сентября 2010 at 21:41

  19. Очень хотелось бы получить не как можно больше новых фич C#, а полноценную поддержку старых.
    Например, анонимные методы, lambda-expressions, linq — очень удобная вещь, но вот во время дебага проверить работу какого-либо выражения, вставив его в Watch, нельзя, и также нельзя во время дебага изменить код внутри анонимного метода да и метода, который его содержит. А ведь таким способом исправляется значительная часть мелких ошибок(типа +1/-1 в цыклах, методы для генерации строк и пр.), и перезапускать после каждой маленькой правки проект, который запускается 2-3 минуты(а потом часто еще и парольчик нужно ввести, перейти на нужную форму и т.д.), это еще то удовольствие :)
    Не поймите неправильно, я не против новых фич, более того, я даже за. Просто по причинам, указаным выше, многие фичи часто попросту не используются, вследствии чего и забываются. Вот часто так и получается, что серьезные приложения пишем на «pure» C#2.0(еммм, анонимные методы, ок, «almost pure») а на C#4.0 — хелло вордлы всякие.

    Alexey Berezan

    28 сентября 2010 at 23:21

    • Ну в этом я не соглашусь на 100% — даже если отладка где-то страдает, это не значит что на этом нельзя писать. Я не шучу! Посмотрите например на разработку в С++ без Intel Parallel Studio. А как насчет отсутсвия вменяемой 64-битной отладки в VS2008 и более ранних версиях? Да, это нехорошо, но мы все равно все это пишем, поставляем на этом решения.

      Dmitri

      28 сентября 2010 at 23:52

      • Никто ж не говорит что писать на этом нельзя, писать на этом нужно. Просто лично для меня полноценная отладка олд-скульного кода сохраняет намного больше времени и нервов нежели економия нескольких строк кода. Конечно, новые фичи С# я использую, но только в тех местах, где точно уверен, что отладку делать не буду, т.е. в относительно простых участков кода. А хотелось бы использовать их почаще.

        > Посмотрите например на разработку в С++ без Intel Parallel Studio.
        > А как насчет отсутсвия вменяемой 64-битной отладки в VS2008 и более ранних версиях?
        Спору нет, пишем, поставляем решения. Но ведь намного приятней когда разработка в С++ ведется С Intel Parallel Studio, VS2008 есть 64-я отладка, правильно?

        Alexey Berezan

        29 сентября 2010 at 1:39

        • * упс, извините, опечатался, хотел написать
          а в VS2008 есть 64-битная отладка,

          Alexey Berezan

          29 сентября 2010 at 1:45

        • Ну, mixed-mode отладка для 64-битных приложений не работает в VS2008

          Dmitri

          29 сентября 2010 at 8:18

    • » перезапускать после каждой маленькой правки проект, который запускается 2-3 минуты(а потом часто еще и парольчик нужно ввести, перейти на нужную форму и т.д.), это еще то удовольствие :)»

      Эээээ а юнит-тесты?

      Andrey Shchekin

      29 сентября 2010 at 0:22

      • А не всегда в проекте есть юнит-тесты. А в большых проектах с legacy кодом юнит тесты написать еще и очень проблематично, если реально вообще.

        Alexey Berezan

        29 сентября 2010 at 1:25

        • Ну как бы тесты это первый шаг перед изменениями в любых проектах (не знаю, есть ли это в книжке про legacy code, но должно быть). Хотя интеграционные вместо юнит тоже ок.

          Кстати, на legacy code написать юнит тесты абсолютно реально с помощью Moles или TypeMock.

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

          Andrey Shchekin

          29 сентября 2010 at 1:41

        • Ну, все равно бы еще чуток поспорил, да чуствую и так уже в оффтоп зашли :) Так что пожалуй на этом и остановимся.

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

          Alexey Berezan

          29 сентября 2010 at 2:13

  20. Чего бы я хотел видеть в следующей версии C#
    1)managed компилятор, compiler as service, объектную модель компилятора и желательно полегче, чем CCI
    2)Полное квази-цитирование, чтобы по любому коду C# строилось expression tree. Желательно еще добавить механизмы для сплайсинга.
    3)Поддержку языком кортежей
    4)Паттерн-матчинг (маловероятно, но все же)
    5)Глобальный вывод типов

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

    Стас

    29 сентября 2010 at 0:03

    • Все будет так (пожалуй, кроме глобального вывода типов), и даже больше, но в Nemerle 2.0. :)

      hc

      29 сентября 2010 at 0:47

      • Вспомнилась сцена из фильма «Спиздили», когда Ави прилетает из США в Лондон.
        Действующие лица Ави (А) и Даг (Д).
        А — Я очень не люблю выбираться из своей страны, особенно когда выбираюсь не на песчаные пляжи, где все ходят в бикини и подтаскивают мне коктейли
        Д — Но у нас есть песчаные пляжи…
        А — И кому нах** они нужны?

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

        Кроме того, несмотря на продолжительное существование, не было написано ни одного killerapp на этом языке.

        Стас

        29 сентября 2010 at 1:18

        • Это, конечно, флейм уже, наверное, но можно несколько примеров несогласованности на вскидку? Чего не хватает до того, чтобы являться функциональном языком, по сравнению с F#? Понятие юзабельности размытое, разве конструкция из C# «var foo = new Dictionary()» более юзабельна, чем «def foo = Dictionary()» из немерле; но это мелочи, по сравнению с (в C#) запуска внешней тулы для генерации парсера по грамматике, когда в немерле грамматику можно описать в атрибуте и дело сделано.

          Проекты на Nemerle есть, но в основном внутренние. Из крупных — сам компилятор. Могу привести в пример еще http://uniquation.com это еще не killer app, но уникальная разработка.

          Rystsov Denis

          29 сентября 2010 at 1:45

        • Как минимум не хватает карраинга, first-class operators, монадного синтаксиса (хотя вроде ко второй версии что-то прикрутили), глобального вывода типов, лакончиности записи.

          Это все можно сказать просто глядя на исходники на Nemerle, даже не писать ни строчки. Если начинать писать, то можно еще много чего найти.

          Стас

          29 сентября 2010 at 7:31

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

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

          Сurrying:
          def f(a,b) { a + b }
          def g = f(2,_);
          WriteLine(g(1));

          Operator as a first class object:
          def z = [1,2,3].Fold(0, _+_);
          WriteLine(z);

          Вывод типов работает внутри методов, уровнем выше он не нужен, так как декларация типа в интерфейсе является контрактом.

          Rystsov Denis

          29 сентября 2010 at 11:30

        • Этого и следовало ожидать. Очередной бред сивой кобыли вместо аргументов.

          Все кроме отсутствие глобального вывода типов абсолютнейшая чушь. Аргументы тут уже привели, так что не буду повторяться. Скажу только про мнимую «лаконичность». Начнем с того, что к указанным выше «недостаткам» (в кавычках, так как они высосаны из пальца) вообще никаким образом никакого отношения не имеют. Ну, а закончим тем, что вот уже 6 лет вот здесь:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/raytracer/
          лежит примеры реализации raytracer-а на ML, C# и Nemerle демонстрирующие ту самую лаконичность.
          Не трудно заметить, что минимальный пример на Nemerle практически идентичен по длине минимальному примеру на C#:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/raytracer/ray2.ml
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/raytracer/ray.n
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/raytracer/ray-cs.cs

          Так что продолжайте дискредитировать себя и дальше делая заявления не соответствующие действительности.

          Vlad

          29 сентября 2010 at 12:32

        • > Nemerle практически идентичен по длине минимальному примеру на C#

          Опечатался. Имелось в виду «идентичен по длине минимальному примеру на ML». Пример C#, конечно же намного длиннее.

          Кроме того, не надо забывать, что Вы Стас говорили о включении фич в C#:
          «Чего бы я хотел видеть в следующей версии C#
          1)managed компилятор, compiler as service, объектную модель компилятора и желательно полегче, чем CCI
          2)Полное квази-цитирование, чтобы по любому коду C# строилось expression tree. Желательно еще добавить механизмы для сплайсинга.
          3)Поддержку языком кортежей
          4)Паттерн-матчинг (маловероятно, но все же)
          5)Глобальный вывод типов»

          Уж что, что, а Nemerle в любом виде лаконичнее C#-а. Так что кроме как попыткой сменить тему обсуждения ваши кивки на лаконичность назвать нельзя.

          Так что остается только еще раз повторить, что Вы ждете какого-то мифического счастья в будущем, в то время когда почти все, что вы ожидаете уже давно есть.
          Ну, а про глобальный вывод типов тут уже верно заметили. На уровне тел членов вывод типов есть и он даже значительно лучше чем в F# (про C# даже говорить не приходится), а на глобальном уровне он даже вреден, так как контракты нужно выражать явно.

          Vlad

          29 сентября 2010 at 12:48

        • Стас. Без обид, но единственное адекватная мысль в твоем сообщении — это замечание о том, что девелоперов у Nemerle мало.

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

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

          Скажем Nemerle on rails (аналог Ruby on rails), но в статически типизированном языке и с поддержкой LINQ-а потянет на эту роль?

          Или скажем генератор парсеров «шаговой доступности» — PegGrammar, который использовать так же просто как регекспы (так как он реализован в виде макроса), но при этом работающий со скоростью близкой к рукописным парсерам и позволяющим разбирать грамматики самых сложных для разбора компьютерных языко?

          А что за killerapp созданы на F#-е?

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

          Если я ошибаюсь, то с радостью послушаю конструктивный рассказ о «несогласованностях», о том почему «Nemerle никак не является функциональным языком», о том почему «не может тягаться с даже F#» и в особенности о том почему именно «даже» (что F# такой плохой язык?). Ну, и конечно же очень интересен рассказ о том в чем заключается «никак по юзабельности не дотягивает до C#». А то те кто этот язык пробовали почему-то потом постоянно плюются пытаясь писать на C# по той же самой причине но с точностью до наоборот.

          Vlad

          29 сентября 2010 at 2:01

        • Точно, я еще забыл упоминуть отношение разработчиков к какой-либо критике. Сразу объявляется «полным гоном» или «вот тебе макросы, сделай сам»

          Для F# killerapp давно существует и называется F# Web Tools.

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

          Стас

          29 сентября 2010 at 7:38

        • Хотя бы одна статья — http://habrahabr.ru/blogs/nemerle/104968/ Код оттуда живой и работает в http://uniquation.com

          Rystsov Denis

          29 сентября 2010 at 11:18

        • > Точно, я еще забыл упоминуть отношение разработчиков к какой-либо критике.

          Стас, помилуйте! Не надо этой демагогии. Критике мы только рады. Но критика должна содержать достоверные факты, а не основываться на лжи и выдумках, как ваши суждения. Тогда от нее есть толк.

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

          Например, как-то на форум зашел некий dsorokin и заявил, что дескать, на его взгляд F# лучше чем Nemerle, так как в первом есть ComputationExpressions. Ему резонно заметили, что встраивать такую штуку в язык при наличии макросов не имеет никакого смысла, и что ComputationExpressions можно реализовать самостоятельно в виде макроса.

          В отличии от Вас dsorokin не обиделся на эти слова, а взял и опробовал реализовать такой макрос. В результате у него получилась реализация которая сейчас доступна в snippets/ComputationExpressions репозитория немерла.

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

          > Для F# killerapp давно существует и называется F# Web Tools.

          Помилуйте! Это же неуловимый Джо. Неуловимый потому что его на фиг не нужно никому ловить. К тому же проект явно не развивается уже несколько месяцев и это при том, что релиза так и не было.

          Для Немерла тоже есть похожая разработка называется Nemerle on rails. Очень приятный фрэймворк созданный в рекордные строка. Код доступен на гугкоде. Легко гуглится.

          > PegParser может и существует, но увидеть бы хоть одну статью с примером его использования.

          Примеров использования хватает. Тот же парсер C# 4.0 доступен здесь:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/CSharp/
          Более простые примеры:
          Простой строчный калькулятор:
          http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Calculator/
          JSParser http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/JSParser/

          Vlad

          29 сентября 2010 at 13:20

        • >Например, как-то на форум зашел некий dsorokin и заявил, что дескать, на его взгляд F# лучше чем Nemerle, так как в первом есть ComputationExpressions. Ему резонно заметили, что встраивать такую штуку в язык при наличии макросов не имеет никакого смысла, и что ComputationExpressions можно реализовать самостоятельно в виде макроса.

          Только в итоге оно было реализовано через дополнительные ключевые слова, что не есть гуд.

          Стас

          29 сентября 2010 at 16:09

        • Покажите мне другой язык где это вообще возможно?!
          В том же F# пришлось править код компилятора.

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

          Так что серьезно сравнивать Немерл можно толко с Лиспом.

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

          Во второй версии немерла, работа над которой начнется в ближайшее время (а точнее уже потихонечку уже ведется, так как PegGrammar — это по сути прототип новой макро-системы), можно будет вводить практически любые синтаксические расширения. Единственное ограничение они должны хоть как-то отличаться от синтаксиса, что уже использован для других возможностей.

          Vlad

          29 сентября 2010 at 17:21

        • Кстати, в F# точно так же было введены дополнительные ключевые слова let! и return.

          Vlad

          5 октября 2010 at 0:39

        • Ну, и конечно же очень интересен рассказ о том в чем заключается «никак по юзабельности не дотягивает до C#». А то те кто этот язык пробовали почему-то потом постоянно плюются пытаясь писать на C# по той же самой причине но с точностью до наоборот.

          Вот у меня почему-то «не срослось», хотя честно пробовал. Мне кажется что даже тот же Boo, который я (и не только я) реально использовал (даже Айенде книжку накатал) как-то лучше «продан», что ли, чем Nemerle. Ну и синтаксис — дело конечно наживное, но я беру Boo и там практически все понятно, синтаксис знакомый. А вот Nemerle, как и F# например, нужно целенаправленно изучать.

          Dmitri

          29 сентября 2010 at 8:23

        • Забавно, если поменять местами Nemerle и Boo, то высказывание станет верно для меня)

          Синтаксис F# действительно немного пугает, а Boo мне показался реинкарнацией Python для .Net, из них троих, c синтаксической точки зрения Nemerle — почти C#, только типы нужно не перед переменной/методом писать, а после.

          Rystsov Denis

          29 сентября 2010 at 11:14

        • Осмелюсь предположить, что до этого Вы хорошо знали Питон. Потому у Вас все так хорошо прошло с Бу.

          Что до Немерла, то как я понимаю, вы не осилили варианты (которых попросту нет в Бу). Иначе, при наличии опыта программирования на C# освоение немерла не составило бы труда.

          Как я уже говорил, имеет смысл сделать вторую попытку прочитав «Язык Nemerle» ссылки на который я приводил выше.

          Кстати, макросистема Бу позаимствована у Немерла.

          Vlad

          29 сентября 2010 at 13:25

      • Почему в 2.0 то?

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

        Vlad

        29 сентября 2010 at 2:06

  21. Собственно большая часть предложенного уже давно реализовано в Nemerle. Так что не ясно, что сидеть и ждать милости от «природы» когда их можно получить уже сейчас, здесь и совершенно бесплатно.

    Вот, например, использование макроса упрощающего работу с dependency property:
    http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.WPF/Test/Main.n
    а вот его реализация:
    http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.WPF/Nemerle.WPF/DependencyProperty.n

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

    Vlad

    29 сентября 2010 at 0:52

  22. Ухты. Не знал о Lazy. У меня давно есть свой InVal.Lazy для подобных целей.

    Smth?.Address?.PostCode — это круто и очень желаемо

    Также желанно
    1) создавать собственные (нечитабельные ;) ) операторы |> ||> [->] — на вкус пользователя
    2) разрешить define с параметром
    Две эти фичи могут быть источниками ошибок — (но иногда без них очень плохо) — поэтому пусть исспольнование их нужно включать в Properties наподобие unsafe.

    .Net Framework фичи:
    1) Управлять, кто первый среди WeakReference уйдет

    Богдан

    29 сентября 2010 at 1:12

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

    line771

    29 сентября 2010 at 1:43

    • А что плохого в том, что предлагаемые фичи заимствуются из других языков?

      Заимствование возможностей — это нормальный процесс. Есть только 2-3 языка в которых фичи придуманы с нуля. В остальных — это развитие идей взятых из других языков.

      В том же C# нет ни одной новой идеи. Все заимствовано. Даже LINQ имеет прототип — Haskell DB.

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

      Vlad

      29 сентября 2010 at 17:28

  24. Вобщем, я так понял, все согласны с тем, что с C# надо завязывать, а то будет новый С++.
    А тем временем кто-нибудь разработает новый язык, который будет содержать все плюшки и даже больше. Правда, есть предположение, что лет через 5 и этого будет мало. И вот тогда мы снова встретимся где-нибудь в коментах =)

    Maxim Moiseev

    29 сентября 2010 at 8:02

    • Ну это еще не гарантия того, что его будут использовать. Посмотри например на Google Go.

      Dmitri

      29 сентября 2010 at 8:19

      • А что с Go?

        Это экспериментальный язык который только-только появился на свет. Его судьба пока неизвестна. Но то что за ним стоит мощная компания — Гугль — говорит о том, что язык может и выжить.

        Vlad

        29 сентября 2010 at 17:30

  25. Я не фанат ФП, хотел бы такого сахара:
    1. Нормальные Extension method (ref/out/static classes) + extension properties
    2. Сделать что-нибудь с замыканием в foreach
    3. var в полях
    4. yield return из анонимных функций
    5. constraint на отдельные функции и операторы

    qst

    29 сентября 2010 at 8:09

  26. скажу честно, что при создании крупных учетных систем самым главным являлось — удачное проектирование всей системы и модулей в частности. а именно, простыми словами:
    — модель абстрактного хранилища, отвязанного от конкретной реализации СУБД;
    — выделенный исполнитель бизнес-логики, отвязанный от отображения и конкретной реализации СУБД, с построением объектов и обвязыванием их поведением;
    — гибкая система генерации и кастомизации интерфейсов (вэб или окна, или даже консоль, не важно)
    И такие подробности, как всяческие фичи в языках — капля в море по затратности и рискам получения гибкой и масштабируемой системы. Что есть фичи, что нет, это ни чего не меняет. При грамотной организации всех видов работ, постоянном активно контроле и тестировании — ни каие фичи не нужны. Я это испытал уже более чем за 15 лет. Ну вот вообще ни как они не нужны и ни чем не помогают в вопросах достижения глобальных целей, как бы не ныли и не гундосили программисты.
    Более того скажу — чем больше фич, тем:
    — дольше работают программисты
    — больше зависимость от программиста
    — дороже они стоят
    — больше рисков от качества фич
    Я иногда удивляюсь, почему в России так много программируют, почему так часто переписывают системы, почему так много гениально талантливых программистов копаются в фичах…

    system_builder

    29 сентября 2010 at 11:12

    • Это всё вообще не про то. Конечно для менеджера проекта важнее нормально налаженный цикл тестирования, чем сокращение для IEnumerable. Конечно, высокоуровневая архитектура тоже важна. Но это не тот уровень.

      Простой пример: можно сделать модель абстрактного хранилища без LINQ, но это дольше и дороже.

      В таинственное мнение, что при большем кол-ве фич программисты работают медленнее (в каких единицах? кто это вообще мерял?), я не верю.

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

      Andrey Shchekin

      29 сентября 2010 at 11:23

    • Более того, для автора этого поста и для многих комментаторов архитектура на том уровне, о котором вы говорите, это дело само собой разумеещееся.

      Конечно, можно нанять быстрых и дешёвых людей, не слушать что они там «ноют», и сделать тесты и контроль за качеством кода (например, посадить архитектора делать code review). Видел таких заказчиков тоже. Но результат будет либо очень дорогим (архитектор проверил, сказал всё перереписать, и так много раз), либо с трудом поддерживаемым в будущем.

      Andrey Shchekin

      29 сентября 2010 at 11:31

      • Во первых, мелкосфт делает фишки, которые вас привлекают — это главное для них! Наивно предполагать, что это не основная их цель. Именно поэтому вы в последствии так много тратите времени на изучения, так часто обсуждаете проблемы, и так долго изворачиваетесь, чтобы используя предложенный инструмент сделать что-то серьезное. Не успев закончит обсуждение, «у вас в почте» новая реклама от мелкософт, о новых фичах в С# под названием «для ленивых».
        Во вторых. То, что у вас так случалось «архитектор сказал все переписать» — это именно то, о чем я и говорю — некачественная организация работ, по большей части потому, что менеджеры проектов и архитекторы имеют очень высоко задранный нос, и торчат на таких форумах или вообще неизвестно где торчат. Контроль исполнения работ участниками должен быть очень активным. Программист должен получать задачи, которые он сможет решить не более чем за 1-2 часа, или результаты этапов работ можно было бы проверить с такой частотой. Архитектор — тот же инженер, что и программист, хотя его задачи не всегда можно разделить на этапы или с большей вероятностью оценить риски. Но его так же необходимо проверять и контролировать, чтобы было понятно, туда ли он движется. И надо бы проводить предпроектные исследования и тесты, чтобы снизить риски такого исхода — «архитектор сказал — все надо переписать».
        Вы таки предлагаете сидеть копаться в фичах?

        system_builder

        30 сентября 2010 at 9:37

    • Как по мне так программисты работают как раз меньше. Другое дело что если систему написали «крутаны» а на саппорт вы поставили «динозавров» которые боятся слова лямбда и не знают что такое метод расширения — то тогда вы возможно и заслужили такие проблемы.

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

      Dmitri

      29 сентября 2010 at 12:17

      • В чем-то я конечно с вами согласен. Но это не обязательно верно сажать на саппорт программистов. Все опять же зависит от компании.
        Если это научные исследования в, как вы сказали, «маленькая консалтинговая компания которая не разгребает авгиевы конюшни а занимается интересными, прогрессивными вещами», то наверное наука ради науки — это полезно для будущих качественных скачков в этой области. Где-то так лет через 50. Но пока что видны мягкие и незначительные эволюционные поползновения на протяжении десятков лет. Я говорю с точки зрения полезности практиков, работающих в отрасли. И это понятно, область то новая — разработка алгоритмов и внедрение их в исполнительную систему — например, персональный компьютер. Пока ни чего особого в отличиях нет среди самых разноцветных языков и концепций в изложении задач исполнительной системе. А именно это определяет глобальные затраты и стимулирует цели. И разговоры о фичах по мне так — копание в песочнице. Я ни кого не заставлю иметь такое же мнение. Просто и мне, как кроме всего еще и практикующему программисту, вполне достаточно концептуальных новшеств в новых средах разработке.

        system_builder

        29 сентября 2010 at 12:27

  27. Некоторые из них можно реализовать препроцессором, наверняка.

    Стас Агарков

    29 сентября 2010 at 22:45

  28. Некоторые фичи интересны, но пожайлуста — не надо из стройного и типизированного C# делать делфи-скриптообразное Г…! сенкс

    C# Dev

    30 сентября 2010 at 2:12

    • Вот отличное замечание! Я даже побоялся написать такое, потому, что предполагал, что на меня обрушится шквал Г… людей с таким менталитетом: «а я хАчу чтобА звездАчка писалась до АпиратАра, и чтобА мышАй меньшИ двигать»юю и ете же авторы дальше: «… потому что это это согласуется с современно модой в ИТ отрасли, особенно на ландшафтах интеграционных проектов и с активным развитием функционального программирования и идеологии префиксного изложения».
      И побоялся потому, что автора забросали таки Г…ом, когда он отметил, что больше бы надо заниматься повышением качеств уже созданных фич, их большей интеграцией и развитием, чем замусориванием языка «элементами для лентяев», попытался предложить улучшить возможности по дэбаггингу, трассировке и тестированию фич, и его опять обГ..нили…

      system_builder

      30 сентября 2010 at 9:26

      • Да не нервничайте вы так! Этот топик сам по себе флеймовый, поэтому естественно что тут много людей и много мнений.

        Dmitri

        30 сентября 2010 at 10:41

        • ну таки плохо то, что мОлодежжжь впитывает не лучшие практики, не лучший подход к делу…
          это как осам халявный мед, или наркоманам халявные наркотики. только покажи — слетаются и маньячат «на тему»… а они составляют определенную часть отрасли, и они могут своими настроениями и пожеланиями повлиять на развитие других.. и так это может стать необратимым лавинообразным процессом расщепления :)))) («не дай бог»)
          взять только некоторые новшества в C# 4, которые приводят к расхолаживанию и потере строгости языка… интересно, что было бы с математикой, если бы там вот такой бред творился.. но там с этим сложно, там всегда требуются доказательства и обоснования, там труд, а здесь — маркетинг, «заманилово» лентяев, затягивание в болото….

          system_builder

          30 сентября 2010 at 10:49

  29. Я пропустил или упоминания о итераторах не было? :)

    Andrey

    30 сентября 2010 at 6:55

  30. да… фичи, перефичи…
    вот бы всех этих айтишников заселить на отдельную территорию, где голые степи и леса, скинуть им строительных материалов в большом количестве и строительной техники, и сказать — что и когда построите, в том и тогда и будете жить!
    вот это будет РЖАЧКА!!!

    system_builder

    30 сентября 2010 at 10:54

    • Не очень сравнение. Равно как строителям дать компы и поглядеть как они … Кстати, вы в новых домах квартиры видели :)

      Я вот только в одном согласен — не надо из C# делать этакий супер PHP с читабельностью RegExp. Причем у меня складывается ощущение что в жертву фичам приносится производительность.

      Andrey

      30 сентября 2010 at 11:39

      • Извините, не совсем точно выразил мысль. Забыл добавить — «если бы программисты были строителями и строили дома…»
        Вот быстренько нашел то, что читал когда то.
        http://mshakurov.narod.ru/IT_Compatible.html
        Развлекитесь.

        system_builder

        30 сентября 2010 at 12:51

        • Да я понял что про этот прикол речь :) Просто все равно — криво. А тут серьезный флейм :) :) :)

          Andrey

          30 сентября 2010 at 14:47

  31. Про сахар рассказали, а про самое главное, метапрограммирование — нет.

    xna

    1 октября 2010 at 15:22

    • А что там рассказывать? Сказали же «Компилятор как сервис». Это значит, что вы сможете взять компилятор и делать с ним что захотите. :)

      А метапрограммирования, как и сахара не будет.

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

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

      Vlad

      1 октября 2010 at 16:56

      • «Компилятор как сервис» и «метапрограммирования не будет» — взаимоисключающие явления.

        xna

        4 октября 2010 at 13:05

        • Да нет, пожалуйста, вот в Mono уже compiler-as-service, если можно так сказать. А метапрограммирование — совсем другого уровня штука, чем написать свой компилер/препроцессор.

          Есть ещё VS, есть ещё необходимость этот компилятор вручную поддерживать, etc.

          Andrey Shchekin

          4 октября 2010 at 19:26

        • Если воображение очень сильное, то можно утверждать, что метапрограммирование было всгеда и есть сейчас, так как всегда моджно сгенерировать код в текстовый файл и скомпилировать этот файл.

          Тот же T4 есть, так что генерировать код не так уж и тяжело получается.

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

          «Компилятор как сервис» упростит возможность компиляции кода в рантайме, но тех возможностей что есть, скажем в Nemerle или Lisp-е он не даст. А без этого продуктивной работы небудет.

          В Nemerle и Lisp-е можно сварганить внутренний DSL и элегантно решить проблему. А вот компилятор-компонет (а именно это пока что подразумевается за красивым слоганом «Компилятор как сервис») этой гибкости и легкости не даст.

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

          Vlad

          5 октября 2010 at 0:26

  32. […] комментариев в блоге и вот, пожалуйста, флейм. Тема: "Возможные фичи C# 5". Чуть позже Майкла Хэр (Michael Hare) поделился своим […]

  33. Хорошая тема поднята!

    Calabonga

    5 октября 2010 at 0:11

  34. Инлайн инициализация автоматических свойств, подобно инициализации полей. Например:

    string Name { get; set; } = «Urrri»;

    string Name { get; set; value=»Urrri» }

    Urrri

    5 октября 2010 at 21:43

  35. Extension properties

    про них писал Эрик Липперт, поечму от них отказались. ДАлеко не факт что снова решат вернуться

    Andrei Kapytau

    7 октября 2010 at 23:04

  36. а яб добавил кроме T! еще и T% значение задается только однажды и не может быть изменено.

    Naugad

    9 октября 2010 at 1:01

  37. Скорее к .NET чем к C#:
    1. INumeric interface for standard numeric types.
    struct UInt32: INumeric
    {

    }
    2. Discriminated unions:
    union MyUnion: Enum
    {
    case Enum.Red: RedClass;
    case Enum.Green: GreenClass;

    }
    3. Fixed size arrays
    byte[10] x;

    Sergey Shandar

    11 апреля 2011 at 15:41

  38. Только «Синтакcический сахар для dependency property» зацепило. Здорово будет конечно, если реализуют. Всё остальное ни о чем.

    Oleg

    19 апреля 2011 at 14:53


Оставить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: