Re: Каковы перспективы языка?
От: geniepro http://geniepro.livejournal.com/
Дата: 09.03.07 23:08
Оценка: +1 :))) :)
Здравствуйте, Ka3a4oK, Вы писали:

KK>Меня интересуют факты свидетельствующие о перспективности языка Nemerle. Кто еще заинтересовался в языке, кроме энтузиатов? Статьи серьезных дядек, проекты и т.д


Здесь имеются люди, очень сильно сомневающиеся в перспективах Хаскелла, несмотря на наличие кучи статей и книг серьёзных дядек по Хаскеллу, разных проектов и даже обучения Хаскеллу в американских ВУЗах (не всех, конечно, но всё же, во всяких там Оксфордах и пр.), а так же поддержки со стороны Майкрософта. Тем не менее, несмотря на всё это, есть тут люди, которые в перспективы Хаскелла совершенно не верят... :о)

Если продолжить их логику, то у Немерле перспектив в принципе быть не может. Но я с ними не согласен! :о)).
Re[4]: Каковы перспективы языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.05.07 13:41
Оценка: +1 :)))
Здравствуйте, ravlyk, Вы писали:

R>А попробовать встроить его в SharpDevelop?


Попробуй.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ну конечно у Немерле нет будущего :)
От: IT Россия linq2db.com
Дата: 11.06.07 13:12
Оценка: 1 (1) +2
Здравствуйте, FDSC, Вы писали:

FDS>Ещё неудобство, например я хочу вернуть result


FDS>Я не могу написать так:

FDS>if (condition)
FDS>{
FDS> def result = kjsdhfjklasdh()
FDS>}
FDS>else
FDS>{
FDS> def result = werioptuertj();
FDS>}
FDS>Calc(result)

Так ты не можешь написать нигде.

FDS>Нужно писать так:


Нет, нужно писать так:

def result =
  if (condition)
  {
    kjsdhfjklasdh()
  }
  else
  {
    werioptuertj();
  }
    
Calc(result)
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Каковы перспективы языка?
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.03.07 10:38
Оценка: +3
Здравствуйте, ie, Вы писали:

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


KK>>Сможет ли Nemerle стать си-плюс-плюсом для платформы .NET?


ie>Вряд ли, причем это не проблема языка, а проблема глупого менеджмента и маркетинга.


Знаешь есть такая поговорка "народ имеет то правительство, которое его имеет".
Т.е. не совсем правильно переваливать ответственность на менеджмент и маркетинг, они исходят из той ситуации, которая есть — на рынке труда, в образовании и т.п.
Re[9]: Ну конечно у Немерле нет будущего :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.06.07 23:36
Оценка: 6 (2)
Здравствуйте, Константин Л., Вы писали:

ИД>>>
ИД>>>def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);
ИД>>>

FDS>>И что это такое??? Я нефига не понял...

КЛ>подозреваю, что Map бегает по массиву и для каждого elem вызывает elem *= ck. А вот как грамотно называется _ * ck? Замыкание?


Map — это фукнция которая отображает один список (в данном случае массив) в другой список. При этом она преобразует элементы с помощью переданной ей фукнцией.
Другими словами он пораждает новый список элементы которого равны исходным к которым применили фунцию переданну фунции Map в качестве параметра. Например, следующий код получает список квадратов жлементов исходного массва целых приведненных к строке:
def ary = array[1,2,3];
def lst = ary.Map(elem => (elem * elem).ToString());
WriteLine(lst); // в lst содержится список строк


Конструкция "_ * ck" — это частичное применение фунции.

Если мы напишем x * y, то получим выражение умножающее 'x' на 'y'. Мы можем сделать фунцию которая бдет умножаеть на определнное значение ее едениственный параметр. Это можно сделать так:
def mulTo10(x)
{
  x * 10
}

или так (при этом мы получим безымянную функцию — лмбду):
x => x * 10

или используя частчное примененеие:
_ * 10

здесь подчеркивание говорт компилятору, что параметр оператора не задан и что его моно будет задать позже как параметр получившейся лямбды. В итоге "_ * 10" переписывается в "x => x * 10" только имя параметра генерируется автоматически.
В частичном применении могут использоваться не только константы, но и захваченные в текущем контексте переменные. Следующий пример аналогичен предыдущим:
def x = 10;
_ * x

Таким образом если нам нужно передать в другую фунцию (в нашем случае в Map) функцию которая имеет один параметр, ее тело состоит из умнажения этого параметра на некую перменную из текущего контекста (х, в нашем случае), то мы можем вместо описания полной фунции просто воспользоваться частичным применением.
Частично можно применять любую фунцию, операторы и даже экземпляр объекта. Подробности на сайте языка.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ну конечно у Немерле нет будущего :)
От: Vermicious Knid  
Дата: 11.06.07 14:22
Оценка: 4 (1) +1
Здравствуйте, FDSC, Вы писали:


FDS>С другой стороны у Немерле сохранился убивающий меня недостаток C++/C# — округление без предупреждений в выражениях по типу 1/8*pi — постоянно приходится думать, где компилятор округлит и как,

Гы. Здесь все ясно как божий день. Ты производишь целочисленное деление 1 и 8(оба аргумента — целые числа, чего же ты хочешь ). Если тебе это кажется недостатком — welcome to Haskell, OCaml, etc. Мне лично работа с числами в этих языках раздражает значительно больше, чем работа с числами в C++/C#/Nemerle. Еще кажется в Паскале целочисленное деление отдельная операция, меня это бесило, когда приходилось иметь с ним дело(как же давно это было ).

FDS> и прибавился недостаток в виде возможности повторного определения переменной в коде (лично я не понял, зачем это сделано).

Не согласен, это бывает удобно. Вообще это сделано по мотивам OCaml, там тоже самое, только записывается несколько более очевидно и как следствие менее кратко:
let x = 1 in
let x = x * 22 in
x;;

Я как-то пришел к выводу, что это еще как-то связано с внутренним устройством компилятора, в частности макро-системы. Гигиена в Nemerle кажется так работает — допустим макрос определяет внутри себя def someFancyId = 2, во внешнем коде определен другой someFancyId. Так вот имена у них будут одинаковыми, но будет разный, так называемый, "цвет". Чтобы макросы могли пользоваться внешними идентификаторами мы либо должны вообще игнорировать цвет(так делает сплайс $(smth : dyn)), либо брать его из контекста в котором был вызван макрос(как делает $(smth : usesite)), либо отправлять макросу имена в качестве параметра(в составе выражения) — у них будет цвет соответствующий их текущему контексту(макрос как-бы создает новый контекст). Вроде так.

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

А вообще если подумать, то тот-же C++ предоставляют нечто похожее, например:
int x = 1;
{
  float x = 22.0f;
  std::cout << x << std::endl;
}

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

FDS>Циклы на нём писать то же не удобно, вместо простого int i = 0 нужно писать mutable i = 0

Ерунда. Лично я на Nemerle очень редко использую for(; ; ) цикл, фактически никогда не использую. Во-первых foreach позволяет делать так:
foreach(i in [0..n-1])

Во-вторых для есть такие функции как FoldI, FindIndex, IterI. По поводу mutable, я в самом начале своего знакомства с Nemerle использовал макрос var, а потом забил на это и теперь стараюсь просто как можно меньше использовать mutable. Кажется были предложения заменить mutable на var, но дальше предложений дело не пошло(авторы языка кажется согласились на добавление макроса var). Лично я не против варианта с добавлением var в качестве ключевого слова полностью равнозначного mutable(то есть для членов классов тоже), но боюсь, что многие от этой идеи будут не в восторге.

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

Это хорошо. Меня лично Nemerle изначально привлек макросами, и только потом пришло осознание, что без (написания собственных) макросов это тоже неплохой язык. Важно только понимать, что преимущества языка обеспечиваются во многом стандартными макросами, квазицитированием и паттерн-мэтчингом AST, которые в компиляторе для анализа и генерации кода применяется очень часто. Без них Nemerle был бы совершенно другим языком.
Re: Каковы перспективы языка?
От: _pk_sly  
Дата: 15.03.07 09:27
Оценка: +2
неверен подход.
"а вот убедите-ка меня использовать N, а я буду придумывать, почему я этого не хочу"

не хочешь — не надо
Re[9]: Ну конечно у Немерле нет будущего :)
От: Klapaucius  
Дата: 13.06.07 12:02
Оценка: +2
FDS>Ага, попробуй взять студента и спросить у него, скажем, формулу Остроградского, запретив при этом писать в математических выражениях

Я, правда, не студент, но можно я впаду в детство? Спасибо.
Имеется в виду формула Остроградского-Гаусса?
Поток через поверхность равен сумме источников и стоков в объеме, ограниченном этой поверхностью.
А что, теперь студенты отвечают, что это три закорючки с одной стороны и две с другой?

FDS>Понимаешь о чём я говорю? Когда записываешь что-то не так, как думаешь, тебе приходится выполнять в уме дополнительные преобразования, которые увеличивают вероятность возникновения ошибки


Ну так он и записывает, как думает. И я точно также поступаю. С нами что-то не так?
... << RSDN@Home 1.2.0 alpha rev. 677>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[6]: Ну конечно у Немерле нет будущего :)
От: Иванков Дмитрий Россия  
Дата: 11.06.07 16:53
Оценка: 8 (1)
Здравствуйте, FDSC, Вы писали:

FDS>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):

FDS>
                
FDS>                def Lf = cf.Length;
FDS>                def dx = array(Lf);
FDS>                for (mutable i = 0; i < Lf; i++)
FDS>                {
FDS>                    dx[i] = cf[i] * ck;
FDS>//                    Console.WriteLine($"$(cf[i]) * $(ck)");
FDS>                }

Проще так:
def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);

FDS>                    for (mutable i = 0; i < Lf; i++)
FDS>                    {
FDS>                        dx[i] += incDx[i];
FDS>                    }

Вот тут простой библиотечной функцией не заменить (пока?). Можно конечно что-то такое def dx = Map2 (dx, ToList (incDx), _ + _).ToArray (), но не стоит

Дальше еще не вчитывался.
Re[7]: Ну конечно у Немерле нет будущего :)
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.06.07 17:29
Оценка: 4 (1)
Здравствуйте, Иванков Дмитрий, Вы писали:

ИД>Здравствуйте, FDSC, Вы писали:


FDS>>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):

FDS>>
FDS>>                def Lf = cf.Length;
FDS>>                def dx = array(Lf);
FDS>>                for (mutable i = 0; i < Lf; i++)
FDS>>                {
FDS>>                    dx[i] = cf[i] * ck;
FDS>>//                    Console.WriteLine($"$(cf[i]) * $(ck)");
FDS>>                }
ИД>

ИД>Проще так:
ИД>
ИД>def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);
ИД>


Скажу больше. Проще так:
using Nemerle.Utility;
...
def x = cf.Map(_ * ck);


ИД>
FDS>>                    for (mutable i = 0; i < Lf; i++)
FDS>>                    {
FDS>>                        dx[i] += incDx[i];
FDS>>                    }
ИД>

ИД>Вот тут простой библиотечной функцией не заменить (пока?). Можно конечно что-то такое def dx = Map2 (dx, ToList (incDx), _ + _).ToArray (), но не стоит

Для всего для чего нет библиотечных фунций можно создать собственные фунции .

Кстати, в донете код:
for (mutable i = 0; i < Lf; i++)
    dx[i] += incDx[i];

медленее нежели:
for (mutable i = 0; i < dx.Length; i++)
    dx[i] += incDx[i];

так как при этом первый вариант не выбрасывает проверок выхода за пределы массива, а второй выкидывает (если конечно JIT не подеравили).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Ну конечно у Немерле нет будущего :)
От: IT Россия linq2db.com
Дата: 11.06.07 18:07
Оценка: 4 (1)
Здравствуйте, FDSC, Вы писали:

FDS>Когда это возможно, я пишу так, но, вполне возможно, я захочу вызвать в теле уловия ещё какую-то функцию после вычисления неужного значения — тогда этот код не сработает.


Ещё как сработает.

def result =
  if (condition)
  {
    kjsdhfjklasdh()
  }
  else
  {
    def result = werioptuertj();
    CallAnotherMethod();
    result
  }
    
Calc(result)


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

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

def result =
  if (flag1 && {
    def flag2 = CallLongOperation();
    flag2 && flag3 || !flag2 && flag4
  })
  {
    kjsdhfjklasdh()
  }
  else
  {
    werioptuertj();
  }
    
Calc(result)

Если переписать этот код на шарпе, то получится более витиевато и главное разглядеть отдельные участки алгоритма в таком коде будет уже не так просто.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Ну конечно у Немерле нет будущего :)
От: Иванков Дмитрий Россия  
Дата: 12.06.07 17:51
Оценка: 4 (1)
Здравствуйте, FDSC, Вы писали:

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


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


FDS>>>Только вот списки там МОГУТ быть разной длины


VD>>Значит алгоритм нужно менять. Обрабатывать эти случаи.


FDS>Я не очень понял, где в этом алгоритме ограничение на то, чтобы списки были одинаковой длины?

FDS>Вот, а у меня всё нормально работает для списков разной длины, так что у меня правильней

Ну как сказать нормально, только если второй длиннее первого
Вариант WolfHound-а легко обобщается на этот случай
        def GetDx(_, _)
        {
        | ([ck], cf :: _flast) =>
            (cf.Map(_ * ck), [])
            
        | (ck :: klast, cf :: flast) =>
            def (incDx, cflast) = GetDx(klast, flast);
            (cf.MapI((i, f) => f * ck + incDx[i]), cf :: cflast)
        
        | _ => throw Exception();//Если второй короче или если первый пуст
        }
Re[4]: Ну конечно у Немерле нет будущего :)
От: FDSC Россия consp11.github.io блог
Дата: 11.06.07 14:53
Оценка: 1 (1)
Здравствуйте, VladD2, Вы писали:

VD>
VD>Calc(if (condition) kjsdhfjklasdh() else werioptuertj())
VD>

VD>получается даже гороче и понятнее.

Тебе, может, и понятнее, а я, если бы увидел такую строку, незамедлительно бы переписал её через вспомогательную переменную
Re: Каковы перспективы языка?
От: _nn_ www.nemerleweb.com
Дата: 10.03.07 18:16
Оценка: +1
Здравствуйте, Ka3a4oK, Вы писали:

KK>Меня интересуют факты свидетельствующие о перспективности языка Nemerle. Кто еще заинтересовался в языке, кроме энтузиатов? Статьи серьезных дядек, проекты и т.д.


Будущее есть. Но вот когда оно наступит

  • Компилятор.
    На данный момент компилятор работоспособный, но не на 100%. Еще не все доделанно.

  • IDE
    Для Nemerle нужна поддержка в IDE.
    На данный момент интеграция Nemerle в VS немного сыровата.

  • Установка
    Легкость установки Nemerle ни у кого не вызывает сомнения.
    Обычному пользователю нужен файл установки после которого все будет работать. Увы этого еще нет.

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

    Чем раньше все это дело придет к стабильной версии тем перспективней и язык.
  • http://rsdn.nemerleweb.com
    http://nemerleweb.com
    Re[3]: Каковы перспективы языка?
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 16.03.07 19:00
    Оценка: :)
    Здравствуйте, ie, Вы писали:

    ie>Вряд ли, причем это не проблема языка, а проблема глупого менеджмента и маркетинга.


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

    KK>>Что бы объявлении вакансии писали не C#, а Nemerle.


    ie>Надеюсь увидить хотя бы что-то вроде: "знание Nemerle будет плюсом"


    С++ толкался огромнейшей конторой AT&T (бывшей Bell) с 1980-го по 1993-гг. И только к 1995-му на него перешло значимое количество программистов. Причем это практически в условиях полного отсуствия конкуренции. Конечно били разные Лиспы и Смолтоки, но серьезной кокуренции они не составляли на том оборудовании.

    Руби шел просто к признанию (т.е. когда о нем сатли массово говорить и хоть где-то применять) около 10 лет.

    Питон еще больше.

    Так что же ты хочешь от языка который еще не появился.

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

    Та же AT&T вкладывала в С++ не так много денег, но тем не мнее без AT&T С++ бы не быоло. Впрочем сейчас есть Интернет. Возможно он заменит AT&T или MS.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 12:54
    Оценка: :)
    Здравствуйте, Ka3a4oK, Вы писали:

    KK>Меня интересуют факты свидетельствующие о перспективности языка Nemerle. Кто еще заинтересовался в языке, кроме энтузиатов? Статьи серьезных дядек, проекты и т.д.


    У Немерле нет будущего: когда я напишу свой компилятор программировать не нужно будет вообще!
    Серьёзные дядьки обанкротятся и я буду единственным в мире квадралионером


    А если серьёзно, просто посмотри какой это язык: он очень удобен, даже если не использовать его функциональные возможности. Он избавляет, в частности, от написания (кое-где) даже классов и интерфейсов, позволяет засчёт замыканий упростить архитектуру, "развязать" связи между различными частями программы. Почувствуй это. Лично мне наплевать, есть у него будущее или нет (если бы я был менеджер, я бы это будущее обеспечил), им удобно пользоваться даже сейчас

    Другое дело, что чисто теоретически, все фичи из Немерле могут со временем так или иначе перекочевать в C#, например, хотя будет ли при этом C# органично их сочетать — не понятно.

    С другой стороны у Немерле сохранился убивающий меня недостаток C++/C# — округление без предупреждений в выражениях по типу 1/8*pi — постоянно приходится думать, где компилятор округлит и как, и прибавился недостаток в виде возможности повторного определения переменной в коде (лично я не понял, зачем это сделано). Циклы на нём писать то же не удобно, вместо простого int i = 0 нужно писать mutable i = 0

    Ещё неудобство, например я хочу вернуть result

    Я не могу написать так:
    if (condition)
    {
    def result = kjsdhfjklasdh()
    }
    else
    {
    def result = werioptuertj();
    }
    Calc(result)

    Нужно писать так:
    mutable result; // def result тоже не будет работать без инициализации
    if (condition)
    {
    result = kjsdhfjklasdh()
    }
    else
    {
    result = werioptuertj();
    }
    Calc(result)

    Это тоже крайне неудобно

    Так что, лично моё мнение, если нет особого риска, Немерле можно изучать как удобный язык программирования, если он вам кажется удобным, а какое у него будет будущее одному богу известно. Хотя, говорят, макросы у него супер... но лично я так и не понял что и как с ними надо делать
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 14:15
    Оценка: +1
    Здравствуйте, desco, Вы писали:
    D>а почему не просто

    D>
    D>def result = if (condition) kjsdhfjklasdh() else werioptuertj();
    D>Calc(result)
    D>

    Вот, вот. А если подумать, то и переменная тут в общем-то не нужна. Если только для отладочных целей.
    Calc(if (condition) kjsdhfjklasdh() else werioptuertj())

    получается даже гороче и понятнее.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 17:22
    Оценка: :)
    Здравствуйте, Иванков Дмитрий, Вы писали:

    ИД>Здравствуйте, FDSC, Вы писали:


    FDS>>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):

    FDS>>
                    
    FDS>>                def Lf = cf.Length;
    FDS>>                def dx = array(Lf);
    FDS>>                for (mutable i = 0; i < Lf; i++)
    FDS>>                {
    FDS>>                    dx[i] = cf[i] * ck;
    FDS>>//                    Console.WriteLine($"$(cf[i]) * $(ck)");
    FDS>>                }
    ИД>

    ИД>Проще так:
    ИД>
    ИД>def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);
    ИД>

    И что это такое??? Я нефига не понял...

    Да и потом, это как раз упрощать не надо, это и есть просто. Точнее, просто, пока в императивном стиле
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: Иванков Дмитрий Россия  
    Дата: 11.06.07 17:44
    Оценка: +1
    Здравствуйте, FDSC, Вы писали:

    FDS>Здравствуйте, Иванков Дмитрий, Вы писали:


    ИД>>Проще так:

    ИД>>
    ИД>>def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);
    ИД>>

    FDS>И что это такое??? Я нефига не понял...

    FDS>Да и потом, это как раз упрощать не надо, это и есть просто. Точнее, просто, пока в императивном стиле


    Понятно, не совпали представления о простоте

    В такой задаче следующим шагом к упрощению я бы сделал операторы для работы с массивами как с векторами, код стал бы примерно таким:
    def dx = cf * ck;
    dx += incDx;
    CalculatedPoints[CalcI] = 0 :: (dx * t * k + CalculatedPoints[CalcI - 1].ChopFirst(1));
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 18:04
    Оценка: +1
    Здравствуйте, Иванков Дмитрий, Вы писали:

    ИД>В такой задаче следующим шагом к упрощению я бы сделал операторы для работы с массивами как с векторами, код стал бы примерно таким:


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

    Просто императивно реализация схемы Адамса и методов Рунге-Кутты выглядит проще, в ней гораздо проще найти ошибку, в частности
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 23:36
    Оценка: :)
    Здравствуйте, FDSC, Вы писали:

    FDS>Ага, попробуй взять студента и спросить у него, скажем, формулу Остроградского, запретив при этом писать в математических выражениях

    FDS>Понимаешь о чём я говорю? Когда записываешь что-то не так, как думаешь, тебе приходится выполнять в уме дополнительные преобразования, которые увеличивают вероятность возникновения ошибки

    Скажи, в твоих мыслях когда ты думашь об алгоритмах действительно временные переменные присуствуют?
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[10]: Ну конечно у Немерле нет будущего :)
    От: IO Украина  
    Дата: 12.06.07 08:23
    Оценка: +1
    Здравствуйте, FDSC, Вы писали:

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


    VD>>Для начала нужно потихоничку побороть предрассудок заставляющий тебя думать, что if-ы это statment-ы, а не выражения. Потом изучить фунции вроде Map, Filter и т.п.


    FDS>Да нет у меня этого предрассудка, просто забываю об этом и выглядит это часто просто некрасиво


    Аргумент "некрасиво" — это часто следствие предрассудка.
    Re[12]: Ну конечно у Немерле нет будущего :)
    От: mkizub Литва http://symade.tigris.org
    Дата: 23.06.07 06:30
    Оценка: :)
    Здравствуйте, VladD2, Вы писали:

    VD>Ага. Это потому что во фрэймворке распознается паттерн цикла и проверка выхода за границы массива выносится за пределы цикла, но в любом случае анализ там примитивнийший, и вынести вторую проверку она не может, так что пока что С/С++ тут по любому будут выигрывать.


    VD>Вот до сих пор не пойму, что меало сделать более обощенный механизм оптимизации? Ну, хотя бы при при-JIT-е?


    И не поймёшь. Ты же думаешь, что JIT это так просто, взял да и оптимизнул код. Только паттерн распознать.
    Ага.
    Замечательная иллюстрация того, чем текстовые языки (в данном случае — байткод, IL), мешают оптимизации
    программы.
    SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
    Re[14]: Ну конечно у Немерле нет будущего :)
    От: mkizub Литва http://symade.tigris.org
    Дата: 25.06.07 17:04
    Оценка: :)
    Здравствуйте, VladD2, Вы писали:

    M>>Замечательная иллюстрация того, чем текстовые языки (в данном случае — байткод, IL), мешают оптимизации

    M>>программы.

    VD>Я не вижу тут никакой иллюстрации. Я вижу довольно безотвественну болтавню без какой-либо аргументации.


    Кстати, ещё один пример на этом же самом материале.
    Почему Nemerle не может сгенерировать байткод в таком виде, чтоб попасть в шаблон распознаваемый JIT-ом?
    Всё потому же — for в nemerle это макрос, и информация о том, что это цикл — теряется на этапе
    макроподстановки. Вместо

    $(init)
    goto check;
    loop:
    $(body)
    check:
    if $(cond)
      goto loop;


    вы генерите

    $(init)
    check:
    if ! $(cond)
      goto end;
    $(body)
    goto check;
    end:


    Вместо того, чтоб поправить бэкэнд у nemerle вы говорите о том, что в мелкософте должны поправить компилятор.
    Так им это так-же неудобно, как и вам. Что вам надо "восстановить" изначальный код (распознать, что это
    был for), что им. Вот ты же рассказываешь как это легко сделать, буде в наличии есть паттерн-мэтчинг и прочая
    функциональщина. Вот и сделали бы за день-другой. Почему не делаете? Времени нет и руки не доходять?
    В мелкософте тоже времени нет и руки не доходят.

    Но и в том и в другом случае — проблема в том, что теряется семантическая информация. Что при развёртывании
    макроса в Nemrele, что при генерации байткода в котором нет if-ов и loop-ов, а есть только jump-ы — теряется
    информация, и потом надо делать компилятор сложнее, медленее и с большим количеством багов — всё ради
    попытки восстановить утерянную информацию.
    SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
    Re[15]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 26.06.07 12:30
    Оценка: +1
    Здравствуйте, mkizub, Вы писали:

    M>Ух ты круть какая. Первый парень на деревне.


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

    M>Всё гораздо хуже.

    M>Ты же занимаешься программированием, то есть кибернетика тебе должна быть знакома.

    Ага. Считаю ее лженаукой.

    M>В ней есть такой постулат, впрочем, достаточно очевидный — для эффективного управления сложной системой, сложность управляющей системы должна быть больше, чем управляемой.


    Дальше можно не продолжать. Это бредовое утверждение. Ты собственно сам его и опровергаешь. И вообще, это офтоп плюс не интересная тема.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: AngeL B. Россия  
    Дата: 29.06.07 19:24
    Оценка: +1
    Здравствуйте, VGn, Вы писали:

    VD>>Ага и еще не ясно зачем эти фигурные скобки. Без них можно в одну строку уложиться:

    VD>>
    VD>>def result = if (condition) kjsdhfjklasdh() else werioptuertj();
    VD>>


    VGn>Аналог тернарного оператора в C#

    узко мыслишь.
    А вот эти примеры аналог какого оператора?

    а)

    def result = 
            if( cond ) {
                def i = 0;
                while( arr[i] < func(arr[i]) && cond1 ) i++;
                i;
            }
            else proc_another(arr[0]);



    б)

    def result = match( list ) {
         | x :: _ when x > 0 => -x;
         | x :: _ => x;
         | x :: [] => x+1;
       }



    вопрос же не в том, что if с простыми ветками можно заменить тетрарным, а в том, что любой оператор возвращает значение, так что надобность в тетрарном операторе отпадает. Поскольку конструкция это в сильной степени синтетическая. Тот же ИФ только в виде операции.
    Re[8]: Имена переменных
    От: VGn Россия http://vassilsanych.livejournal.com
    Дата: 12.07.07 06:55
    Оценка: +1
    FDS>А что именно не понятно и как их назвать?
    FDS>cf — массив запомненных значений функций
    FDS>ck — массив коэффициентов схемы Адамса
    FDS>Dx — приращение к текущему значению функции

    FDS>Как их по другому назвать так, чтобы понятно было?


    Эээх! Математики!
    Словами называть надо. Абревиатуры и идентификаторы в именах — перманентное зло!
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    PS
    От: VGn Россия http://vassilsanych.livejournal.com
    Дата: 12.07.07 07:05
    Оценка: +1
    FDS>>Как их по другому назвать так, чтобы понятно было?

    Если это — сокращения принятые соглашением, то соглашение должно быть легко доступно.
    Т.е эта твоя расшифровка должна стоять в комментариях или на неё должна быть прямая ссылка.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Каковы перспективы языка?
    От: Ka3a4oK  
    Дата: 09.03.07 19:12
    Оценка:
    Меня интересуют факты свидетельствующие о перспективности языка Nemerle. Кто еще заинтересовался в языке, кроме энтузиатов? Статьи серьезных дядек, проекты и т.д.
    ... << RSDN@Home 1.1.4 stable rev. 510>>
    Re: Каковы перспективы языка?
    От: Ka3a4oK  
    Дата: 10.03.07 10:06
    Оценка:
    Сможет ли Nemerle стать си-плюс-плюсом для платформы .NET? Что бы объявлении вакансии писали не C#, а Nemerle.
    ... << RSDN@Home 1.1.4 stable rev. 510>>
    Re[2]: Каковы перспективы языка?
    От: Ka3a4oK  
    Дата: 10.03.07 10:19
    Оценка:
    Пропущен предлог в.
    ... << RSDN@Home 1.1.4 stable rev. 510>>
    Re[2]: Каковы перспективы языка?
    От: ie Россия http://ziez.blogspot.com/
    Дата: 10.03.07 10:29
    Оценка:
    Здравствуйте, Ka3a4oK, Вы писали:

    KK>Сможет ли Nemerle стать си-плюс-плюсом для платформы .NET?


    Вряд ли, причем это не проблема языка, а проблема глупого менеджмента и маркетинга.

    KK>Что бы объявлении вакансии писали не C#, а Nemerle.


    Надеюсь увидить хотя бы что-то вроде: "знание Nemerle будет плюсом"
    ... << RSDN@Home 1.2.0 alpha rev. 655>>
    Превратим окружающую нас среду в воскресенье.
    Re[4]: Каковы перспективы языка?
    От: bkat  
    Дата: 15.03.07 08:14
    Оценка:
    Здравствуйте, Курилка, Вы писали:

    Оверквотинг почикан.
    К>Знаешь есть такая поговорка "народ имеет то правительство, которое его имеет".
    К>Т.е. не совсем правильно переваливать ответственность на менеджмент и маркетинг, они исходят из той ситуации, которая есть — на рынке труда, в образовании и т.п.

    Верно...
    Чтобы изменить эту ситуацию, надо статать этим самым менеджментом,
    взять на себя риск и начать использовать Nemerle (или еще что-то новое)
    в коммерческом проекте, за который ты же сам лично и отвечаешь

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

    Ну и так далее...
    Re: Каковы перспективы языка?
    От: Ka3a4oK  
    Дата: 15.03.07 21:51
    Оценка:
    Я решил выучить что-нибудь кроме C++. Интерес больше практичесий, чем академический. Я смотрел на Lisp, затем на Python, остановился на Nemerle. Net рано или поздно придется учить(допустим это бесспорно). Net это больше идеология, среда, библиотеки и меньше язык. Мне кажется, все равно с помощью какого языка изучать Net. Если Nemerle тупик, то я, уже зная Framework, перейду на другой язык(С#) с малыми потерями. Проблема новых языков, отсутствие библиотек. У Nemerle такой проблемы нет. Мне кажется хорошей идеей книга из серии "изучаем Net" с примерами на Nemerle(менее радикально на Nemerle и C#). Примерами, показывающими превосходство Nemerle. Очень важна нормальная интеграция Nemerle в Visual Studio. Неискушенный программист может выбрать C# только из-за более удобной поддержки среды разработки.
    ... << RSDN@Home 1.1.4 stable rev. 510>>
    Re[2]: Каковы перспективы языка?
    От: Аноним  
    Дата: 16.03.07 11:36
    Оценка:
    Здравствуйте, Ka3a4oK, Вы писали:

    KK>Net рано или поздно придется учить(допустим это бесспорно).


    К сожалению, для меня это не то что не бесспорно, а скорее даже маловероятно, посему факторов для того чтобы "сесть" на Н недостаточно для решительных действий
    Re[2]: Каковы перспективы языка?
    От: _FRED_ Черногория
    Дата: 16.03.07 16:33
    Оценка:
    Здравствуйте, _nn_, Вы писали:

    __>IDE

    __>Для Nemerle нужна поддержка в IDE.
    __>На данный момент интеграция Nemerle в VS немного сыровата.

    Я бы сказал "интеграция Nemerle в VS уже немного сыровата."
    Help will always be given at Hogwarts to those who ask for it.
    Re[2]: Каковы перспективы языка?
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 16.03.07 19:00
    Оценка:
    Здравствуйте, geniepro, Вы писали:

    G>Здесь имеются люди, очень сильно сомневающиеся в перспективах Хаскелла, несмотря на наличие кучи статей и книг серьёзных дядек по Хаскеллу, разных проектов и даже обучения Хаскеллу в американских ВУЗах (не всех, конечно, но всё же, во всяких там Оксфордах и пр.), а так же поддержки со стороны Майкрософта. Тем не менее, несмотря на всё это, есть тут люди, которые в перспективы Хаскелла совершенно не верят... :о)


    Что-то я вообще не заметил людей у каоторых есть сомнения на счет Хаскеля. Есть две группы людей: 1. Люди не сомневающиеся в том, что Хаскель — это чисто эксперементальный язык которому не грозит практическое прпмененеие в промышелнном программировании. 2. Люди которые верят в Хаскель. Последних мизер.

    G>Если продолжить их логику, то у Немерле перспектив в принципе быть не может. Но я с ними не согласен! :о)).


    Как раз у Немерлея то в отличии от Хаскеля переспективы более чем осязаемые. Он является совершенно практическим языком. Так что обсуждать тмут можно только станет ли он популярным и насколько. А в его практической применеимости вопросы вообще не возникают. Раз уж C# и Ява практически применимы, то и он подавно. Ведь Немерле можно рассматривать как расширение C#. Это как с С/С++.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[2]: Каковы перспективы языка?
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 16.03.07 22:34
    Оценка:
    Здравствуйте, Ka3a4oK, Вы писали:

    KK>Я решил выучить что-нибудь кроме C++. Интерес больше практичесий, чем академический. Я смотрел на Lisp, затем на Python, остановился на Nemerle. Net рано или поздно придется учить(допустим это бесспорно). Net это больше идеология, среда, библиотеки и меньше язык. Мне кажется, все равно с помощью какого языка изучать Net. Если Nemerle тупик, то я, уже зная Framework, перейду на другой язык(С#) с малыми потерями.


    Мысаль разумная.

    KK>Проблема новых языков, отсутствие библиотек. У Nemerle такой проблемы нет. Мне кажется хорошей идеей книга из серии "изучаем Net" с примерами на Nemerle(менее радикально на Nemerle и C#).


    Пока что лучшим введением в дотнет является книга Рихтера "CLR via C#".
    Очень рекомендую. C# можно соотнести с Nemerle как C c C++ (или как С++ 1.0 и С++ 3.0), то есть как надмножество дающее возможность использовать другие парадигмы. Только если С предоставлял только структурное программирвоание, то C# сразу содежит ООП. Немерле же расширяет его фунциональным программированием и метапрограммированием. C# переводится в Nemerle в полностью автоматическом режме. Так что заучив некоторый список отличий ты сможешь без проблем читать программы на обоих языках и переводить (мысленно) один в другой (точнее C# в Nemerle, так как обратное возможно далеко не всегда).

    KK> Примерами, показывающими превосходство Nemerle.


    Разница между Nemerle и C# лежит несколько в более высокой области нежели дотнет. На уровне поддержки дотнета они близнецы браться. Но уровень .Net — это довольно низкий уровень — уровень рантайма. По сути и C# и Nemerle это больше чем дотнет.

    Nemerle имеет приемущества в области декомпозиции кода, проектирования, кодирования и т.п.

    KK>Очень важна нормальная интеграция Nemerle в Visual Studio. Неискушенный программист может выбрать C# только из-за более удобной поддержки среды разработки.


    Согалсен. Над этим мы работаем, но конечно ресурсов у нас не столько сколько у МС. У МС на создание хорошей стреды для Шарпа ушло много лет. Мы пока работаем меньше года. Кое что уже есть, но честно признаюсь поддержка среды для Шарпа пока лучше.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[3]: Каковы перспективы языка?
    От: ravlyk Австралия http://stitcharteasy.com
    Дата: 23.05.07 12:56
    Оценка:
    KK>>Очень важна нормальная интеграция Nemerle в Visual Studio. Неискушенный программист может выбрать C# только из-за более удобной поддержки среды разработки.

    VD>Согалсен. Над этим мы работаем, но конечно ресурсов у нас не столько сколько у МС. У МС на создание хорошей стреды для Шарпа ушло много лет. Мы пока работаем меньше года. Кое что уже есть, но честно признаюсь поддержка среды для Шарпа пока лучше.


    А попробовать встроить его в SharpDevelop?
    Re: Каковы перспективы языка?
    От: lonli Беларусь  
    Дата: 11.06.07 12:20
    Оценка:
    Здравствуйте, Ka3a4oK, Вы писали:

    KK>Меня интересуют факты свидетельствующие о перспективности языка Nemerle. Кто еще заинтересовался в языке, кроме энтузиатов? Статьи серьезных дядек, проекты и т.д.


    Блин не помню где встречал обсуждение VladD2 о том, что M$ ограничивает развитие новых языков тем, что их не поддерживает. Так что напишу сюда...
    Прочитал в ОЖ что Гугл компанию какую-то купил. А может стоит предложить развитие такого перспективного языка не M$ а Гуглу?
    Ребенка с первого класса школы надо учить науке одиночества. ©Ф.Раневская
    Re[2]: Каковы перспективы языка?
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 12:38
    Оценка:
    Здравствуйте, _nn_, Вы писали:

    __>
  • IDE
    __>Для Nemerle нужна поддержка в IDE.
    __>На данный момент интеграция Nemerle в VS немного сыровата.

    Сыровата, но работать в ней, в основном, можно

    __>
  • Установка
    __>Легкость установки Nemerle ни у кого не вызывает сомнения.
    __>Обычному пользователю нужен файл установки после которого все будет работать. Увы этого еще нет.

    Мммм? Правда? А как же я установил Немерле на свой компьтер? Ммммм.... неужели я скомпилировал код и даже этого не заметил?.. ну я гений...

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


    Зачем, достаточно пользоваться той версией, которая есть, иногда её обновляя. Я вот пользуюсь без всяких обновлений и пока как-то не чувствую, что компилятор нужно каждую неделю обновлять
  • Re[2]: Ну конечно у Немерле нет будущего :)
    От: desco США http://v2matveev.blogspot.com
    Дата: 11.06.07 13:15
    Оценка:
    Здравствуйте, FDSC, Вы писали:



    FDS>Ещё неудобство, например я хочу вернуть result


    FDS>Я не могу написать так:

    FDS>if (condition)
    FDS>{
    FDS> def result = kjsdhfjklasdh()
    FDS>}
    FDS>else
    FDS>{
    FDS> def result = werioptuertj();
    FDS>}
    FDS>Calc(result)

    FDS>Нужно писать так:

    FDS>mutable result; // def result тоже не будет работать без инициализации
    FDS>if (condition)
    FDS>{
    FDS> result = kjsdhfjklasdh()
    FDS>}
    FDS>else
    FDS>{
    FDS> result = werioptuertj();
    FDS>}
    FDS>Calc(result)

    FDS>Это тоже крайне неудобно


    а почему не просто

    def result = if (condition) kjsdhfjklasdh() else werioptuertj();
    Calc(result)
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 14:15
    Оценка:
    Здравствуйте, IT, Вы писали:

    IT>Нет, нужно писать так:


    IT>
    IT>def result =
    IT>  if (condition)
    IT>  {
    IT>    kjsdhfjklasdh()
    IT>  }
    IT>  else
    IT>  {
    IT>    werioptuertj();
    IT>  }
        
    IT>Calc(result)
    IT>


    Ага и еще не ясно зачем эти фигурные скобки. Без них можно в одну строку уложиться:
    def result = if (condition) kjsdhfjklasdh() else werioptuertj();
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 14:52
    Оценка:
    Здравствуйте, IT, Вы писали:

    IT>Так ты не можешь написать нигде.


    Да, но в Nemerle это усугубляется тем, что все переменные константны и такая запись требуется

    FDS>>Нужно писать так:


    IT>Нет, нужно писать так:


    IT>
    IT>def result =
    IT>  if (condition)
    IT>  {
    IT>    kjsdhfjklasdh()
    IT>  }
    IT>  else
    IT>  {
    IT>    werioptuertj();
    IT>  }
        
    IT>Calc(result)
    IT>


    Когда это возможно, я пишу так, но, вполне возможно, я захочу вызвать в теле уловия ещё какую-то функцию после вычисления неужного значения — тогда этот код не сработает.
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:02
    Оценка:
    Здравствуйте, Vermicious Knid, Вы писали:

    VK>Гы. Здесь все ясно как божий день. Ты производишь целочисленное деление 1 и 8(оба аргумента — целые числа, чего же ты хочешь ). Если тебе это кажется недостатком — welcome to Haskell, OCaml, etc. Мне лично работа с числами в этих языках раздражает значительно больше, чем работа с числами в C++/C#/Nemerle. Еще кажется в Паскале целочисленное деление отдельная операция, меня это бесило, когда приходилось иметь с ним дело(как же давно это было ).


    А вот мне наоборот это очень нравилось и не так уж давно я последний раз пользовался операцией div, хотя, лично мне, она нужна крайне редко и 1/8 = 0 в C++ у меня вызывает только недоумение

    FDS>> и прибавился недостаток в виде возможности повторного определения переменной в коде (лично я не понял, зачем это сделано).


    VK>В C# конечно такой номер не проходит, но нужно понимать разницу между C# и Nemerle, где выражения(и блоки кода) играют роль как-бы кубиков конструктора и дополнительная гибкость совсем не лишняя.


    Личное моё мнение — лишняя. Благо в Немерле всегда можно объявить вложенную функцию

    FDS>>Циклы на нём писать то же не удобно, вместо простого int i = 0 нужно писать mutable i = 0

    VK>Ерунда. Лично я на Nemerle очень редко использую for(; ; ) цикл, фактически никогда не использую. Во-первых foreach позволяет делать так:
    VK>
    VK>foreach(i in [0..n-1])
    VK>


    Спасибо, не знал

    VK>Во-вторых для есть такие функции как FoldI, FindIndex, IterI. По поводу mutable, я в самом начале своего знакомства с Nemerle использовал макрос var, а потом забил на это и теперь стараюсь просто как можно меньше использовать mutable.


    Я использую mutable почти только в for
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: rameel https://github.com/rsdn/CodeJam
    Дата: 11.06.07 15:03
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Когда это возможно, я пишу так, но, вполне возможно, я захочу вызвать в теле уловия ещё какую-то функцию после вычисления неужного значения — тогда этот код не сработает.


    Что мешает возвращать вычисленное значение последним
    ... << RSDN@Home 1.2.0 alpha rev. 693>>
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 15:04
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Когда это возможно, я пишу так, но, вполне возможно, я захочу вызвать в теле уловия ещё какую-то функцию после вычисления неужного значения — тогда этот код не сработает.


    Прмер, в студию, плиз. Уверяю тебя, что нет такого случая когда бы нельзя было бы написать "так".
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 15:04
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    VD>>
    VD>>Calc(if (condition) kjsdhfjklasdh() else werioptuertj())
    VD>>

    VD>>получается даже гороче и понятнее.

    FDS>Тебе, может, и понятнее, а я, если бы увидел такую строку, незамедлительно бы переписал её через вспомогательную переменную


    Ты просто привык к плохому. На самом деле я бы и на Шарпе неапсал бы так:
    Calc(condition ? kjsdhfjklasdh() : werioptuertj())
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 15:04
    Оценка:
    Здравствуйте, Vermicious Knid, Вы писали:

    VK>Во-вторых для есть такие функции как FoldI, FindIndex, IterI. По поводу mutable, я в самом начале своего знакомства с Nemerle использовал макрос var, а потом забил на это и теперь стараюсь просто как можно меньше использовать mutable. Кажется были предложения заменить mutable на var, но дальше предложений дело не пошло(авторы языка кажется согласились на добавление макроса var). Лично я не против варианта с добавлением var в качестве ключевого слова полностью равнозначного mutable(то есть для членов классов тоже), но боюсь, что многие от этой идеи будут не в восторге.


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

    ЗЫ (офтоп)

    Ты что-то говорил о реализации макросов-расширений. Ты не хотел бы этим заняться?
    А то разработчики компилятора явно в боятся этим заниматься.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 15:13
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>А вот мне наоборот это очень нравилось и не так уж давно я последний раз пользовался операцией div, хотя, лично мне, она нужна крайне редко и 1/8 = 0 в C++ у меня вызывает только недоумение


    Дело привычки. Меня тоже div бесит. Сколько я в свое время ошибок из-за этого соврешил...

    FDS>Личное моё мнение — лишняя. Благо в Немерле всегда можно объявить вложенную функцию


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

    Это и есть фунциональный стиль, когда ты не перечисляешь операторы меняющие стостояние, а пишешь некое вычисление которое возвращает значение. При этом все предсказуемо и просто. Вычисление подчиняется законом дривовидной структуры.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:20
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Прмер, в студию, плиз. Уверяю тебя, что нет такого случая когда бы нельзя было бы написать "так".


    Согласен. Есть случаи, когда так писать не очень удобно. Я пишу так, как думаю, и на Немерле, в частности, пишу именно из-за того, что этот язык позволяет мне писать именно мои мысли
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:22
    Оценка:
    Здравствуйте, rameel, Вы писали:

    R>Что мешает возвращать вычисленное значение последним


    Например, код с побочными эффектами, который явно/неявно использует result
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:26
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Ты просто привык к плохому. На самом деле я бы и на Шарпе неапсал бы так:

    VD>
    VD>Calc(condition ? kjsdhfjklasdh() : werioptuertj())
    VD>


    Влад, это ты привык к плохому Эта каша просто нечитается

    Ты мне скажи, ты что так и думаешь:

    "вот, сейчас я вызову функцию расчёта чего-то там, а в неё передам результат работы функции kjsdhfjklasdh, если условие выполнено, иначе — werioptuertj"?

    Лично я думаю по другому:

    "Сейчас я рассчитаю чего-то там, этому чему-то требуется такие-то исходные данные. Как их вычислить: если condition, то исходные данные выч. функцией kjsdhfjklasdh, иначе — werioptuertj"

    Разница принципиальна, вплоть до повышения количества ошибок приблизительно в 2,5 раза при переходе с моего варианта на твой
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:36
    Оценка:
    Здравствуйте, VladD2, Вы писали:

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


    FDS>>Когда это возможно, я пишу так, но, вполне возможно, я захочу вызвать в теле уловия ещё какую-то функцию после вычисления неужного значения — тогда этот код не сработает.


    VD>Прмер, в студию, плиз. Уверяю тебя, что нет такого случая когда бы нельзя было бы написать "так".


    Вот это разве красиво смотрится?
                    fres = 
                    
                    if (klast != [])
                    {
                        def (incDx, cflast) = GetDx(klast, flast);
                        for (mutable i = 0; i < Lf; i++)
                        {
                            dx[i] += incDx[i];
                        }
                        cf::cflast;
                    }
                    else
                    {
                        [];
                    };
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 15:39
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Дело привычки. Меня тоже div бесит. Сколько я в свое время ошибок из-за этого соврешил...


    А сколько я нулей получил в C++ ... меня бесит 1/8 = 0

    FDS>>Личное моё мнение — лишняя. Благо в Немерле всегда можно объявить вложенную функцию


    VD>Это даже не гигкость. Это идеология. Все есть выражение. Нет таках случаев в Немерле, чтобы в выражение нельзя было засунуть все что угодно и наоборот, чтобы нельзя было засунуть выражение куда угодно.


    +

    VD>Это и есть фунциональный стиль, когда ты не перечисляешь операторы меняющие стостояние, а пишешь некое вычисление которое возвращает значение. При этом все предсказуемо и просто. Вычисление подчиняется законом дривовидной структуры.


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

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

    Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):
    public module IntegrationSchems
        {
    // .....
    
            public Adams5k: list[double] = [1901.0, -2774.0, 2616.0, -1274.0, 251.0];
            public Adams5c: double = 1.0/720.0;        
    
            // Общая реализация схем Адамса
            // K : массив коэффициентов для суммы функций
            // k : множитель при всей сумме (т.е. множитель при величине шага)
            // CalculatedPoints: массив уже вычисленных точек
            // CalcI - номер текущей точки, подлежащей вычислению
            // f - функция для вычисления правой части уравнений
            // F - объект, хранящий уже вычисленные правые части уравнений
            public Adams(K: list[double], k : double, CalculatedPoints: array[2, double], CalcI: int, f: array[double], F: list[array[double]]): list[array[double]]
            {
    
                def GetDx(K, F)
                {
                    def (ck: double :: klast) = K;
                    def (cf: array[double] :: flast) = F;
                    
                    def Lf = cf.Length;
                    
                    mutable fres;
                    
                    def dx = array(Lf);
                    for (mutable i = 0; i < Lf; i++)
                    {
                        dx[i] = cf[i] * ck;
    //                    Console.WriteLine($"$(cf[i]) * $(ck)");
                    }
    
                    if (klast != [])
                    {
                        def (incDx, cflast) = GetDx(klast, flast);
                        for (mutable i = 0; i < Lf; i++)
                        {
                            dx[i] += incDx[i];
                        }
                        fres = cf::cflast;
                    }
                    else
                    {
                        fres = [];
                    };
                    
                    (dx,  fres)
                }
    
                def SetNewPoint(dx, t)
                {
                    def L = CalculatedPoints.GetLength(0);
                    for (mutable i = 1; i < L; i++)
                    {
                        CalculatedPoints[i, CalcI] = dx[i - 1] * t * k + CalculatedPoints[i, CalcI - 1];
                    }
                }
    
                // Шаг интегрирования
                def t = CalculatedPoints[0, CalcI] - CalculatedPoints[0, CalcI - 1];
            
                def (dx, result) = GetDx(K, f :: F);
    
                SetNewPoint(dx, t);
                            
                result;
            }
            
            // Метод Рунге-Кутты
            public RK(K: list[list[double]],
                      CalculatedPoints: array[2, double],
                      CalcI: int, I0: int, I1: int, f: int *int * int * double * array[1, double] -> array[double], F: list[array[double]]): list[array[double]]
            {
                def L      = CalculatedPoints.GetLength(0);
                def t      = CalculatedPoints[0, CalcI] - CalculatedPoints[0, CalcI - 1];
            
                def (kList :: ktail) = K;
                def (k :: klt)       = kList;
                
                mutable RKresult: array[double] = array(L - 1);
    
                
                // Обяъвления типов из-за забытого индекса: иначе сообщения об ошибке выдавались не там, где надо из-за того,
                // что компилятор думал, что типы передаваемых значений другие
                // К тому же так просто более понятен смысл
                
                // Получить список вспомогательных коэффициентов
                // В каждом списке в k содержимое: [множитель при t, множитель при младшем (с меньшим индексом) коэффициенте, .., при старшем коэффициенте]
                def GetKs(k: list[list[double]], fn: list[array[double]])
                {
                    // Найти приращение к аргументу x функции f (т.е. f(x + Ksm, t + t * kt) )
                    def GetKsm(kn: list[double], fn: list[array[double]])
                    {
                        if (fn == [] || kn == [])
                        {
                                def result = array(L);
                                for (mutable i = 0; i < L - 1; i++)
                                {
                                    result[i] = 0.0;
                                }
                                result;
                        }
                        else
                        {
                            def (fi :: ftail) = fn;
                            def (k  :: ktail) = kn;
    
                            def result = MGauss.MatrixCopy(fi);
                            for (mutable i = 0; i < L - 1; i++)
                            {
                                result[i] *= k;
                            }
    
                            if (ktail != [])
                            {
                                def Ksm    = GetKsm(ktail, ftail);
                                for (mutable i = 0; i < L - 1; i++)
                                {
                                    result[i] += Ksm[i];
                                }
                                result;
                            }
                            else
                            {
                                result;
                            }
                        }
                    }
    
                    def (kf :: ktail) = k;
                    def (kt :: kn)    = kf;
                    
                    
                    def xn  = array(L - 1);
                    def Ksm = GetKsm(kn, fn);
                    
                    for (mutable i = 0; i < L - 1; i++)
                    {
                        xn[i] = CalculatedPoints[i + 1, CalcI - 1] + Ksm[i];
                    }
    
                    // Найти приращение к t (т.е. f(x + Ksm, t + t * kt)
                    def tn = t * kt + CalculatedPoints[0, CalcI - 1];
                    
                    def fi = f(CalcI, I0, I1, tn, xn);
                    
    
                    if (fn == [])
                    {
                        for (mutable i = 0; i < L - 1; i++)
                          RKresult[i] = fi[i];
                    }
                    else {};
    
                    
                    for (mutable i = 0; i < L - 1; i++)
                    {
                        fi[i] *= t;
                    }                
    
                    if (ktail != [])
                        GetKs(ktail, fi::fn);
                    else
                        fi::fn;                     // старший коэффициент (с большим индексом) в начале списка
                }
                
                
                
                // Просуммировать их с соотв. коэффициентами, получив приращение
                // В k - [общий множитель, множитель при старшем коэффициенте, ..., множитель при младшем коэффициенте ]
                def GetSummK(k: list[double], ks: list[array[double]])
                {
                    def result = array(L - 1);
                    
                    // Вычислить следующее слагаемое суммы
                    def GetSumm(k, ks): void
                    {
                        def (kl  :: klt ) = k;
                        def (ksl :: kslt) = ks;
    
                        for (mutable i = 0; i < L - 1; i++)
                        {
                            result[i] += kl * ksl[i];
                        }
    
                        if (klt != [])
                        {
                            GetSumm(klt, kslt);
                        }
                        else {};
                    }
                
                    def (kl  :: klt ) = k;
                    def (ksl :: kslt) = ks;
                    
                    // Первое слагаемое суммы вычислить тут, так как всё равно нужно инициализировать массив
                    for (mutable i = 0; i < L - 1; i++)
                    {
                        result[i] = kl * ksl[i];
                    }
                    
                    if (klt != [])
                    {
                        GetSumm(klt, kslt);
                    }
                    else {};
                    
                    result;
                }
                
                
                def ks     = GetKs   (ktail, []);   // Получить список вспомогательных коэффициентов и result
                def dx     = GetSummK(klt, ks);     // Просуммировать их с соотв. коэффициентами, получив приращение
    
                for (mutable i = 1; i < L; i++)
                {
                    CalculatedPoints[i, CalcI] = k * dx[i - 1] + CalculatedPoints[i, CalcI - 1];
                }
    
                RKresult :: F;                    // Результат функции - список вычисленных значений правых частей в точках интегрирования
            }
            
    // ....
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: rameel https://github.com/rsdn/CodeJam
    Дата: 11.06.07 16:18
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Например, код с побочными эффектами, который явно/неявно использует result


    И чем в этом случае mutable нам поможет, в твоем примере выше с mutable ты от побочного эффекта бы не избавился в отличие от
    ... << RSDN@Home 1.2.0 alpha rev. 693>>
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: Vermicious Knid  
    Дата: 11.06.07 16:49
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Вот это разве красиво смотрится?

    FDS>
    FDS>                fres = 
                    
    FDS>                if (klast != [])
    FDS>                {
    FDS>                    def (incDx, cflast) = GetDx(klast, flast);
    FDS>                    for (mutable i = 0; i < Lf; i++)
    FDS>                    {
    FDS>                        dx[i] += incDx[i];
    FDS>                    }
    FDS>                    cf::cflast;
    FDS>                }
    FDS>                else
    FDS>                {
    FDS>                    [];
    FDS>                };
    FDS>

    Ну так может и не очень. А вот так уже чуть лучше:
                        def ApplyDx(incDx, cflast)
                        {
                            for(i in [0..Lf-1])
                                dx[i] += incDx[i];
                            cf :: cflast
                        }
                        def fres = if (klast is []) [] else ApplyDx(GetDx(klast, flast));
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 17:29
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Вот это разве красиво смотрится?

    FDS>
    FDS>                fres = 
                    
    FDS>                if (klast != [])
    FDS>                {
    FDS>                    def (incDx, cflast) = GetDx(klast, flast);
    FDS>                    for (mutable i = 0; i < Lf; i++)
    FDS>                    {
    FDS>                        dx[i] += incDx[i];
    FDS>                    }
    FDS>                    cf::cflast;
    FDS>                }
    FDS>                else
    FDS>                {
    FDS>                    [];
    FDS>                };
    FDS>


    Если выбросить лишние скобки, то вполне себе ничего:
    def fres = 
        if (klast != [])
        {
                def (incDx, cflast) = GetDx(klast, flast);
                foreach (i in $[0..Lf - 1])
                        dx[i] += incDx[i];
                cf :: cflast;
        }
        else [];

    Если кода в теле if-а становится много, то можно, как предложил VKnid вынести его в локальную функцию. В интеграции она автоматически схлопнется и будет выглядеть очень прилично. А если надо распхнешь ее и посмотришь.
    У этого способа есть еще одно приемущество. Название фунции за одно автоматически документирует код.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 17:29
    Оценка:
    Здравствуйте, FDSC, Вы писали:

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


    VD>>Ты просто привык к плохому. На самом деле я бы и на Шарпе неапсал бы так:

    VD>>
    VD>>Calc(condition ? kjsdhfjklasdh() : werioptuertj())
    VD>>


    FDS>Влад, это ты привык к плохому Эта каша просто нечитается


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

    FDS>Ты мне скажи, ты что так и думаешь:


    FDS>"вот, сейчас я вызову функцию расчёта чего-то там, а в неё передам результат работы функции kjsdhfjklasdh, если условие выполнено, иначе — werioptuertj"?


    Ну, с твоими названиями я вообще думать не могу. Мозг отключаетя .
    А вообще, я не вижу проблемы. Мы передаем фукнции результат вычисления некоторого выражения. Если оно короткое, то почему бы его не поместить прмямо в параметр фунции? Это и читается просто. И смысл полностью передает. Если я и ввожу перменные в таких случаях, то только если хочу в отладчике поглядеть значение передающееся в параметр.

    FDS>Лично я думаю по другому:


    FDS>"Сейчас я рассчитаю чего-то там, этому чему-то требуется такие-то исходные данные. Как их вычислить: если condition, то исходные данные выч. функцией kjsdhfjklasdh, иначе — werioptuertj"


    Ты думашь императивно.
    На самом деле есть выражение значение которого ты передаешь в функцию Calc. И совершенно пофигу будет ли значение этого выражения помещено в переменную или нет.

    FDS>Разница принципиальна, вплоть до повышения количества ошибок приблизительно в 2,5 раза при переходе с моего варианта на твой


    Разница у тебя в голове. Это как с общением. Один легко подходит к кому угодно и спрашивает, что хочет, а другой боится рот открыть с незнакомцем, а на публике вообще входит в ступор и колотун от страха. А меж тем разница только в том, что у одного нет тараканов в голове, а у другого внетренее табу (предрассудок на уровне животного чувства). Взгляни на мир более прагматично и поймешь, что то о чем ты говоришь не более чем предрассудок.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 17:29
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>А сколько я нулей получил в C++ ... меня бесит 1/8 = 0


    Я тебе и говорю — дело привычки. В школе ты как-то обходился без div ведь?

    FDS>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):...


    Что я могу сказать? Это код не совсем на Немерле. Это промежуточный код на эдаком C#++. Его можно очень хорошо причесать.
    В прочем, с точки зрения производительнолсти он наверно неполох.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 18:02
    Оценка:
    Здравствуйте, VladD2, Вы писали:

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


    Ну, для меня это — плохо читаемая каша...

    FDS>>Ты мне скажи, ты что так и думаешь:


    FDS>>"вот, сейчас я вызову функцию расчёта чего-то там, а в неё передам результат работы функции kjsdhfjklasdh, если условие выполнено, иначе — werioptuertj"?


    VD>Ну, с твоими названиями я вообще думать не могу. Мозг отключаетя .


    Ну дак я же просто по клавиатуре прошёлся пальцами...

    VD>А вообще, я не вижу проблемы. Мы передаем фукнции результат вычисления некоторого выражения. Если оно короткое, то почему бы его не поместить прмямо в параметр фунции? Это и читается просто. И смысл полностью передает. Если я и ввожу перменные в таких случаях, то только если хочу в отладчике поглядеть значение передающееся в параметр.


    Ну, лично у меня статистика ошибок при кодировании увеличивается, причём чувствительно, если я делаю несколько операций одновременно в одной строке


    FDS>>"Сейчас я рассчитаю чего-то там, этому чему-то требуется такие-то исходные данные. Как их вычислить: если condition, то исходные данные выч. функцией kjsdhfjklasdh, иначе — werioptuertj"



    VD>На самом деле есть выражение значение которого ты передаешь в функцию Calc. И совершенно пофигу будет ли значение этого выражения помещено в переменную или нет.


    Конечно пофигу. Важно разделить две операции — вызов функции с параметром и вычисление параметра — они не связаны друг с другом

    FDS>>Разница принципиальна, вплоть до повышения количества ошибок приблизительно в 2,5 раза при переходе с моего варианта на твой


    VD>Разница у тебя в голове. Это как с общением. Один легко подходит к кому угодно и спрашивает, что хочет, а другой боится рот открыть с незнакомцем, а на публике вообще входит в ступор и колотун от страха. А меж тем разница только в том, что у одного нет тараканов в голове, а у другого внетренее табу (предрассудок на уровне животного чувства). Взгляни на мир более прагматично и поймешь, что то о чем ты говоришь не более чем предрассудок.


    Ага, попробуй взять студента и спросить у него, скажем, формулу Остроградского, запретив при этом писать в математических выражениях
    Понимаешь о чём я говорю? Когда записываешь что-то не так, как думаешь, тебе приходится выполнять в уме дополнительные преобразования, которые увеличивают вероятность возникновения ошибки
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 11.06.07 18:11
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Что я могу сказать? Это код не совсем на Немерле. Это промежуточный код на эдаком C#++. Его можно очень хорошо причесать.


    Ну я и не особо преследовал цель писать на Немерле, мне как раз нужен был inc(C#) (это я не показал реализацию метода перемещений... там вообще от Немеле камня на камне не осталось, что-то дельфиподобное получилось).

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

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


    Да, не жалуюсь, как ни странно. Даже удивился, ожидал более медленной работы
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: WolfHound  
    Дата: 11.06.07 19:45
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):

    Как-то так:
    public module IntegrationSchems
    {
        public MapI [From, To] (this from : array [From], f : int * From -> To) : array [To]
        {
          if (from == null)
            array(0)
          else
          {
            def result = array (from.Length);
    
            for (mutable i = 0; i < from.Length; ++i)
              result [i] = f (i, from [i]);
    
            result
          }
        }
    
    
        public Adams5k: list[double] = [1901.0, -2774.0, 2616.0, -1274.0, 251.0];
        public Adams5c: double = 1.0/720.0;        
    
        // Общая реализация схем Адамса
        // K : массив коэффициентов для суммы функций
        // k : множитель при всей сумме (т.е. множитель при величине шага)
        // CalculatedPoints: массив уже вычисленных точек
        // CalcI - номер текущей точки, подлежащей вычислению
        // f - функция для вычисления правой части уравнений
        // F - объект, хранящий уже вычисленные правые части уравнений
        public Adams // когда у функции много параметров их нужно разносить на разные строчки. Так лучше читается.
            ( K : list[double]
            , k : double
            , CalculatedPoints : array[2, double]
            , CalcI : int
            , f : array[double]
            , F : list[array[double]]
            ) : list[array[double]]
        {
    
            def GetDx(_, _)
            {
            | ([ck], [cf]) =>
                (cf.Map(_ * ck), [])
                
            | (ck :: klast, cf :: flast) =>
                def (incDx, cflast) = GetDx(klast, flast);
                (cf.MapI((i, f) => f * ck + incDx[i]), cf :: cflast)
            
            | _ => throw Exception();//Если списки разной длинны.
            }
    
    //Дальше не переписывал
            def SetNewPoint(dx, t)
            {
                def L = CalculatedPoints.GetLength(0);
                for (mutable i = 1; i < L; i++)
                {
                    CalculatedPoints[i, CalcI] = dx[i - 1] * t * k + CalculatedPoints[i, CalcI - 1];
                }
            }
    
            // Шаг интегрирования
            def t = CalculatedPoints[0, CalcI] - CalculatedPoints[0, CalcI - 1];
        
            def (dx, result) = GetDx(K, f :: F);
    
            SetNewPoint(dx, t);
                        
            result;
        }
        public Main() : void
        {
        }    
    }

    Кстати имена получше подбирай, а то вобще не понятно что к чему.

    2 VladD2 еще один метод в библиотеку.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Пусть это будет просто:
    просто, как только можно,
    но не проще.
    (C) А. Эйнштейн
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: Константин Л. Франция  
    Дата: 11.06.07 19:59
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Здравствуйте, Иванков Дмитрий, Вы писали:


    ИД>>Здравствуйте, FDSC, Вы писали:


    FDS>>>Вот что у меня получилось в итоге (может это можно сделать проще и понятнее? Как?):

    FDS>>>
                    
    FDS>>>                def Lf = cf.Length;
    FDS>>>                def dx = array(Lf);
    FDS>>>                for (mutable i = 0; i < Lf; i++)
    FDS>>>                {
    FDS>>>                    dx[i] = cf[i] * ck;
    FDS>>>//                    Console.WriteLine($"$(cf[i]) * $(ck)");
    FDS>>>                }
    ИД>>

    ИД>>Проще так:
    ИД>>
    ИД>>def dx = Nemerle.Utility.NArray.Map (cf, _ * ck);
    ИД>>

    FDS>И что это такое??? Я нефига не понял...

    подозреваю, что Map бегает по массиву и для каждого elem вызывает elem *= ck. А вот как грамотно называется _ * ck? Замыкание?

    FDS>Да и потом, это как раз упрощать не надо, это и есть просто. Точнее, просто, пока в императивном стиле
    Re[2]: Ну конечно у Немерле нет будущего :)
    От: Андрей Хропов Россия  
    Дата: 11.06.07 20:14
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Циклы на нём писать то же не удобно, вместо простого int i = 0 нужно писать mutable i = 0


    обычно достаточно

    foreach(i in $[0..n])
        ...
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: Mckey Россия  
    Дата: 11.06.07 21:04
    Оценка:
    Здравствуйте, Vermicious Knid, Вы писали:

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



    FDS>>С другой стороны у Немерле сохранился убивающий меня недостаток C++/C# — округление без предупреждений в выражениях по типу 1/8*pi — постоянно приходится думать, где компилятор округлит и как,


    В настоящее время уже практически полным автоматом пишу 1.0/8*pi

    VK>Ерунда. Лично я на Nemerle очень редко использую for(; ; ) цикл, фактически никогда не использую. Во-первых foreach позволяет делать так:

    VK>
    VK>foreach(i in [0..n-1])
    VK>

    VK>Во-вторых для есть такие функции как FoldI, FindIndex, IterI.

    Щас проверил свой самый большой пока класс на 7 страниц и нашел в нем только один for, и то лишь потому что там внутри действительно нужен индекс, а мапить индекс в тупл или сделать через foreach(i in [0..n-1]) не слишком производительно, потому как функция вызывается очень часто.

    Чаще всего использую использую Fold-ы, Map-ы и Iter-ы или некие собственные рекурсивные loop-ы, вроде этих:

    public Equals(Dat: Data): bool
      def walk_array (i)
        i >= count || (data[i]==Dat.data[i] && walk_array (i + 1))
      if (count != Dat.Count) false
      else walk_array(0)
    
    def LoopSelfData(i,j,k,p:int)
      data[i] =  Arr[j] |> _/p:double
      if (i == count-1) ()
      else if (k == p) LoopSelfData(i+1,j+1,1,p)
      else LoopSelfData(i+1,j,k+1,p)


    VK>По поводу mutable, я в самом начале своего знакомства с Nemerle использовал макрос var, а потом забил на это и теперь стараюсь просто как можно меньше использовать mutable. Кажется были предложения заменить mutable на var, но дальше предложений дело не пошло(авторы языка кажется согласились на добавление макроса var). Лично я не против варианта с добавлением var в качестве ключевого слова полностью равнозначного mutable(то есть для членов классов тоже), но боюсь, что многие от этой идеи будут не в восторге.


    Я тоже вначале использовал макрос с var, однако сейчас анализ показал что mutable присутствует только в объявлении некторых переменных класса, да и то после появления анонимных пропертей количество их также сокращается... Так что mutable виден сразу и из далека и от var-ов я уже отказался.

    И вообще когда я только начинал переходить на немерле — писал в основном в сишарповском стиле. Теперь иногда выпадает время переписать первоначальные варианты — до полного прохождения всех тестов просто комментирую первоначальные варианты методов и функций и дописываю по новому... в более функциональном стиле...
    Последующий анализ текстов показывает что 80% кода после этого занимают комментарии (старых тел методов).
    Nemerle рулит ... Уже месколько раз видел косые завистливые взгляды коллег которые пишут на шарпе, а особенно тех кто пишет на VB.NET.
    Делай добро и бросай его в воду...
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 23:36
    Оценка:
    Здравствуйте, Mckey, Вы писали:

    M>Щас проверил свой самый большой пока класс на 7 страниц и нашел в нем только один for, и то лишь потому что там внутри действительно нужен индекс, а мапить индекс в тупл или сделать через foreach(i in [0..n-1]) не слишком производительно, потому как функция вызывается очень часто.


    А почему ты считашь, что foreach(i in [0..n-1]) сильно медленее чем for?

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

    M>Последующий анализ текстов показывает что 80% кода после этого занимают комментарии (старых тел методов).
    M>Nemerle рулит ... Уже месколько раз видел косые завистливые взгляды коллег которые пишут на шарпе, а особенно тех кто пишет на VB.NET.

    Ого! Ты его в боевых условиях исползуешь? Если не сложно поделись, что за задачи решаешь.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 23:36
    Оценка:
    Здравствуйте, Константин Л., Вы писали:

    Первое и последнее предупреждение за оверквотинг.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 11.06.07 23:36
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Ну я и не особо преследовал цель писать на Немерле, мне как раз нужен был inc(C#) (это я не показал реализацию метода перемещений... там вообще от Немеле камня на камне не осталось, что-то дельфиподобное получилось).


    Скорее не Дельфиподобное, а Шарпподобное, но не суть. Вот Вольфахуд показал
    Автор: WolfHound
    Дата: 11.06.07
    как можно было бы поступить.

    FDS>Честно говоря, я даже не представляю себе, как его причёсывать так, что бы он получился на Немерле... но приложение с ним стало проще писать, я прямо почти перестал чувствовать какие-то ограничения со стороны языка


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

    Вот Mckey о чем-то подобном говорит: Re[3]: Ну конечно у Немерле нет будущего :)
    Автор: Mckey
    Дата: 12.06.07
    .

    Это не приходит моментально. Все кто изначально учился программировать на императивных языках вроде С, С++, Дельфи, С# и т.п., по началу пишут на Немерле как на С#+, потом как на С#++, а потом проникаются его истинной сутью. И после этого наступает настоящий драйв! Главное не зацикливаться на этом. Нужно просто каждый раз садясь писать код на Немерле пытаться применить новую фичу. Можно даже сначала писать код как получается, а потом думать как бы егом ожно было бы сжать используя функциональные фишки.

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


    FDS>Да, не жалуюсь, как ни странно. Даже удивился, ожидал более медленной работы


    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[10]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 07:43
    Оценка:
    Здравствуйте, VladD2, Вы писали:

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


    FDS>>Ага, попробуй взять студента и спросить у него, скажем, формулу Остроградского, запретив при этом писать в математических выражениях

    FDS>>Понимаешь о чём я говорю? Когда записываешь что-то не так, как думаешь, тебе приходится выполнять в уме дополнительные преобразования, которые увеличивают вероятность возникновения ошибки

    VD>Скажи, в твоих мыслях когда ты думашь об алгоритмах действительно временные переменные присуствуют?


    ГЫ LOL, Влад, предупреждать надо, я же чуть со стула не упал!!!

    Конечно присутствуют, иначе бы их не было. Смотри как получаются временные переменные

    Так, я хочу посчитать какую-то ерунду, ага, пишу

    Calc()


    Угу, для расчёта этой ерунды мне нужно туда передать базис задач Коши

    Calc(CauchyBasis)


    и вектор решений разрешающей СЛАУ

    Calc(CauchyBasis, ResultTransitions)


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


    При этом мысли могу течь немного в другом русле

    Я хочу обойти дерево

    MarkTree(tree)


    Если текущий (верхний) элемент дерева содержит вектор, который даёт нулевое скалярное произведение, с другим вектором, я его помечаю

    MarkTree(tree, vect)
    {
      if ( isNull( ScalarMul(vect, GetVectorValue(tree) ) ) )
      {
        MarkTree;
      }
      else {};
    }


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


      def smr = ScalarMul( vect, GetVectorValue(tree) );
      if ( isNull( smr ) )
      {
        MarkTree;
      }
      else {};


    Потому что потом ход моих мыслей по одной строке понять будет труднее, да и читается это труднее

    И т.д.
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 08:07
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Для начала нужно потихоничку побороть предрассудок заставляющий тебя думать, что if-ы это statment-ы, а не выражения. Потом изучить фунции вроде Map, Filter и т.п.


    Да нет у меня этого предрассудка, просто забываю об этом и выглядит это часто просто некрасиво
    Пойду искать и качать по этому делу документацию

    VD>Вот Mckey о чем-то подобном говорит: Re[3]: Ну конечно у Немерле нет будущего :)
    Автор: Mckey
    Дата: 12.06.07
    .


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


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


    Ну вот Map например — я не знал о существовании этой "фичи" — не мог и применить. Знал бы, сразу бы применил, потому как удобнее
    Просто само по себе ФП не имеет особых преимуществ перед процедурным программированием, его стоит применять только там, где оно даёт более ясный код.

    Просто на сайте вся документация разрознена, если бы они её объединили в архив, что бы можно было скачать один-два документа, возможно, многих проблем бы не было. А пользоваться on-line я не могу — у меня Dial-up — это дорого и очень медленно

    VD> И потихоничку стараться пробовать переписать код в немного более фунциональной манере. Вместо циклов пробовать использовать рекурсию (если это дуобнее) и т.п.


    Собственно, скажем, если удобна рекурсия, то на Немерле я всегда пишу рекурсией, её у меня там стало больше, чем в других языках, иногда это бывает откровенно удобнее, но не так часто рекурсия удобна, по крайней мере, в тех алгоритмах, которые я программирую
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 08:26
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

    Спасибо, одну вещь не понял.

    WH>
    WH>public module IntegrationSchems
    WH>{
           // здесь, я так понимаю, создаётся шаблонный метод MapI, а что значит "this from" в параметрах?
    WH>    public MapI [From, To] (this from : array [From], f : int * From -> To) : array [To]
    WH>}    
    WH>


    А исключение на разную длину списков вы зря поставили, хотя, конечно, правильно
    Re[11]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 08:31
    Оценка:
    Здравствуйте, IO, Вы писали:

    FDS>>Да нет у меня этого предрассудка, просто забываю об этом и выглядит это часто просто некрасиво


    IO>Аргумент "некрасиво" — это часто следствие предрассудка.


    Аргумент "некрасиво" — следствие эстетического чувства при взгляде на код: код выглядит как каша перемешанных символов. Я люблю код, в котором пустого места больше, чем заполненного, здесь это не поощряется

    Хотя, согласен, тут есть и привычка
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: Иванков Дмитрий Россия  
    Дата: 12.06.07 08:50
    Оценка:
    Здравствуйте, FDSC, Вы писали:

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


    FDS>Спасибо, одну вещь не понял.


    WH>>
    WH>>public module IntegrationSchems
    WH>>{
    FDS>       // здесь, я так понимаю, создаётся шаблонный метод MapI, а что значит "this from" в параметрах?
    WH>>    public MapI [From, To] (this from : array [From], f : int * From -> To) : array [To]
    WH>>}    
    WH>>


    Это метод-расширение, т.е. можно писать from.MapI (f), а не только MapI (from, f)
    This может стоять у первого параметра public static метода.
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: WolfHound  
    Дата: 12.06.07 08:54
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>А исключение на разную длину списков вы зря поставили,

    А по другому никак. Иначе получишь предупреждение от компилятора.

    FDS>хотя, конечно, правильно

    Вот именно. Себе верить нельзя. Те вобще.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Пусть это будет просто:
    просто, как только можно,
    но не проще.
    (C) А. Эйнштейн
    Re[11]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 12.06.07 13:38
    Оценка:
    Здравствуйте, FDSC, Вы писали:


    FDS>Вот тебе уже появились две переменные, насколько они временные — это уже другой вопрос


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

    FDS>При этом мысли могу течь немного в другом русле


    FDS>Я хочу обойти дерево


    FDS>
    FDS>MarkTree(tree)
    FDS>


    FDS>Если текущий (верхний) элемент дерева содержит вектор, который даёт нулевое скалярное произведение, с другим вектором, я его помечаю


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

    FDS>
    FDS>MarkTree(tree, vect)
    FDS>{
    FDS>  if ( isNull( ScalarMul(vect, GetVectorValue(tree) ) ) )
    FDS>  {
    FDS>    MarkTree;
    FDS>  }
    FDS>  else {};
    FDS>}
    FDS>


    FDS>В одной строке сразу вызов трёх функций, т.е. я не всегда мыслю вспомогательными переменными.


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

    FDS>Хотя такую строку я почти наверняка разложу на

    FDS>
    FDS>  def smr = ScalarMul(vect, GetVectorValue(tree));
    FDS>  if ( isNull( smr ) )
    FDS>  {
    FDS>    MarkTree;
    FDS>  }
    FDS>  else {};
    FDS>


    FDS>Потому что потом ход моих мыслей по одной строке понять будет труднее, да и читается это труднее


    Откровенно говоря не вижу разницы. Но вижу в обоих вариантах косяк с if-ом. Он как раз хорошо показывает, что ты не врено мыслишь о чем-то.

    По идее раз алгоритм на дереве, то тебе бы надо в этой фунции или вызывать его рекурсивно для подветок, или вообще вынести итерацию по дереву в отдельную фунцию, а сам алгоритм записать в более простом виде. Вот как сдела бы я:
    TraverseTree(node : Node) : IEnumerable[Node]
    {
        yield node;
        TraverseTree(node.Left);
        TraverseTree(node.Right);
    }
    ...
    foreach (node in TraverseTree(tree.Root))
        when (isNull(ScalarMul(vect, GetVectorValue(node))))
          MarkTree(node);

    Уж не знаю подрбностей алгоритма, но как-то так.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: Mckey Россия  
    Дата: 12.06.07 13:56
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>А почему ты считашь, что foreach(i in [0..n-1]) сильно медленее чем for?


    Мое мнение основывалось на когда-то ранее реализованном бенче:

    #pragma indent
    using System
    using System.Console
    using Nemerle.Collections
    using Nemerle.Diagnostics
    
    def sum = _ + _
    
    def fermat_t(n)
        def q = $[1..n]
        q.FoldLeft(0,sum)
        
    def fer_t(n)
        def ferm_t(x,acc)
            match(x)
                | 0 => acc
                | _ => ferm_t(x-1,acc+x)
        ferm_t(n,0)
        
    def fermat_p(n)
        $[1..n].Map(fermat_t).FoldLeft(0,sum)
    
    def fer_p(n,acc=0)
        match(n)
            | 0 => acc
            | _ => fer_p(n-1,acc+fer_t(n))
            
    def factorial(n)
        $[1..n].FoldLeft(1,_*_)
    
    def fact(n,acc=1)
        match(n)
            | 1 => acc
            | _ => fact(n-1,acc*n)
            
    def factoriallist(n)
        $[1..n].Map(factorial)
        
    def fibonacci(n)
        | 0 | 1 => 1
        | _ => fibonacci(n-2) + fibonacci(n-1)
        
    def fibonaccilist(n)
        $[1..n].Map(fibonacci)
    
    WriteLine(fermat_t(1))
    WriteLine(fer_t(1))
    WriteLine(fermat_t(2))
    WriteLine(fer_t(2))
    WriteLine(fermat_t(3))
    WriteLine(fer_t(3))
    WriteLine(fermat_p(1))
    WriteLine(fer_p(1))
    WriteLine(fermat_p(2))
    WriteLine(fer_p(2))
    WriteLine(fermat_p(3))
    WriteLine(fer_p(3))
    WriteLine(fermat_p(4))
    WriteLine(fer_p(4))
    WriteLine(factorial(5))
    WriteLine(fact(5))
    WriteLine(fact(10))
    WriteLine(factoriallist(5))
    WriteLine(fibonacci(5))
    WriteLine(fibonaccilist(5))
    time repeat (10000000) _ = factorial(10)
    time repeat (10000000) _ = fact(10)
    time repeat (10000000) _ = factorial(5)
    time repeat (10000000) _ = fact(5)
    time repeat (1000000) _ = fermat_p(20)
    time repeat (1000000) _ = fer_p(20)
    time repeat (10000000) _ = fermat_p(5)
    time repeat (10000000) _ = fer_p(5)
    _ = ReadLine()


    где реализация функций через рекурсию была в 10 раз быстрее чем через $[...].

    Однако...
    Пришлось провести достаточно серьезное исследование производительности различных типов циклов. Участвовали следующие реализации:

        public ApplyFunc(f: Vals->Vals): void
          for (mutable i = 0; i < count; i++)
            data[i] = f(data[i])
        
        public ApplyFuncFE(f: Vals->Vals): void
          foreach (i in $[0..count-1])
            data[i] = f(data[i])
        
        public ApplyFuncM(f: Vals->Vals): void
          data = data.Map(f)
          
        public ApplyFuncC(f: Vals->Vals): void
          data = data.ConvertAll(f)
          
        public ApplyFuncL(f: Vals->Vals): void
          def Loop(i)
            data[i] = f(data[i])
            if (i == count-1) ()
            else Loop(i+1)
          Loop(0)
              
        public ApplyFuncI(f: int*Vals->Vals): void
          for (mutable i = 0; i < count; i++)
            data[i] = f(i+1,data[i])
        
        public ApplyFuncIFE(f: int*Vals->Vals): void
          foreach (i in $[0..count-1])
            data[i] = f(i+1,data[i])
            
        public ApplyFuncIM(f: int*Vals->Vals): void
          data = Map2(data,$[1..count],(x,y)=>(y,x)).Map(f).ToArray()
        
        public ApplyFuncIL(f: int*Vals->Vals): void
          def Loop(i)
            data[i] = f(i+1,data[i])
            if (i == count-1) ()
            else Loop(i+1)
          Loop(0)
          
        public static Bench(apf: (Vals->Vals)->void, f: Vals->Vals, c: long, m: string): void
          WriteLine($"Bench $m function $c times:")
          time repeat(c) apf(f)
          
        public static BenchI(apfi: (int*Vals->Vals)->void, f: int*Vals->Vals, c: long, m: string): void
          WriteLine($"Bench $m function $c times:")
          time repeat(c) apfi(f)


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

    Затем все-таки (в среднем) цикл for... На третьем месте foreach — проигрыш порядка 5%, что для меня было неожиданно, с учетом выше приведенного примера. А вот циклы на основе Map-ов и ConvertAll-ов ведут себя по разному в зависимости от сложности передаваемой внутрь функции. Хотя выглядит функция ApplyFuncM очень кратко и красиво.
    Самой медленной оказалась функция ApplyFuncIM — но это и так было ясно — по количеству преобразований которые в ней производятся.

    VD>Ого! Ты его в боевых условиях исползуешь? Если не сложно поделись, что за задачи решаешь.


    Ну не такие уж они и боевые эти условия...
    Я уже как-то говорил что пишу программки для себя, никто надо мной не стоит и требует быстроты их реализации и т.д.
    В основном это задачи преобразования данных из одной базы данных с одним типом и количеством идентификационной информации и различными периодами этих данных — в данные другой базы данных соотвественно с другим типом и количеством идентификаторов и периодом этих данных. Плюс совмещение всех этих данных из различным баз данных с каком-то общем отчетном приложении. Через декларативное описание разметки вывода этих данных, периодов и применяемых к ним преобразований.
    Делай добро и бросай его в воду...
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 12.06.07 14:12
    Оценка:
    Здравствуйте, Mckey, Вы писали:

    M>Затем все-таки (в среднем) цикл for... На третьем месте foreach — проигрыш порядка 5%, что для меня было неожиданно, с учетом выше приведенного примера.


    Собственно о том и речь. По внешнему виду можно подумать, что foreach генерирует списки и пользуется итератором, что конечно относительно не быстро. Но на саом деле foreach отслеживает то что ему задают статический диапазон и генерирует для него специльный случай. То что он медленее на 5% — это логично, так как при этом генерируется не самый оптимльный код. Дело в том, что диапазон может быть как прирастающий, так и убывающий. По уму просто генерировать разный код и все, но разработчики этого макроса сделали чуть менее оптимально. Они заводят переменную говорящую увеличивать или уменьшать счетчик. Эта проверка каждый раз осуществляется в рантайме. На саом деле процессоры класса Core 2 могут вообще нивилировать разницу. Но все же она есть.
    Вот только это всего лишь не очень оптимальная реализция. Так что можно забить на нее (все равно она дает ухудшение, по твоим же словами, на 5% и это на практически пустом цикле). Рано или поздно макрос подправят и разница исчезнет. Так что лучше не жертвовать выразительностью кода.
    Если хочется, что бы неоптимальность исчезла раньше, то нужно просто добавить баг-репорт и привести там код из Рефлектора (который показывает суть проблемы).

    M> А вот циклы на основе Map-ов и ConvertAll-ов ведут себя по разному в зависимости от сложности передаваемой внутрь функции. Хотя выглядит функция ApplyFuncM очень кратко и красиво.


    Дык понятно. Накладные расходы на вызов больше. Если фунция делает что-то значительное, то они невилируются на ее фоне. Если она складывает 2 + 2, то ясный пень расходы на вызов можно увидеть. Только в рельной жизни это обычно тоже не создает проблем.

    M>Самой медленной оказалась функция ApplyFuncIM — но это и так было ясно — по количеству преобразований которые в ней производятся.


    Это скорее из-за того, что там операция $[1..count] превращается в создание реального списка каждый элемент которого — это объект создаваемый в памяти. Вот так действительно писать наврено не стоит. По крайней мере в критических местах.
    M>Я уже как-то говорил что пишу программки для себя, никто надо мной не стоит и требует быстроты их реализации и т.д.

    Хм. А, что тогда, за VB-кодеры с завистью смотрят из-за спины?

    M>В основном это задачи преобразования данных из одной базы данных с одним типом и количеством идентификационной информации и различными периодами этих данных — в данные другой базы данных соотвественно с другим типом и количеством идентификаторов и периодом этих данных. Плюс совмещение всех этих данных из различным баз данных с каком-то общем отчетном приложении. Через декларативное описание разметки вывода этих данных, периодов и применяемых к ним преобразований.


    Хм. Интересно... Правда не очень похоже на творчество для дома, для семьи.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: Mckey Россия  
    Дата: 12.06.07 14:57
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Собственно о том и речь. По внешнему виду можно подумать, что foreach генерирует списки и пользуется итератором, что конечно относительно не быстро. Но на саом деле foreach отслеживает то что ему задают статический диапазон и генерирует для него специльный случай. То что он медленее на 5% — это логично, так как при этом генерируется не самый оптимльный код. Дело в том, что диапазон может быть как прирастающий, так и убывающий. По уму просто генерировать разный код и все, но разработчики этого макроса сделали чуть менее оптимально. Они заводят переменную говорящую увеличивать или уменьшать счетчик. Эта проверка каждый раз осуществляется в рантайме. На саом деле процессоры класса Core 2 могут вообще нивилировать разницу. Но все же она есть.


    На нем и пытал... К сожалению — это дома — на работе такой красоты (Core 2 Duo 6600) нету...

    M>> А вот циклы на основе Map-ов и ConvertAll-ов ведут себя по разному в зависимости от сложности передаваемой внутрь функции. Хотя выглядит функция ApplyFuncM очень кратко и красиво.

    VD>Дык понятно. Накладные расходы на вызов больше. Если фунция делает что-то значительное, то они невилируются на ее фоне. Если она складывает 2 + 2, то ясный пень расходы на вызов можно увидеть. Только в рельной жизни это обычно тоже не создает проблем.

    Кстати непонятно почему ConvertAll так отстает...
    Например на таком коде он в почти в 5 раз быстрее...


    def l = ["PArAM_Simple","INGIS_Izm(Mon):34124","PIRAMIDA_Izm(3M):13:15","CK_Avg:7"]
    def lp = l.Map(_:>Par)
    // Первый две строки не так важны
    mutable i = 0
    time repeat(100000) Array.ForEach(Array.ConvertAll(lp.ToArray(),_.ToString),_x=>i++)
    WriteLine(i)
    i = 0
    time repeat(100000) lp.Map(_.ToString()).Iter(_x=>i++)
    WriteLine(i)
    i = 0
    time repeat(100000) Array.ForEach(lp.Map(_.ToString()).ToArray(),_x=>i++)
    WriteLine(i)


    Первый из бенчей в 5 раз быстрее чем два других..

    VD>Хм. А, что тогда, за VB-кодеры с завистью смотрят из-за спины?

    VD>Хм. Интересно... Правда не очень похоже на творчество для дома, для семьи.

    Да нет — это всеж таки по работе.. А завистливые кодеры — это как раз программисты из службы поддрежки аппаратно-программных комплексов. Пишут программки по составлению отчетов из какой-то отдельной базы, а не как у меня из всех сразу... Т.к. отчеты в основном в excel перегоняются, то тут VB-шнику проще — у него есть параметры по умолчанию.
    Тем более по их завистливым ро... лицам видно что если работать по правилам и... составить тех. задание и направить им на разработку — то там оно благополучно и умрет... А так — пишу сам для себя — и производительность получатся намного больше чем у них всех вместе взятых... Плюс еще весь код теститься, что они часто забывают делать...
    Делай добро и бросай его в воду...
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 12.06.07 15:55
    Оценка:
    Здравствуйте, Mckey, Вы писали:

    M>Кстати непонятно почему ConvertAll так отстает...


    ConvertAll — это фрэймворковский метод работающий через делегаты. Они медленее фунционального типа Немерле. Array.ForEach, кстати, тоже.

    M>
    M>time repeat(100000) Array.ForEach(lp.Map(_.ToString()).ToArray(),_x=>i++)
    M>

    Тут можно было MapToArray исползовать. По идее это еще быстрее должно быть.

    M>Первый из бенчей в 5 раз быстрее чем два других..


    M>Да нет — это всеж таки по работе.. А завистливые кодеры — это как раз программисты из службы поддрежки аппаратно-программных комплексов. Пишут программки по составлению отчетов из какой-то отдельной базы, а не как у меня из всех сразу... Т.к. отчеты в основном в excel перегоняются, то тут VB-шнику проще — у него есть параметры по умолчанию.

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

    Ясно.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[12]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 17:09
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    FDS>>Вот тебе уже появились две переменные, насколько они временные — это уже другой вопрос


    VD>Это не переменные. Это параметры. Вполне логично, то они себе появились. А вот зачем у тебя появляются временные переменные кэширующие эти значения перед передачей в фукцнию?


    Нет, это переменные, я написал как я применяю функцию, а не её объявление. Сама функция ещё не написана

    VD>По идее раз алгоритм на дереве, то тебе бы надо в этой фунции или вызывать его рекурсивно для подветок, или вообще вынести итерацию по дереву в отдельную фунцию, а сам алгоритм записать в более простом виде. Вот как сдела бы я:

    VD>
    VD>TraverseTree(node : Node) : IEnumerable[Node]
    VD>{
    VD>    yield node;
    VD>    TraverseTree(node.Left);
    VD>    TraverseTree(node.Right);
    VD>}
    VD>...
    VD>foreach (node in TraverseTree(tree.Root))
    VD>    when (isNull(ScalarMul(vect, GetVectorValue(node))))
    VD>      MarkTree(node);
    VD>

    VD>Уж не знаю подрбностей алгоритма, но как-то так.

    Забыл я обойти дерево
    Честно говоря, я бы без foreach сделал


    MarkNode(tree)
    {
      def sm = ScalarMul(vect, GetVectorValue(node))
      when ( isNull(sm) )
        /// ....
    }
    
    
    MarkTree(tree): tree
    {
      MarkNode(tree);  
    
      MarkTree(tree.left);
      MarkTree(tree.right)
    
      tree
    }
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 17:10
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

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


    FDS>>А исключение на разную длину списков вы зря поставили,

    WH>А по другому никак. Иначе получишь предупреждение от компилятора.

    Мда... это плохо

    FDS>>хотя, конечно, правильно

    WH>Вот именно. Себе верить нельзя. Те вобще.

    Только вот списки там МОГУТ быть разной длины
    Re[7]: Имена переменных
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 17:34
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

    WH>Кстати имена получше подбирай, а то вобще не понятно что к чему.


    А что именно не понятно и как их назвать?
    cf — массив запомненных значений функций
    ck — массив коэффициентов схемы Адамса
    Dx — приращение к текущему значению функции

    Как их по другому назвать так, чтобы понятно было?
    Re[10]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 12.06.07 17:36
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Только вот списки там МОГУТ быть разной длины


    Значит алгоритм нужно менять. Обрабатывать эти случаи.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[11]: Ну конечно у Немерле нет будущего :)
    От: FDSC Россия consp11.github.io блог
    Дата: 12.06.07 17:40
    Оценка:
    Здравствуйте, VladD2, Вы писали:

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


    FDS>>Только вот списки там МОГУТ быть разной длины


    VD>Значит алгоритм нужно менять. Обрабатывать эти случаи.


    Я не очень понял, где в этом алгоритме ограничение на то, чтобы списки были одинаковой длины?
    Вот, а у меня всё нормально работает для списков разной длины, так что у меня правильней
    Re[12]: Ну конечно у Немерле нет будущего :)
    От: IO Украина  
    Дата: 12.06.07 17:53
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Аргумент "некрасиво" — следствие эстетического чувства при взгляде на код: код выглядит как каша перемешанных символов. Я люблю код, в котором пустого места больше, чем заполненного, здесь это не поощряется

    Никто не запрещает писать так:

    if
    (
      Function1
      (
        Function2(),
        Function3
        (
          Function4()
        )
      )
    )
    {
      Function5();
      Function6();
    }
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: Klapaucius  
    Дата: 13.06.07 12:02
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Кстати, в донете код:

    VD>
    VD>for (mutable i = 0; i < Lf; i++)
    VD>    dx[i] += incDx[i];
    VD>

    VD>медленее нежели:
    VD>
    VD>for (mutable i = 0; i < dx.Length; i++)
    VD>    dx[i] += incDx[i];
    VD>

    VD>так как при этом первый вариант не выбрасывает проверок выхода за пределы массива, а второй выкидывает (если конечно JIT не подеравили).

    Увы, далеко не всегда. Может помешать другой массив incDx (для него-то проверку выбрасывать нельзя), например.
    using System;
    using System.Console;
    using Nemerle.Utility;
    
    module Program
    {
        Main() : void
        {
            def count = 10_000_000;
            def dx : array[int] = array(count);
            def incDx : array[int] = array(count);
        
            def timing(unit : void->void)
            {
                unit();
                def sw = System.Diagnostics.Stopwatch();
                sw.Start();
                unit();
                sw.Stop();
                WriteLine(sw.ElapsedTicks);
            }
        
            timing( () => {
                for (mutable i = 0; i < dx.Length; i++)
                    dx[i] += incDx[i];
            });
            
            timing( () => {
                def len = dx.Length;
                for (mutable i = 0; i < len; i++)
                    dx[i] += incDx[i];
            });
        
            _ = ReadLine();
        }
    }


    506100502
    345686186


    .NET Framework 2.0.50727
    Xeon-A(Prestonia) X2, 2666 MHz
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: Klapaucius  
    Дата: 13.06.07 12:02
    Оценка:
    Здравствуйте, Андрей Хропов, Вы писали:

    АХ>обычно достаточно

    АХ>
    АХ>foreach(i in $[0..n])
    АХ>


    В данном случае $ можно не писать.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
    Re[10]: Оффтоп
    От: FDSC Россия consp11.github.io блог
    Дата: 13.06.07 12:43
    Оценка:
    Здравствуйте, Klapaucius, Вы писали:

    FDS>>Ага, попробуй взять студента и спросить у него, скажем, формулу Остроградского, запретив при этом писать в математических выражениях


    K>Я, правда, не студент, но можно я впаду в детство? Спасибо.

    K>Имеется в виду формула Остроградского-Гаусса?

    Именно она

    K>Поток через поверхность равен сумме источников и стоков в объеме, ограниченном этой поверхностью.


    Блин, этот вопрос был рассчитан на тех, кто не знает формулу Остроградского
    Давайте по другому: попробуйте теперь написать то, что подумали в формулах — согласитесь, есть возможность ошибиться

    K>А что, теперь студенты отвечают, что это три закорючки с одной стороны и две с другой?


    Чего они только не отвечают...


    K>Ну так он и записывает, как думает. И я точно также поступаю. С нами что-то не так?


    Думаете вы не так
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 13.06.07 16:02
    Оценка:
    Здравствуйте, Klapaucius, Вы писали:

    K>Увы, далеко не всегда. Может помешать другой массив incDx (для него-то проверку выбрасывать нельзя), например.


    Значит Немерловый компилятор генерирует код которые не распознается как паттерн JIT-ом.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[10]: Ну конечно у Немерле нет будущего :)
    От: rameel https://github.com/rsdn/CodeJam
    Дата: 13.06.07 17:42
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Значит Немерловый компилятор генерирует код которые не распознается как паттерн JIT-ом.


    Похоже. что да. Аналогичный код на шарпе имеет несколько лучшие показатели:
    C#
    163164
    160065
    
    Немерле
    404236
    264025


    ЗЫ. FW2.0, ноут Core Duo T2050-1.60ГГц
    ... << RSDN@Home 1.2.0 alpha rev. 693>>
    Re[11]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 13.06.07 21:40
    Оценка:
    Здравствуйте, rameel, Вы писали:

    R>Похоже. что да. Аналогичный код на шарпе имеет несколько лучшие показатели:

    R>[code]
    R>C#
    R>163164
    R>160065

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

    Вот до сих пор не пойму, что меало сделать более обощенный механизм оптимизации? Ну, хотя бы при при-JIT-е?
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[10]: Ну конечно у Немерле нет будущего :)
    От: Klapaucius  
    Дата: 14.06.07 12:10
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Значит Немерловый компилятор генерирует код которые не распознается как паттерн JIT-ом.


    Это плохо. И надеяться на то, что ситуация изменится в обозримом будущем не приходится?
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
    Re[11]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 14.06.07 23:16
    Оценка:
    Здравствуйте, Klapaucius, Вы писали:

    VD>>Значит Немерловый компилятор генерирует код которые не распознается как паттерн JIT-ом.


    K>Это плохо.


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

    K> И надеяться на то, что ситуация изменится в обозримом будущем не приходится?


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

    Ну, а что касается обозримого будущего, то это зависит. В конце концов можешь взяться сам.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[13]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 25.06.07 13:49
    Оценка:
    Здравствуйте, mkizub, Вы писали:

    M>И не поймёшь. Ты же думаешь, что JIT это так просто, взял да и оптимизнул код. Только паттерн распознать.

    M>Ага.

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

    Я прекрасно понимаю все трудности и всю подноготную. Каких-то неразрешимых пробелем там нет. Если в джит-варианте еще можно сослаться на то, что качественная оптимизация увеличит время компиляции, то в пре-джит-вариенте это уже не проблема. Так что дело тут исключительно в том, что этим никто не занялся, ну, и в том, что в МС исползуются дико низкоуровеневые средства разработки на которых вопросы оптимизации выливаются в море сложного кода. Если бы они довели до ума проект Феникс и использовали бы для написания кода оптимизации какой-нибудь высокоуровневый ЯП с паттерн-матчингом, то сложность задачи снизилась бы на порядок (а то и больше) и ее смогли бы решить пара студентов за пару месяцев.

    M>Замечательная иллюстрация того, чем текстовые языки (в данном случае — байткод, IL), мешают оптимизации

    M>программы.

    Я не вижу тут никакой иллюстрации. Я вижу довольно безотвественну болтавню без какой-либо аргументации.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[14]: Ну конечно у Немерле нет будущего :)
    От: mkizub Литва http://symade.tigris.org
    Дата: 25.06.07 14:31
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    M>>И не поймёшь. Ты же думаешь, что JIT это так просто, взял да и оптимизнул код. Только паттерн распознать.

    M>>Ага.

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


    Ух ты круть какая. Первый парень на деревне.

    VD>Я прекрасно понимаю все трудности и всю подноготную. Каких-то неразрешимых пробелем там нет. Если в джит-варианте еще можно сослаться на то, что качественная оптимизация увеличит время компиляции, то в пре-джит-вариенте это уже не проблема. Так что дело тут исключительно в том, что этим никто не занялся, ну, и в том, что в МС исползуются дико низкоуровеневые средства разработки на которых вопросы оптимизации выливаются в море сложного кода. Если бы они довели до ума проект Феникс и использовали бы для написания кода оптимизации какой-нибудь высокоуровневый ЯП с паттерн-матчингом, то сложность задачи снизилась бы на порядок (а то и больше) и ее смогли бы решить пара студентов за пару месяцев.


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

    Ты рассматриваешь только управляющую систему для программы. Конечно, можно сделать AOT/JIT компиляцию лучше. Но для этого надо, чтоб кто-то в мелкософте этим занялся. А у них, в мелкософте, совсем другие проблемы. Там есть лаборатория, у лаборатории есть начальник который отчитывается перед другим начальником, а тот перед следующим начальником. И им совершенно пофиг низкоуровневые проблемы оптимизации кода JIT компилятора. У них там взаимодействие между подразделенеиями, продажи, рейтинги, и прочие показатели не имеющие к компиляторам никакого отношения.

    Понимаешь? Только такие большие корпорации как мелкософт/ай-би-эм/etc могут создать технологию уровня .NET, иначе не хватит ресурсов у фирмы, технология будет слишком сложной для небольшой фирмы. И следовательно, эта технология будет автоматически неэффективной — в виду неэффектиного управления.

    Это именно принципиальная проблема. Это самая принципиальная проблема управления вообще.

    M>>Замечательная иллюстрация того, чем текстовые языки (в данном случае — байткод, IL), мешают оптимизации программы.


    VD>Я не вижу тут никакой иллюстрации. Я вижу довольно безотвественну болтавню без какой-либо аргументации.


    Ну так учись смотреть в корень, а не в обиженную гордыню. Тем более, что ты как-бы читал ту статью про SOP, которую всё никак не напечатают на RSDN.
    Вроде как тебе эту аргументацию не надо было приводить, ты ж вроде как читал.

    Если бы код из программы передавался в JIT/AOT компилятор как семантическая единица, то вообще никакой необходимости в распознавании
    паттернов бы не было. И необходимости расписывать for loop через jump-ы бы не было. А байткод — это синтаксически фиксированный текст.
    В нём нет и быть не может никаких if/loop/match. Там только conditional/unconditional jump-ы есть. И приходится JIT компилятору пытаться
    понять что-же именно писал программист. Не понял — не оптимизировал.
    SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
    Re[15]: Ну конечно у Немерле нет будущего :)
    От: WolfHound  
    Дата: 26.06.07 07:02
    Оценка:
    Здравствуйте, mkizub, Вы писали:

    M>Всё гораздо хуже.

    M>Ты же занимаешься программированием, то есть кибернетика тебе должна быть знакома.
    M>В ней есть такой постулат, впрочем, достаточно очевидный — для эффективного управления сложной системой, сложность управляющей системы должна быть больше, чем управляемой. Иначе нельзя построить полную модель управляемой системы и расчитать минимальное изменение для компенсации изменения внешних параметров.
    M>Немедленный вывод из этого — полностью оптимальное (эффективное) управление системой невозможно. Поскольку если управляющая система сложнее управляемой — то нужна ещё одна система, управляющая управляющей системой, ещё более сложная. И если не впадать в построение бесконечно сложных систем, то с необходимостью наши управляющие системы будут менее сложными, чем управляемые, и иерархически они будут упрощаться вплоть до полного примитивизма.

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

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

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

    Кстати твое решение всеголишь разновидность шаблонящего оптимизатора.
    По сути разници ни какой.
    Ну и что что у тебя шаблоны уже выведены, а ему нужно их искать?
    Всеравно эта схема будет хуже чем полноценный анализ потока исполнения.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Пусть это будет просто:
    просто, как только можно,
    но не проще.
    (C) А. Эйнштейн
    Re[16]: Ну конечно у Немерле нет будущего :)
    От: mkizub Литва http://symade.tigris.org
    Дата: 26.06.07 07:33
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

    WH>У тебя проблема в изначальной посылке.

    WH>Нам не нужно оптимальное управление.
    WH>Нам нужно близкое к оптимальному.

    Это такой аутотренинг. Я не хочу быть богатым. Я доволен тем, что я беден. Мне не нужно быть богатым...


    WH>Добится этого можно устранив определенные классы неоптимальностей.

    WH>Например проверки которые никогда не сработают.

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


    Конечно. Но это локальная оптимальность управления. Я же говорю о всей иерархии.

    WH>Кстати твое решение всеголишь разновидность шаблонящего оптимизатора.

    WH>По сути разници ни какой.
    WH>Ну и что что у тебя шаблоны уже выведены, а ему нужно их искать?
    WH>Всеравно эта схема будет хуже чем полноценный анализ потока исполнения.

    О каком моём решении ты говоришь?
    И почему этот неизвестный в природе "шаблонящий оптимизатор" (первый раз слышу о таком, может ты о pipehole optimization?)
    будет обязательно хуже, чем полноценный анализ потока исполнения?
    Скажем, у нас на фирме был такой полноценный. Хотел от 256 до 512 мег памяти и работал несколько минут при компиляции.
    Разве же он лучше другого, который требовал 100 кб и работал практически мгновенно и помещался прямо в мобильный
    телефон (хотя ничего особенного не оптимизировал, но хоть что-то)?
    SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
    Re[15]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 26.06.07 12:30
    Оценка:
    Здравствуйте, mkizub, Вы писали:

    M>Почему Nemerle не может сгенерировать байткод в таком виде, чтоб попасть в шаблон распознаваемый JIT-ом?


    Потому что никто этим специально не занимался.

    M>Всё потому же — for в nemerle это макрос, и информация о том, что это цикл — теряется на этапе

    M>макроподстановки.

    Если написать рекурсивную фунцию со счетчиком, то она преобразуется в for 1 в 1. Макрос может генерировать любой код. Так что это не более чем вопрос его реализации.

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

    Умные рассуждения о goto поскипаны.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[16]: Небольшой оффтоп (навеяно темой)
    От: konsoletyper Россия https://github.com/konsoletyper
    Дата: 26.06.07 16:55
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    M>>Почему Nemerle не может сгенерировать байткод в таком виде, чтоб попасть в шаблон распознаваемый JIT-ом?


    VD>Потому что никто этим специально не занимался.


    Интересно, а почему никто специально не займётся маленькой, но очень полезной оптимизацией match'а, когда он используется в качестве switch'а. В любом случае генерится куча условных переходов. А в случаях вроде:

    match(x)
    {
    1 => ...
    2 => ...
    ...
    }

    хотелось бы, чтобы генерилась инструкция IL switch.
    ... << RSDN@Home 1.2.0 alpha rev. 672>>
    Re[17]: Небольшой оффтоп (навеяно темой)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 27.06.07 17:26
    Оценка:
    Здравствуйте, konsoletyper, Вы писали:

    K>Интересно, а почему никто специально не займётся маленькой, но очень полезной оптимизацией match'а, когда он используется в качестве switch'а. В любом случае генерится куча условных переходов.


    Как я понимаю, главным образом, от лени. Дело в том, что реализация усложняется наличием защиты (guards, т.е. when во вхождениях match-а). Если использовать MSIL-ные switch-и, то надо отслеживать множество частных случаев. А так как в большинстве случаев все и так работает очень шустро, то никто этим и не озаботился до сих пор.

    П уму, кончень, нужно это дело исправлять.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[18]: Небольшой оффтоп (навеяно темой)
    От: konsoletyper Россия https://github.com/konsoletyper
    Дата: 27.06.07 18:01
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Как я понимаю, главным образом, от лени. Дело в том, что реализация усложняется наличием защиты (guards, т.е. when во вхождениях match-а). Если использовать MSIL-ные switch-и, то надо отслеживать множество частных случаев. А так как в большинстве случаев все и так работает очень шустро, то никто этим и не озаботился до сих пор.


    Думаю, сделать доп. проверку перед самим алгоритмом компиляции match'а сделать не составит труда. Всего-то и нужно проверить типа выражения, и если он int/short/char/etc, просмотреть все шаблоны на предмет того, что они представлены одним или несколькими конкретными литералами.

    VD>П уму, кончень, нужно это дело исправлять.


    Ага.
    ... << RSDN@Home 1.2.0 alpha rev. 672>>
    Re[19]: Небольшой оффтоп (навеяно темой)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 27.06.07 19:56
    Оценка:
    Здравствуйте, konsoletyper, Вы писали:

    K>Думаю, сделать доп. проверку перед самим алгоритмом компиляции match'а сделать не составит труда.


    Это на словах, а на деле... в общем, можешь попробовать.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[20]: Небольшой оффтоп (навеяно темой)
    От: WolfHound  
    Дата: 28.06.07 06:00
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    K>>Думаю, сделать доп. проверку перед самим алгоритмом компиляции match'а сделать не составит труда.

    VD>Это на словах, а на деле... в общем, можешь попробовать.
    Вобще говоря match любой сложности можно разложить на switch'и и хвостовые вызовы.
    После чего оптимизировать уже весьма примитивную модель.
    Такой подход позволит заоптимизировать не только сложные match'и но и кучу другого кода который сечас получается не очень эффективным.
    Нужно сесть и сделать. Вот только где бы время взять...
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Пусть это будет просто:
    просто, как только можно,
    но не проще.
    (C) А. Эйнштейн
    Re[21]: Небольшой оффтоп (навеяно темой)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 28.06.07 10:56
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

    WH>Вобще говоря match любой сложности можно разложить на switch'и и хвостовые вызовы.

    Несомненно!
    WH>...Нужно сесть и сделать. Вот только где бы время взять...

    Вот именно. Если время было бы не ресурс, то все давно было бы сделано. Так что лучше помогите воплотить в жизнь мечты, а не травите ими душу.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[22]: Небольшой оффтоп (навеяно темой)
    От: konsoletyper Россия https://github.com/konsoletyper
    Дата: 28.06.07 12:21
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Вот именно. Если время было бы не ресурс, то все давно было бы сделано. Так что лучше помогите воплотить в жизнь мечты, а не травите ими душу.


    Это, у меня, возможно, будет с конца следующей недели свободное время. Так что я могу отложить чуть-чуть BnfMacro и заняться этой маленькой оптимизацией (это как раз для BnfMacro критично). Кстати, что там нужно сделать, чтобы получить пароль на SVN? Или, может просто сюда выложить модифицированный файлик?
    ... << RSDN@Home 1.2.0 alpha rev. 672>>
    Re[23]: Небольшой оффтоп (навеяно темой)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 28.06.07 14:23
    Оценка:
    Здравствуйте, konsoletyper, Вы писали:

    K>Кстати, что там нужно сделать, чтобы получить пароль на SVN? Или, может просто сюда выложить модифицированный файлик?


    Насколько я помню это описано в этой статье
    Автор(ы):
    .
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: VGn Россия http://vassilsanych.livejournal.com
    Дата: 28.06.07 21:28
    Оценка:
    VD>Ага и еще не ясно зачем эти фигурные скобки. Без них можно в одну строку уложиться:
    VD>
    VD>def result = if (condition) kjsdhfjklasdh() else werioptuertj();
    VD>


    Аналог тернарного оператора в C#
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: VGn Россия http://vassilsanych.livejournal.com
    Дата: 02.07.07 23:09
    Оценка:
    AB>А вот эти примеры аналог какого оператора? ...

    Я не собирался ни с кем спорить. Просто подвёл итог, что дальнейшее упрощение именно этого куска кода сводит его к оператору C# ,
    который, говоря по существу, — тоже функциональная конструкция.
    Будьте проще, что ли. Это — имхо, просто синтаксис.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
    Re[7]: Ну конечно у Немерле нет будущего :)
    От: Dufrenite Дания  
    Дата: 03.07.07 14:49
    Оценка:
    Здравствуйте, WolfHound, Вы писали:

            def GetDx(_, _)
            {
            | ([ck], [cf]) =>
                (cf.Map(_ * ck), [])
                
            | (ck :: klast, cf :: flast) =>
                def (incDx, cflast) = GetDx(klast, flast);
                (cf.MapI((i, f) => f * ck + incDx[i]), cf :: cflast)
            
            | _ => throw Exception();//Если списки разной длинны.
            }


    Не понятно что означают конструкции:

    | ([ck], [cf]) => ...


    | (ck :: klast, cf :: flast) => ...


    Насколько я понимаю в обоих случаях это конструирование списков. Не ясно только что с чем сопоставляется.
    Re[8]: Ну конечно у Немерле нет будущего :)
    От: Дьяченко Александр Россия  
    Дата: 03.07.07 15:29
    Оценка:
    Здравствуйте, Dufrenite, Вы писали:

    D>Не понятно что означают конструкции:


    D>
    D>| ([ck], [cf]) => ...
    D>


    Образец для сопоставления — кортеж из 2-х списков по 1-му элементу в каждом (ck, cf — элементы)

    D>
    D>| (ck :: klast, cf :: flast) => ...
    D>


    Образец для сопоставления — кортеж из 2-х списков в каждом из которых более 1 элемента (ck, cf — первые элементы, а klast, flast — остатки списков (хвосты))

    D>Насколько я понимаю в обоих случаях это конструирование списков. Не ясно только что с чем сопоставляется.


    ЗЫ. Функция с любым кол-вом параметров может быть представлена как функция с одним параметром — кортежем из соответствующего кол-ва элементов, поэтому образцы для сопоставления в функции GetDx — кортежи из 2-х элементов.
    ... << RSDN@Home 1.2.0 alpha rev. 694>>
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 11.07.07 10:54
    Оценка:
    Здравствуйте, FDSC, Вы писали:

    FDS>Согласен. Есть случаи, когда так писать не очень удобно. Я пишу так, как думаю, и на Немерле, в частности, пишу именно из-за того, что этот язык позволяет мне писать именно мои мысли

    Исправляй мысли
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[9]: Ну конечно у Немерле нет будущего :)
    От: Dufrenite Дания  
    Дата: 11.07.07 14:52
    Оценка:
    Спасибо за объяснение.
    Всё теперь понятно, просто уж очень непривычные конструкции.
    Re[3]: Ну конечно у Немерле нет будущего :)
    От: D. Mon Великобритания http://thedeemon.livejournal.com
    Дата: 06.08.07 06:00
    Оценка:
    FDS>>Я не могу написать так:
    FDS>>if (condition)
    FDS>>{
    FDS>> def result = kjsdhfjklasdh()
    FDS>>}
    FDS>>else
    FDS>>{
    FDS>> def result = werioptuertj();
    FDS>>}
    FDS>>Calc(result)

    IT>Так ты не можешь написать нигде.


    "Нигде" касается только С++/С#/Nemerle?
    Потому что в том же Руби так написать можно.
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: IT Россия linq2db.com
    Дата: 06.08.07 12:33
    Оценка:
    Здравствуйте, D. Mon, Вы писали:

    DM>"Нигде" касается только С++/С#/Nemerle?


    Да, нигде в нормальных языках.

    DM>Потому что в том же Руби так написать можно.


    В javascript тоже можно, но это кроме как глюкодромом по-другому назвать нельзя.
    ... << RSDN@Home 1.2.0 alpha rev. 0>>
    Если нам не помогут, то мы тоже никого не пощадим.
    Re[4]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 06.08.07 12:40
    Оценка:
    Здравствуйте, D. Mon, Вы писали:

    DM>"Нигде" касается только С++/С#/Nemerle?

    DM>Потому что в том же Руби так написать можно.

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

    Я не знаю ни одного языка где переменные бли бы первокласными значениями. Так что возвращать из выражений переменные нельзя нигде.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
    Re[5]: Ну конечно у Немерле нет будущего :)
    От: cl-user  
    Дата: 08.08.07 11:35
    Оценка:
    Здравствуйте, VladD2, Вы писали:

    VD>Я не знаю ни одного языка где переменные бли бы первокласными значениями. Так что возвращать из выражений переменные нельзя нигде.


    Я знаю один язык, в котором "всё есть строка", и в этих узких рамках переменные ни чем не лучше любых других значений
    Re[6]: Ну конечно у Немерле нет будущего :)
    От: VladD2 Российская Империя www.nemerle.org
    Дата: 08.08.07 17:54
    Оценка:
    Здравствуйте, cl-user, Вы писали:

    CU>Я знаю один язык, в котором "всё есть строка", и в этих узких рамках переменные ни чем не лучше любых других значений


    Остается только порадоваться за тебя.
    ... << RSDN@Home 1.2.0 alpha rev. 637>>
    Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.