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

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

Нужно ли полиглотное программирование в стеке .Net?

54 комментария

Из комментариев к коротенькому посту на Хабре про использование Python как базового языка для Asp.Net мне понравился вот этот комментарий от centur:

Ну собственно повторный вопрос — зачем?
Дмитрий Нестерук высказал вполне здравую мысль — зачем нужна вся эта куча языков, если есть так активно развиваемый C#.
В общем возможность мульти-языкастости среды это клево, но вот потенциальная поддержка этого — один из кругов ада =)

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

F#

Давайте прокинем VB и начнем с языка №2 который уже является полноправным жителем нашей .Net экосистемы. Да, интересный, функциональный язык. А теперь внимание вопрос: в чем собственно его приемущества, какой конкретно от него business value?

Вот я написал несколько проектов либо полностью на F# либо частично. У меня была возможность попробовать такие “рекламируемые” фичи как async workflows и повсеместное отсутствие мутабельности. И вот к каким выводам я пришел:

  • Бизнес-программирование по большому счету мутабельное, тем самым язык который вставляет вам 100 палок в каждое колесо при попытке изменить переменную для него слабо подходит. Чего стоит например вот такое определение:
    let context : Ref<IVisitable option> = ref None
    
  • Async workflows – это всего лишь кастомная издевка над синтаксисом. Это хак. Такой же хак есть и в .Net с использованием AsyncEnumerator (PowerThreading). Ничего “гениального” в этом нет, работу это не упрощает. Вот вам прямое сравнение двух подходов – выводы делайте сами:

    F#

    let private DownloadPage(url:string) =
      async {
        try
          let r = WebRequest.Create(url)
          let! resp = r.GetResponseAsync() // let! позволяет дождаться результата
          use stream = resp.GetResponseStream()
          use reader = new StreamReader(stream)
          let html = reader.ReadToEnd()
          use fs = new FileStream(@"c:\temp\file.htm", FileMode.Create,
                                  FileAccess.Write, FileShare.None, 1024, true);
          let bytes = Encoding.UTF8.GetBytes(html);
          do! fs.AsyncWrite(bytes, 0, bytes.Length) // ждем пока все запишется
        with
          | :? WebException -> ()
      }
    // вызов ниже делает синхронный вызов метода, но поведение внутри метода - асинхронное
    Async.RunSynchronously(DownloadPage("http://habrahabr.ru"))
    

    C#

    public IEnumerator<int> DownloadPage(string url, AsyncEnumerator ae)
    {
      var wr = WebRequest.Create(url);
      wr.BeginGetResponse(ae.End(), null);
      yield return 1;
      var resp = wr.EndGetResponse(ae.DequeueAsyncResult());
      var stream = resp.GetResponseStream();
      var reader = new StreamReader(stream);
      string html = reader.ReadToEnd();
      using (var fs = new FileStream(@"c:\temp\file.htm", FileMode.Create,
                          FileAccess.Write, FileShare.None, 1024, true))
      {
        var bytes = Encoding.UTF8.GetBytes(html);
        fs.BeginWrite(bytes, 0, bytes.Length, ae.End(), null);
        yield return 1;
        fs.EndWrite(ae.DequeueAsyncResult());
      }
    }
    
  • Метапрограммирование в F# неполноценно. То, что там есть цитирование, еще ничего не значит, т.к. нам хочется не транслировать F# в какой-то там язык, мы хотим то цитирование и “сплайс” которыми мы можем помочь компилятору сгенерировать некие структуры в процессе компиляции. Настоящее статическое метапрограммирование есть пока что только в Boo, но оно будет в C#.
  • Создание DSLей – да, оно проще. Если интересно – вот моя статья. Только DSLи – это пока направление которое в основном, во-первых, для internal use, а во-вторых только для продвинутых фирм вроде моей. Точно не для общего пользования. Не верите? Let me google that for you.
  • Идея о том, что F# лучше чем C# для сложного алгоритмического программирования в финансовых и аналогичных индустриях не раскрыта. Да, его используют. Детальных case studies мало, и опять же, никто толком не может объяснить почему. И вообще, какая разница, во что транслировать формулы?

Есть еще нарекания в плане “общей вменяемости” – например набор всяких <@ @>, <@@ @@>, [], [| |], {}, (|x|_|), ->, <-, >>, :>, :?>, |> это же просто бред какой-то! Это “магические операторы”, иначе не назвать.

Вообщем, я действительно хочу использовать F#, но когда я реально начинаю его использовать, то каждая из фич которая изначально кажется selling point языка оказывается неповоротливой и непрактичной. Например, я надеялся что pattern matching поможет мне структурировать разбор строк вот в этом проекте. На самом же деле, код получился практически нечитабельным. Где тут maintainability? Правильно – ее нет в помине.

Boo

Я конечно понимаю что товарищ Айенде, будучи “впереди планеты всей” в плане работы с базами данных, решил поделиться своими замечаниями на тему того, как метапрограммирование на языке Boo может принести реальный business value. Проблема в том, что книжка у него отровенно не удалась, и тем самым аргумент как бы затух.

Идея Boo в том, что у вас есть якобы более лаконичный синтаксис (а-ля Python) плюс возможности расширения компилятора которые делают возможным мета-изыски которых мы затаив дыхание ждем в C#. Ну так что, давайте обсудим эти два “бенефита” на предмет их полезности.

Вообще, идея того что Питон чем-то “лаконичней” чем C# или какой-то там другой язык – это попытка продать абстрактное “нечто”, не подкрепляя это толком никакими аргументами. Возьмем например произвольный кусок кода из проекта:

class ManaIndicatorsAttribute(AbstractAstAttribute):   
  public override def Apply(node as Node):
    c = node as ClassDefinition
    for i in range(ManaSumAttribute.LandTypes.Count):
      basic = ManaSumAttribute.LandTypes[i] as string
      hybridLands as List = []
      for j in range(HybridManaAttribute.HybridLandTypes.Count):
        hybrid = HybridManaAttribute.HybridLandTypes[j] as string
        if (hybrid.Contains(basic)):
          hybridLands.Add(hybrid)
      rbasic = ReferenceExpression(basic.ToLower())
      b = Block();
      b1 = [| return true if $rbasic > 0 |]
      b.Statements.Add(b1)
      for k in range(hybridLands.Count):
        rhybrid = ReferenceExpression((hybridLands[k] as string).ToLower())
        b2 = [| return true if $rhybrid > 0 |]
        b.Statements.Add(b2)
      r = [|
        $("Is" + basic):
          get:
            $b;
      |]
      c.Members.Add(r)

Ну-с, и где тут ‘лаконичность’? На практике получается жесткий, слабочитаемый код, в котором не спасает вывод типов, в котором записи вроде return x if y добавляют только дополнительную степень неоднозначиности, а вы бы видели IL который сгенерирован – у меня при виде того как код на Boo разворачивается в код на C# с помощью Рефлектора глаза на лоб лезут – такое впечатление что этому языку просто плевать на стэк. Поэтому простое суммирование пяти переменных переведенное в C# вернется вам не как a + b + c + d + e а скорее как ((((a + b) + c) + d) + e).

Насчет вещей, аналогичных LINQ. Да, действительно, до Linq в Питоне был козырь в плане разбора списков и прочих, т.е. можно было написать list[1,-1] или например подобное:

List(y for y in (x**2 for x in range(10)) if y % 3 != 0)

Теперь это неактуально т.к. в том же C# можно сделать то же самое, причем с поддержкой IntelliSense и без необходимости запоминать всякие range() (какая разница с Enumerable.Range()? меньше букв?) и прочие названия. Приемущество Linq в том, что это унифицированный API, который выглядит одинаково вне зависимости от того, используете ли вы Linq to Objects, Linq to Events (Rx) или Linq to CepStream (StreamInsight). Тут в основном одни и те же ключевые слова, плюс IntelliSense если вы что-то забыли.

Генераторы… ах, генераторы, идея-то хорошая, но вот скажите мне, что делает следующий кусочек кода:

def TestGenerator():
  i = 1
  yield i
  for x in range(10):
    i *= 2
    yield i

Утипизация? Тем кому она нужна уже имеют ее в C# с помощью таких библиотек как LinFu. Регулярные выражения через /? Ну что ж, может это и удобней, но лично мне все равно, т.к. я использую приложение, которое решает за меня все эти проблемы (хотя соглашусь, что конверсия в C#-строку выглядит коряво). Что остается?

Остается пожалуй только метапрограммирование. Это, на данный момент, единственный козырь в языке который, как мы с коллегами считаем, умрет сразу же после выхода C#5. И если вы считаете что метапрограммивание нужно сегодня и нужно срочно использовать Boo, вот вам несколько контр-аргументов:

  • Язык и инструментарий не развиваются. BooLangStudio мертва. Документация на сайтах частично устарела.
  • Использовать две IDE достаточно напряжно. Я имею ввиду, что вам придется компилировать Boo через SharpDevelop, а потом импортировать сборки в ваши C# проекты. Никакого configuration management рядом не стояло.
  • Компилятор сырой, и у меня были мета-методы которые вообще не сходились, т.е. программа компилировалась в невалидный IL. Никаких гарантий безопасности компилятор не дает.
  • Про IntelliSense или аналогичные вещи можно забыть – Boo вы будете программировать вслепую.

Вообщем, для тех кого это действительно интересует, у меня есть вводная статья про метапрограммирование на Boo. Только вот стоит ли напрягаться? Ведь C#5 не за горами, и есть большая вероятность, что с его выходом можно будет пометить Boo как [Obsolete].

IronPython

Вся критика по языку Boo может быть обращена к IronPython ибо синтаксис похожий. Единственный плюс – что IronPython как бы более “зрелый” и даже имеет поддержку в Visual Studio (IronPythonTools). Ну и да, “динамичность” этого языка несет в себе, якобы, некоторые приемущества которые всем уже известны.

Только есть одно но – тема CLR vs DLR (не знаю можно ли так писать) – явно не раскрыта. Например, почему создатели языка Go намеренно сделали его статическим? Правильно – скорость. А что делать с языком который не дает ощутимых бенефитов в плане синтаксиса, и который по скорости не тянет (чего стоит скорость декораторов, например – да легче помучаться и на C# написать, или подвязать тот же PostSharp).

IronRuby

Если питонообразные языки человек с опытом C# еще как-то может понять, то Ruby – это чистая магия, т.е. язык который нужно долго и прагматично изучать с нуля. А стоит ли это того? Alt.Net сообщество уже прожужжало нам все уши на тему того, что Ruby лучше для тестирования (см. например Cucumber), и я с этим не спорю – действительно, чем ближе мы в BDD приближаемся к обычному английскому, тем больше к нам аппелирует сама концепция BDD. Только вот есть одно но – BDD пока штука не доказанная, она как и приемочное тестирование в стиле Fitnesse является интересной абстракцией к которой индустрия присматривается, но не делает ее стандартом для разработки.

Чем еще хорош Ruby? Да, он неплохо поддерживает динамическое метапрограммирование, есть даже книжка на эту тему. Но занимаясь именно динамическим, а не статическим, метапрограммированием, следует понимать что это не совсем одно и то же – динамическое программирование это серьезное заигрывание с концепциями а-ля ExpandoObject, то есть манипуляция типов на этапе исполнения – нечто, что после безумной головной боли можно реализовать и на Mono.Cecil. В то же время, статическое метапрограммирование – это возможность расширять не тип, а компилятор. Тем самым, сравнивать эти два подхода не очень уместно, и то что Роб Конери хочет “метапрограммирование сегодня и сейчас” – это лично его представление о том, что это такое, и мне кажется он смешивает краски.

Следует заметить, что у IronRuby в отличии от IronPython нет поддержки в Visual Studio. Поэтому придется использовать или SharpDevelop или (сюрприз!!!) IntelliJ IDEA/RubyMine. При этом вы получите IntelliSense для ваших собственных конструкций, но его у вас не будет для различных .Net-библиотек.

Заключение

Прежде всего – да – существуют и другие языки в стеке .Net, например IronScheme. Но чем дальше мы отходим от “канона” тем дальше мы и от обычного бизнес-программирования, а следовательно каким бы элегантным не был тот или иной язык, можно с уверенностью говорить что без участия комьюнити, uptake такого языка будет равен нулю. Примером может служить язык Nemerle, которого, несмотря на наличие интересных (но ни в коей мере не революционных) идей, ожидает та же участь что и Boo.

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

  • Бизнес не примет их без поддержки Microsoft
  • Количество людей, хорошо знающих эти языки мало́, а значит те сотрудники что у вас их знают рискуют стать незаменимыми
  • Клиент вряд ли согласиться на проект на языке, особенно если саппорт он хочет получить не у вас, а где-то еще
  • Инструментарий пока не очень готов – это касается даже таких языков как F#
  • Реально не хватает success stories, которые четко показывают бенефиты

В заключение этой статьи я призываю всех .Net-разработчиков порадоваться, что у нас есть такой гибкий язык как C#, который удовлетворяет все 100% (да-да, именно 100%) наших потребностей. С другой стороны, никто не мешает экспериментировать – главное чтобы ваши эксперименты потом попадали в production, а то иначе это все академизм и теоретизирование. Удачи!

Update 1 Как подсказал коллега @butaji, DLR полезен тем что позволяет легко “скриптовать” ваши .Net-приложения, то есть фактически получать возможность скриптинга ваших .Net-конструктов без использования COM Automation или еще более кустарных извратов. Это конечно огромный плюс в тех ситуациях когда это действительно нужно, особенно если учесть альтернативы (создание всяких проприетарных DSL и т.п.).

Update 2 Судя по всему, с DLR-языками, в частности с IronRuby, все достаточно плохо.

Update 3
Судя по всему, огромным приемуществом DLR являются ситуации, когда нам нужно постоянно подтачивать нашу программу уже после компиляции. Коллега @butaji уже это упомянул, но мне пока это не попадалось как вопиющий юз-кейс. А теперь я даже обзавелся компонентом который делает синтактическую подсветку. Буду встраивать; посмотрим что получится.

Реклама

Written by Dmitri

2 августа 2010 в 16:55

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

комментария 54

Subscribe to comments with RSS.

  1. Упущен один важный момент c DLR/Boo — то, что можно просто заскриптовать .NET (и не только?) приложения и это привносит немалый business value

    butaji

    2 августа 2010 at 17:02

    • А ты быстро прочитал пост — менее чем за минуту. Признаюсь — сам DLR никуда не встраивал, но видел решения где существующий код на том же Питоне был легко подвязан к VSX, судя по всему без портирования вообще. Супер!

      Dmitri

      2 августа 2010 at 17:17

  2. Если честно, то по моему все эти пляски по поводу количества языков запускаемых под clr- это чистая политика партии. Надо догнать и перегнать jvm. Там сотня языков, так и у нас не меньше.
    Для меня кроме C# есть только 1 альтернативный язык в vs2010 — это C++. F# честно говоря просто не понимаю в виду, не понимаю функционального подхода.

    У меня может мозга не хватает, зачем такие языки типа Boo и Nemerlie, но думаю я не один такой, кто не понимает зачем оно. Нас таких 95% наверное.

    Существование ironpython, ironruby, до хоть Phalanger(php) и janet на мой взгляд оправдано только с 1 целью- запустить без изменений код написанный на python, ruby, php, java на стандартной clr или dlr. ну и с целью перетащить товарищей на ms стек, нужна интеграция этих языков с стандартной библиотекой классов.

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

    SychevIgor

    2 августа 2010 at 17:45

    • JVM до недавнего времени не был полиглотным. МС позиционирует полиглотность как уникальную фичу, но тут краски смешались благодаря таким языкам как Scala. И если язык вроде Scala действительно нужен ввиду общей отсталости Java, то в .Net все менее очевидно.

      Насчет С++, это опять же для 1% продвинутых людей которые знают зачем это нужно и как работать с этим из C#. Лично мне недавно был интересен язык Go (от Google), т.к. хочется именно компилируемый язык который поддерживал бы всяческие новые парадигмы.

      Dmitri

      2 августа 2010 at 17:53

  3. Я бы сказал, что главным стимулом для существования не-C# языков является то, что нынешний C# развивается как раз благодаря тем концепциям, которые появлялись в виде частей отдельных языков. Все, что есть в нем — до этого появлялось где-то раньше. Метапрограммирование на CLR? Пускай Boo и Nemerle и не стали мейнстримом, но они подняли тонну материала по компиляции метакода в IL, сгенерировали километры обсуждений применимости метарограммирования в мейнстриме вообще.

    F# и Async Workflows точно таким же образом можно рассматривать как попытку смоделировать удобную среду для асинхронного программирования, причем, опять же — в контексте компиляции функционального кода в IL-код (компиляция функциональных языков — это вообще целый академический эпос).

    Пожалуй, если вкратце, то ответом на заголовок поста будет — да :)

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

    Igor T.

    2 августа 2010 at 19:12

    • Метапрограммирование на CLR? Пускай Boo и Nemerle и не стали мейнстримом, но они подняли тонну материала по компиляции метакода в IL, сгенерировали километры обсуждений применимости метарограммирования в мейнстриме вообще.

      Ну не километры… метапрограммирование, думается мне, понимают процентов 5 разработчиков. Это точно не мейнстрим.

      F# и Async Workflows точно таким же образом можно рассматривать как попытку смоделировать удобную среду для асинхронного программирования, причем, опять же – в контексте компиляции функционального кода в IL-код (компиляция функциональных языков – это вообще целый академический эпос).

      Это не хитрая компиляция, это библиотечное, по сути дела, решение. Что такое workflow? Это перегрузка операторов, так что в async { .. } например операторы let! и do! ведут себя по другому. Подложкой для этого всего все равно является APM, то есть пары BeginInvoke()/EndInvoke().

      Dmitri

      2 августа 2010 at 19:27

      • >>> Ну не километры… метапрограммирование, думается мне, понимают процентов 5 разработчиков. Это точно не мейнстрим.

        но тем не менее C# 5.0 не за горами :)

        >>> Это не хитрая компиляция, это библиотечное, по сути дела, решение.

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

        Короче, не станут сторонние языки мейнстримом, да и никому они в качестве мейнстрима не нужны. А вот прототипом новых фичей в C# — запросто.

        К слову, в статье еще Spec# не упоминался :) Вот он-то очень четко иллюстрирует мою идею.

        Igor T.

        2 августа 2010 at 20:43

      • >> Это не хитрая компиляция, это библиотечное, по сути дела, решение.

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

        Mike Chaliy

        2 августа 2010 at 20:51

        • Я не вижу особой читабельности в постоянных let! и do!

          И вообще, если логика простая, можно использовать и APM. Ну или PowerThreading. А для сложных вещей лучше какую-нть DSLку заточить конкретно для этих целей. Например вот так.

          Dmitri

          2 августа 2010 at 21:01

      • А let! и do! чем не DSL?

        Igor T.

        2 августа 2010 at 21:53

  4. >Да, интересный, функциональный язык. А теперь внимание вопрос: в чем собственно его приемущества, какой конкретно от него business value?

    Я не много с этим языком работал, но подчеркнул бы слудующие пункты, в которых, как я вижу язык имеет преимущество:
    *поддержка асинхронных цепочек на уровне компилятора
    *поддержка реактивного программирования(без использования сторонних библиотек как в шарпе)

    Но да, в нем много синтаксических недостатков, или просто не привык еще.

    apmath

    2 августа 2010 at 19:19

    • Асинхронные цепочки это уровень языка, компилятор делает такой же IL как и C# (см. мой комментарий выше). Что касается реактивного программирования (first class events и т.п.) — тут я вообще разницы не вижу. То что я могу сделать Event.map или Event.filter на события — да, приятно, но я могу сделать то же самое ценой всего лишь одной библиотеки.

      Получается что в этом плане у F# нет приемуществ, т.к. оба примера реализуются с помощью библиотек PowerThreading и Reactive Extensions соответственно.

      Dmitri

      2 августа 2010 at 19:31

  5. Главное чтобы ваши эксперименты потом попадали в production. —> не считаю это такой уж неприложной истиной и это мое главное возражение.

    Alexander Tankeev

    2 августа 2010 at 21:08

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

      Dmitri

      2 августа 2010 at 21:28

  6. Все верное, массы идут за C#. А C# идет за python/ruby/f# и прочей кодлой. Если бы их не было, была бы вторая жава.
    Хотя те тоже встрепенулись.
    Весь этот «зоопарк» действительно можно заменить C# ну пару раз наступив себе на горло. Но можно. Вот с JavaScript все сложнее. Чего мне не хватает, так это аналога GWT (google web toolkit).
    (только не надо про silverlight плз)

    Shrike

    3 августа 2010 at 1:32

    • Я думал вы скажете «только не надо про Script#», ведь именно он пытается быть аналогом GWT, не так ли? Вообще идея GWT очень сильно импонирует, т.к. сокращает, а не преумножает, количество языков, которые нужно знать для разработки веб-приложений.

      Dmitri

      3 августа 2010 at 9:21

      • Script# как-то странно пытается, застряв на C# 1.1.
        Есть более интересная на вид вещь — jsc (jsc-solutions.net). Но как-то отзывов на нее нет.

        «не надо про silverlight» — т.к. это компилируемый язык в приложении для браузера. GWT — тоже компилируемый язык в приложении для браузеров, но совсем по-другому.
        Вобщем MS опять проморгали тренд имхо со своим silverlight’ом.

        Shrike

        3 августа 2010 at 17:53

        • Да не, не проморгали. Это RIA, это нужно чтобы динамический график показать и т.п. Для этого всегда будет рынок, и будут даже те, кто будет строить полноценные решения с SL-фронтендом. Но вернувшись к GWT, да, это совсем другая тема — тема которая имеет огромное количество плюсов по сравнению с той кашей, которая получается даже в самом простом проекте Asp.Net MVC.

          Dmitri

          3 августа 2010 at 20:40

    • WebSharper не пробывали? http://www.intellifactory.com/products/wsp/Tutorial.aspx
      Я сам отношусь весьма скептически к этим инструментам (особенно глядя как хороши всевозможные dynamic data/updatepanel на простых примерах и как они начинают откровенно мешать на сложных задачах).

      Андрей

      3 августа 2010 at 21:39

      • Не пробовал. Для меня странновато использовать функциональный язык в этом контексте. Непонятно где тут пресловутый business value.

        Dmitri

        4 августа 2010 at 17:35

  7. А, еще на тему «нафига нам python и пр» рекомендую глянуть на фреймворки Grails и Django (если не видели).
    Все-таки забавно там, код и он же одновременно dsl для доменной модели и он же одновременно dsl для конфигурации.

    Shrike

    3 августа 2010 at 1:36

  8. Отличная статья, подтвердила для меня то, что я тоже подозревал подсознательно, но не мог чётко высказать. Очень нравятся «так между прочим» ссылки на вещи типа FitNesse — эрудированных специалистов сейчас очень мало к сожалению.
    Так держать!

    Kirill Osenkov

    3 августа 2010 at 7:11

  9. C#, конечно, всем хорош, но! Лично меня уже давно утомляет его синтаксис. Хочется чего-то более простого и, в какой-то мере, изощрённого. Какой-нибудь Лисп или подобие Haskell с Erlang.
    Короче, я против того, чтобы добавлять новые классные конструкции в язык за счёт костылей синтаксиса. Sequence comprehension через LINQ сложно назвать верхом изящества, хотя, несомненно, задачу оно решает.

    Maxim Moiseev

    3 августа 2010 at 9:27

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

      Dmitri

      3 августа 2010 at 12:51

      • Отличное слово — приелся. Многословен и приелся.

        Изучать языки — фан, деньги — суета сует.

        Maxim Moiseev

        3 августа 2010 at 14:44

    • Попробуйте Nemerle. :)

      hc

      3 августа 2010 at 19:16

  10. В защиту F#
    yield return 1; по крайней мере не читабельнее чем let!
    Писать с обработкой ошибок в стиле APM на С# очень неудобно. Да и workflows не ограничиваются только async. Не упомянут pattern matching, active pattern помогают при написании кода. Конечно отсутствие инструментов типа resharper (да и встроенная поддержка студией далека от С#) не способствует развитию использования F#

    Андрей

    3 августа 2010 at 9:39

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

      Dmitri

      3 августа 2010 at 13:05

  11. Почему же не был рассмотрен Nemerle?
    Синтаксис практически полностью копирует C#, есть интеграция в VisualStudio 2008. В отличие от Boo он имеет гораздо больше возможностей относительно «цитирования и сплайсинга» — квазицитирование, при том генерирование невалидного IL из макросов практически нереально. Постепенно обрастает фичами — PEG-парсер на макросе (это в тему разбора текста), компьютеэйшн экспрешонз из F#, умеет LINQ запросы.

    hc

    3 августа 2010 at 16:58

    • а кто его за пределами rsdn.ru знает?
      Cлушал подкаст altspb, кто-то из ведущих сказал: не посещает этот сайт из-за того, что там дизайн так себе :), другие согласились.

      Андрей

      3 августа 2010 at 17:14

      • Уж давно хочу исправить эту ситуацию, но все нехватает силы воли.

        hc

        3 августа 2010 at 19:17

      • Нет, во-первых это подкаст spbalt.net, а во-вторых, мы в основном игнорируем РСДН из-за откровенно непрофессионального поведения его участников. Статьи там интересные, но атмосфера там на грани добра и зла, и участвовать в этом нет ну никакого желания.

        А насчет Nemerle, нужно больше людей которые готовы его рекламировать. Нужна полная поддержка в VS2010, а не поддержка в 2008 которая лично у меня, например, вообще не захотела работать (было давно, правда).

        Более того, претензий к Nemerle слишком много — очень много криптических операторов вроде $.. которые известны только авторам. «С нуля» Nemerle вообще невозможно читать. Ну и попытка вплести функциональщину мне не очень нравится, плюс опять же часть связанная с метапрограммированием по сравнением с Boo запутана (вроде как там 4 конструкта по сравнению с 2мя в Boo).

        Dmitri

        3 августа 2010 at 20:37

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

        Претензии не совсем ясны. Операции и конструкции аналогичные C# выглядят совершенно также. Конкретно по $ — это тот самый сплайс оператор, для подстановки параметров в строку или квазицитату.

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

        Функциональщина совершенно уместна. Язык является гибридным: на уровне объявлений используется труЪ ООП подход аналогичный C# (то с чем совсем плохо у F#), на уровне тел методов находится «функциональщина» — все достаточно чисто и продумано (то с чем откровенно хреново у императивного C#). В отличии от Boo в языке есть квазицитаты, без них генерирование более-менее сложного кода в макросах было бы серьезно осложнено: вы пробовали работать с CodeDom? так вот в Boo происходит работа с чем-то похожим, это я вам скажу мрак полнейший.

        Я не слишком верю что в C# 5.0 появится что-то подобное, тем более когда бишь он выйдет? ;)
        Так что если хочется статического метапрограммирования в .NET без погружения в адские конструкты CIL, то Nemerle это то что нужно.

        hc

        4 августа 2010 at 0:00

  12. очень интересная статья, большое спасибо!

    а где можно почитать про метапрограммирование в C# 5.0?

    cdriper

    3 августа 2010 at 17:13

    • Сейчас — нигде. Есть небольшая презентация Хельсберга где он демонстрирует REPL в C#, но пока больше инфы не было. Как только появится — ей будет пестрить весь интернет.

      Dmitri

      3 августа 2010 at 20:33

      • наверное поэтому гугл мне так ничего и не нарыл по теме :)

        просто ты так уверенно про это пишешь, как про состоявшийся факт…

        кстати, если ты активно пользовал метапрограммирование в F# или Boo, было бы очень интересно почитать по теме, желательно с более менее реалистичными примерами.

        cdriper

        4 августа 2010 at 9:52

      • да…

        и какая связь между REPL и метапрограммированием?

        cdriper

        4 августа 2010 at 9:59

  13. […] Только DSLи – это пока направление которое в основном, во-первых, для internal use, а во-вторых только для продвинутых фирм вроде моей. Точно не для общего пользования. […]

    По-моему, это звучит слишком пафосно и вульгарно.

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

    На самом деле, DSL — это просто.

    Когда напишешь LL(1) парсер с восстанавлением после сбоя , или хотя-бы простой нисходящий парсер методом рекурсивного спуска, тогда меня поймёшь.

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

    Например — lua-скрипты для многих игр — это DLS описания игры (плагинов, заставок, модов, сцен, карт и т.д.)

    hack2root

    11 августа 2010 at 17:35

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

      Dmitri

      11 августа 2010 at 17:43

  14. Вначале хотел написать комментарий, но он получился относительно большим, посему вынес в отдельный пост:
    http://status-alexus.blogspot.com/2010/08/net-ironpython.html

    Alexey Diyan

    12 августа 2010 at 2:32

  15. […] наткнулся на статью Дмитрия Нестерука “Нужно ли полиглотное программирование в стеке .Net?&#…, где была высказана жалоба что нет успешных историй […]

  16. В защиту скриптовых языков в .Net и Python вообще, написал небольшую заметку об успешном проекте с использованием .Net и IronPython:
    http://roinet.net/2010/08/12/nuzhen-li-python-v-net-steke/

    Pavel

    12 августа 2010 at 14:10

  17. А как же все-таки на счет VB.NET? Интересно ваше мнение. Работал в нескольких фирмах и как не странно, для заказчиков, на которых работали фирмы, было предпочтительнее, чтобы писали на VB.NET. Это можно отнести к пережиткам прошлого?

    Роман

    12 августа 2010 at 23:03

    • К сожалению, я не квалифицирован чтобы судить на счет VB. Мне кажется что новые .Net-проекты сейчас создаются исключительно на C#, а вот легаси — тут может быть и VB и C++/CLI и что угодно еще.

      Кто-то просто всегда занимался VB и им легче продолжать писать на нем. Ничего против не имею.

      Dmitri

      12 августа 2010 at 23:28

  18. вообще, как правило, то что есть в C# есть и в VB.NET. если в C#5 появится метопрограммирование, то в VB.NET 11, я думаю тоже. Но учитывая то, что для C# намного лучше поддержка ReSharper’а, то C# конечно предпочтительнее

    Роман

    13 августа 2010 at 0:00

  19. Для .Net еще есть и Clojure (пока в бета-версии)

    Alex Ott

    25 августа 2010 at 18:24

  20. И всё-таки как же язык Scala (для .NET), красивее и продуманнее синтаксиса я ещё вообще не видел. Хотя, конечно, за последнее время C# во многом догнал и уже даже перегнал, но сама идиома Scala — просто замечательная (самая лучшая гибридизация функционального и импиративного языков + метапрограммирование и прямая работа с XML; намного лучше, чем в Nemerle).

    Darklight

    14 сентября 2010 at 16:21

    • Мне кажется что Scala гораздо уместнее сравнивать с F#, и тут он (имхо) весьма серьезно проигрывает по ряду параметров, в частности по синтаксису. Впрочем, Scala — это наверное лучшее что на данные момент существует на JVM, а его поддержка для .Net, насколько я знаю, в зачаточном состоянии.

      Dmitri

      10 января 2011 at 16:29

  21. Часто одним из плюсов F# называют более удобную работу с многопоточностью из-за immutable (не изменных) типов.
    В книге «Real-World Functional Programming WITH EXAMPLES IN F# AND C#» приводится пример immutable типа на C#

    class GameCharacter {
    readonly int health;
    readonly Point location;

    public GameCharacter(int health, Point location) {
    this.health = health;
    this.location = location;
    }

    public GameCharacter HitByShooting(Point target) {
    int newHealth = CalculateHealth(target);
    return new GameCharacter(newHealth, this.location);
    }
    }

    т.е. любое изменение состояния объекта влечет создание нового экземпляра.

    Вопрос — стоит ли применять F# и immutable типы для каких-то сложных и долгих вычислений, покрывает ли удобство распараллеливания затраты на постоянное создание новых экземпляров?

    Alex_BBB

    9 июля 2011 at 7:36

    • Зависит от кол-ва аллокаций. Если вы наплодили миллион объектов и они попали в Gen 2 а у части из них еще и финалайзеры есть, вы будете писать свой garbage collector. Кстати, вон ребята из Jane Street ясно говорят почему не используют F# — запредельное кол-во аллокаций. Ведь следует помнить, что каждая мало мальски функциональная фишка, например передача оператора в качестве аргумента — это лишний выделенный struct.

      С другой стороны, это структура а не класс, что как бы намекает, что ежели использовать System.ValueType’s, stackalloc и т.п. то может все не так плохо.

      Dmitri

      14 июля 2011 at 15:47


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

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

Логотип WordPress.com

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

Фотография Twitter

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

Фотография Facebook

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

Google+ photo

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

Connecting to %s

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