Ой, чо с D деется-то!?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 16.11.06 15:51
Оценка: 13 (5) :))) :))
Совсем недавно, 14 ноября 2006 года, увидел свет D версии 0.174. Как водится, что-то пофикшено, что-то выброшено (хороший, вероятно подарочек тем, кто на D уже начал писать). А вот среди добавленого оказалась поддержка туплов. Которая в сочетании с variadic templates делает программирование на шаблонах в D гооораздо привлекательнее, чем в C++

Например, стандартные пакеты std.traits и std.typetuple уже содержат то, что в C++ достигается килобайтами кода из Boost-a. Красота однако, аж слюньки текут.

Не все, однако, мне понятно и не все, имхо, еще чисто с этими нововедениями. Например, в процитированном ниже коде из описания туплов приходится реализовывать шаблон CurryAll дважды. Вальтер Брайт объясняет это тем, что невозможно перегрузить один и тот же шаблон двумя одинаковыми списками аргументов, поэтому в первый добавляется параметр Dummy. Чем-то напоминает сегоднящние workaround-ды для C++ с помощью SFINAE (хотя в обсуждениях на форуме Брайт высказался, что возможно в будущем это дело будет упрощено). Так же странно, что для копирования элементов из args в Foo.args_m приходится прибегать к поэлементному копированию. Обычное присваивание (пока?) не работает.

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

В общем, по своим языковым изыскам D лично для меня все привлекательнее и привлекательнее, чем C++ (особенно скорость его компиляции). Но когда же, черт побери, стабильная версия выйдет!!! Так ведь и C++0x быстрее, чем D 1.0 stable появится
(Кстати, среди нововведений версии 0.174 есть ключик командной строки -v1, который включает поддержку совместимости с версией 1.0 языка. Значит ли это, что 1.0 уже была? ).

А вот пример из описания туплов D:
R delegate() CurryAll(Dummy=void, R, U...)(R function(U) dg, U args)
{
    struct Foo
    {
        typeof(dg) dg_m;
        U args_m;

        R bar()
        {
            return dg_m(args_m);
        }
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    foreach (i, arg; args)
        f.args_m[i] = arg;
    return &f.bar;
}

R delegate() CurryAll(R, U...)(R delegate(U) dg, U args)
{
    struct Foo
    {
        typeof(dg) dg_m;
        U args_m;

        R bar()
        {
            return dg_m(args_m);
        }
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    foreach (i, arg; args)
        f.args_m[i] = arg;
    return &f.bar;
}

void main()
{
    static int plus(int x, int y, int z)
    {
        return x + y + z;
    }

    auto plus_two = CurryAll(&plus, 2, 3, 4);
    printf("%d\n", plus_two());
    assert(plus_two() == 9);

    int minus(int x, int y, int z)
    {
        return x + y + z;
    }

    auto minus_two = CurryAll(&minus, 7, 8, 9);
    printf("%d\n", minus_two());
    assert(minus_two() == 24);
}


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Ой, чо с D деется-то!?
От: WolfHound  
Дата: 16.11.06 16:00
Оценка: +2 -4 :))) :))) :))) :)))
Здравствуйте, eao197, Вы писали:

Преаращается в жалкое подобие Nemerle...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Ой, чо с D деется-то!?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 16.11.06 18:23
Оценка: +4 :)
Здравствуйте, WolfHound, Вы писали:

WH>Преаращается в жалкое подобие Nemerle...


Nemerle -- это макросы, метапрограммирование + функциональщина. Т.е. то, чего в D пока не видно. Так что вряд ли.
Тем более, что Nemerle -- это только .NET, в отличии от D. Т.к. они вообще в разных песочницах расти будут.

А вот то, что D начинает позволять делать фокусы в духе Александреску, это, имхо, тревожный сигнал. Хотя std.traits полезная штука, но начинает казаться, что D сначала пытался уйти от переусложненности C++, а сейчас может C++ в этом деле переплюнуть.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Ой, чо с D деется-то!?
От: Андрей Хропов Россия  
Дата: 16.11.06 18:42
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Преаращается в жалкое подобие Nemerle...


Знаешь, с одной стороны да (этот синтаксис Tuples просто жесть по сравнение с Nemerle),
с другой стороны в низкоуровневом языке задача которого заменить C/C++ это неплохо.

Мне кажется основная проблема D сейчас — довольно медленный GC (ну и библиотек немного, но это уже скорее про инфраструктуру, а не сам язык):
здесь.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Ой, чо с D деется-то!?
От: WolfHound  
Дата: 16.11.06 18:45
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>Nemerle -- это макросы, метапрограммирование + функциональщина. Т.е. то, чего в D пока не видно. Так что вряд ли.

Дак эта... ты сам то свои ссылки смотрел? Там как раз жалкие попытки сделать то что в немерле сделано давно и несравнимо качественней.

E>Тем более, что Nemerle -- это только .NET, в отличии от D. Т.к. они вообще в разных песочницах расти будут.

А что у D в плане переносимости есть какието преймущества перед Mono?
В любом случае сделать рантайм немерле не завязанный на .NET вполне возможно.

E>А вот то, что D начинает позволять делать фокусы в духе Александреску, это, имхо, тревожный сигнал. Хотя std.traits полезная штука, но начинает казаться, что D сначала пытался уйти от переусложненности C++, а сейчас может C++ в этом деле переплюнуть.

Ну переплюнуть С++ это задачка оооочень трудная. А вот приблизится вполне возможно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Ой, чо с D деется-то!?
От: WolfHound  
Дата: 16.11.06 19:06
Оценка: +3 -1
Здравствуйте, Андрей Хропов, Вы писали:

АХ>Знаешь, с одной стороны да (этот синтаксис Tuples просто жесть по сравнение с Nemerle), с другой стороны в низкоуровневом языке задача которого заменить C/C++ это неплохо.

Системный язык не должен быть низкоуровневым.
Все что нужно это value-типы, поддержка двоичных данных на уровне виртуальной машины и оптимизатор который умеет делать region-inference. Еще нужно иметь несколько различных алгоритмов сборщика мусора в том числе подсчет ссылок и вобще отсутствие сборщика мусора (работает только region-inference).
Короче см singularity там почти оно только CLR на роль виртуальной машины для ОС не очень подходит.

АХ> Мне кажется основная проблема D сейчас — довольно медленный GC (ну и библиотек немного, но это уже скорее про инфраструктуру, а не сам язык):

А для D не возможен быстрый GC. Ибо быстрый == точный, а не консервативный как в D. Проблема в том что дизайн D просто не позволяет сделать точный сборщик мусора.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Ой, чо с D деется-то!?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 16.11.06 20:00
Оценка: +2 :))
Здравствуйте, WolfHound, Вы писали:

E>>Nemerle -- это макросы, метапрограммирование + функциональщина. Т.е. то, чего в D пока не видно. Так что вряд ли.

WH>Дак эта... ты сам то свои ссылки смотрел? Там как раз жалкие попытки сделать то что в немерле сделано давно и несравнимо качественней.

А с чего ты взял, что это калька с Немерле?
Имхо, Немерл-овцы сам туплы откуда-то скомуниздили.
Кроме того, имхо, это явно не попытка догнать Немерле (чо вас на нем так клинт-то, кстати?), а сделать нормально в D то, что в C++ делается с помощью десятиэтажных макросов (памяти Александреску).

E>>Тем более, что Nemerle -- это только .NET, в отличии от D. Т.к. они вообще в разных песочницах расти будут.

WH>А что у D в плане переносимости есть какието преймущества перед Mono?

Реализация D в GNU Compiler Collection, например.

WH>В любом случае сделать рантайм немерле не завязанный на .NET вполне возможно.


А рантайму, вообще-то говоря, цена не большая. Ты вот на Nemerle сможешь без NET Framework писать?

E>>А вот то, что D начинает позволять делать фокусы в духе Александреску, это, имхо, тревожный сигнал. Хотя std.traits полезная штука, но начинает казаться, что D сначала пытался уйти от переусложненности C++, а сейчас может C++ в этом деле переплюнуть.

WH>Ну переплюнуть С++ это задачка оооочень трудная. А вот приблизится вполне возможно.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Ой, чо с D деется-то!?
От: WolfHound  
Дата: 16.11.06 20:55
Оценка: +1
Здравствуйте, eao197, Вы писали:

E>А с чего ты взял, что это калька с Немерле?

А где сказанно что это калька с немерле?
E>Имхо, Немерл-овцы сам туплы откуда-то скомуниздили.
Дык туплы из покон веков были в функциональщине.
E>Кроме того, имхо, это явно не попытка догнать Немерле
Правильно ибо это дохлый номер. Тк гонятся в гибкости с языком который изначально проектировался в минималистической манере и возможностью добавления практически произвольных расширений пустая трата времени. Если конечно не сравнивать с подобным языком. Но D к таким языкам и близко не относится.
E>(чо вас на нем так клинт-то, кстати?),
По себе людей не судят. Стоит только произнести "немерле" как ты сразу начинаешь исходить ядом... к чему бы это?

E>а сделать нормально в D то, что в C++ делается с помощью десятиэтажных макросов (памяти Александреску).

Не получилось сделать нормально... Нормальность нужно сравнивать не с С++, а с языками где все это уже есть. Вот я и сравниваю с одним из лучших на мой взгляд языком... И сравнение не в пользу D.

E>А рантайму, вообще-то говоря, цена не большая.

из под стола раскажи это тем кто сделал внятные рантаймы.
hint: Разработчики руби в число этих людей не входят.

E>Ты вот на Nemerle сможешь без NET Framework писать?

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

E>Приближение, имхо, уже весьма близкое. А вот желание переплюнуть, вместо того, чтобы язык в стабильное состояние перевести, это у автора D просматривается

Автор просто пошол изначально не верным путем и по этому устроил себе массу проблем.
Если бы он выбрал бы путь аля немерле то давно бы язык зарелизил и кучу фенечек прикрутил.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Ой, чо с D деется-то!?
От: Андрей Хропов Россия  
Дата: 16.11.06 20:56
Оценка: +1 :)
Здравствуйте, eao197, Вы писали:

E>Кроме того, имхо, это явно не попытка догнать Немерле (чо вас на нем так клинт-то, кстати?)

Да потому что лучший язык на сегодня, ИМХО.

E>, а сделать нормально в D то, что в C++ делается с помощью десятиэтажных макросов (памяти Александреску).

Что в Немерле делается еще проще.

WH>>В любом случае сделать рантайм немерле не завязанный на .NET вполне возможно.

E>А рантайму, вообще-то говоря, цена не большая. Ты вот на Nemerle сможешь без NET Framework писать?
Так он про это и говорит. Нейтив-код компилятор.
Только тогда считай Немерле останется без возможностей пользоваться кучей функций в .NET.
Кстати сами разработчики именно этим и мотивируют свой выбор в пользу .NET:

Platform

Q: Why use CLI/.NET?


Mainly for interop reasons. There are number of CLI libraries and bindings out there already. There is going to be more and more.

Surely we'll loose WRT to compiled OCaml in terms of performance, at least until JIT's are made perfect, but it is easily possible to write a Gtk, GNOME, Windows GUI or even KDE application, we can embed Nemerle into ASP.NET web pages and there are more and more applications and libraries supporting .NET now. It is also possible to write libraries for other .NET languages, like C# or VB.NET.

We have also avoided significant development costs, because of this decision (no need for low-level compiler, JIT, the runtime library).

(здесь)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: D 1.0 for Jan 1, 2007
От: Андрей Хропов Россия  
Дата: 16.11.06 20:56
Оценка: 19 (2)
Здравствуйте, eao197, Вы писали:

E>(Кстати, среди нововведений версии 0.174 есть ключик командной строки -v1, который включает поддержку совместимости с версией 1.0 языка. Значит ли это, что 1.0 уже была? ).


Вальтер Брайт обещает выпустить 1.0 первого января:
здесь.

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

Для меня же главное же в принципе то, что наконец-то разобрались с двойным значением auto.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Ой, чо с D деется-то!?
От: FR  
Дата: 16.11.06 21:47
Оценка: 2 (2) +5 :)
Здравствуйте, WolfHound, Вы писали:


E>>(чо вас на нем так клинт-то, кстати?),

WH>По себе людей не судят. Стоит только произнести "немерле" как ты сразу начинаешь исходить ядом... к чему бы это?

А зачем призносить слово Немерле в топике никакого к нему отношения не имеющего?
Так что клинит конкретно
Re: Ой, чо с D деется-то!?
От: Андрей Хропов Россия  
Дата: 16.11.06 23:20
Оценка: 41 (3)
Здравствуйте, eao197, Вы писали:

E>А вот пример из описания туплов D:


R delegate() CurryAll(Dummy=void, R, U...)(R function(U) dg, U args)
{
    struct Foo
    {
        typeof(dg) dg_m;
        U args_m;

        R bar()
        {
            return dg_m(args_m);
        }
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    foreach (i, arg; args)
        f.args_m[i] = arg;
    return &f.bar;
}

R delegate() CurryAll(R, U...)(R delegate(U) dg, U args)
{
    struct Foo
    {
        typeof(dg) dg_m;
        U args_m;

        R bar()
        {
            return dg_m(args_m);
        }
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    foreach (i, arg; args)
        f.args_m[i] = arg;
    return &f.bar;
}

void main()
{
    static int plus(int x, int y, int z)
    {
        return x + y + z;
    }

    auto plus_two = CurryAll(&plus, 2, 3, 4);
    printf("%d\n", plus_two());
    assert(plus_two() == 9);

    int minus(int x, int y, int z)
    {
        return x + y + z;
    }

    auto minus_two = CurryAll(&minus, 7, 8, 9);
    printf("%d\n", minus_two());
    assert(minus_two() == 24);
}


Для того чтобы почувствовать разницу вот тот же самый код на Nemerle
(тут также пример и с полной (что фактически эквивалентно ленивому исполнению) и частичной currying,
то что у Вальтера называется Curry и CurryAll (здесь) ):

using Nemerle;
using System.Console;

def plus(x,y,z){ x+y+z }

def minus(x,y,z){ x-y-z }

def plus_two = plus(2,_,_);
WriteLine($"$(plus_two(6, 8))");

def plus_three = plus_two(3,_);
WriteLine($"$(plus_three(7))");

def plus_all = lazy( plus(7,8,9) );
WriteLine($"$plus_all");

def minus_all = lazy( minus(7,8,9) );
WriteLine($"$minus_all");


Да, а вот здесьнекто Reiner Pope соорудил шаблон RealCurry, который делает из функций
типа plus(1,2,3) функции типа curried_plus(1)(2)(3):

void main()
{
    static int plus(int x, int y, int z)
    {
            return x + y + z;
    }

    auto curried_plus = RealCurry(&plus);
    auto plus_two = curried_plus(2);
    auto plus_two_plus_three = plus_two(3);

    writefln(plus_two_plus_three(4)); // 9
    writefln(plus_two(5)(6));         // 13 
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Ой, чо с D деется-то!?
От: FR  
Дата: 17.11.06 08:13
Оценка: :)
Здравствуйте, Андрей Хропов, Вы писали:

АХ>Для того чтобы почувствовать разницу вот тот же самый код на Nemerle


А почему именно на Nеmerle?
Почему не на Наскеле или даже Питоне?
Тоже будет такой же краткий код.
Re[6]: Ой, чо с D деется-то!?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.11.06 08:35
Оценка: +2 -2
Здравствуйте, WolfHound, Вы писали:

E>>А с чего ты взял, что это калька с Немерле?

WH>А где сказанно что это калька с немерле?

Тогда зачем было говорить по превращении D в подобие Немерле?
Вообще, почитай ответ Vermicious Knid. Он там очень хорошо про разницу между Nemerle и D сказал.

E>>(чо вас на нем так клинт-то, кстати?),

WH>По себе людей не судят. Стоит только произнести "немерле" как ты сразу начинаешь исходить ядом... к чему бы это?

К тому что Nemerle здесь оффтопик, зачем его вообще поминать было я не понял.

E>>а сделать нормально в D то, что в C++ делается с помощью десятиэтажных макросов (памяти Александреску).

WH>Не получилось сделать нормально... Нормальность нужно сравнивать не с С++, а с языками где все это уже есть. Вот я и сравниваю с одним из лучших на мой взгляд языком... И сравнение не в пользу D.

И слава богу, ты пользуешься (?) Nemerle и для тебя Nemerle лучше D. Отлично.
Я не собираюсь пользоваться Nemerle вообще, а вот D для меня привлекателен именно как эволюция C++. Поэтому я и сравниваю D с C++. А так же с тем, каким сам D был года три назад.

E>>А рантайму, вообще-то говоря, цена не большая.

WH> из под стола раскажи это тем кто сделал внятные рантаймы.

А ты из их числа?
И делают ли немерловцы сам рантайм или же они очень хорошо используют .NET?

WH>hint: Разработчики руби в число этих людей не входят.


Ну вот, еще и Ruby приплели. У тебя есть проблемы с Ruby-новым runtime? Ты им вообще пользуешься? Или языком в форумах?
На своих задачах я проблем в Ruby runtime не встречал. А что до скорости, так еще вопрос, может ли настолько динамический язык, как Ruby быть быстрым. Одна горячая замена кода чего стоит. Erlang, к примеру, такую возможность предоставляет, но и сам при этом не быстр. А ведь Erlang клепают проффесиональные разработчики языков и рантаймов. Клепатели JRuby, которые на гораздо более современном языке (а не на C) пытаются интерпритатор Ruby сделать и то пока даже сравнимых результатов достичь не могут.

E>>Ты вот на Nemerle сможешь без NET Framework писать?

WH>Смогу. Болие того если сделать внятный рантайм то можно будет скомуниздить подавляющие большинство нетовских и жабовских библиотек.

Ну Scala-лазы в первой версии тоже NET пытались поддерживать. А где теперь эта поддержка?

WH>Если бы он выбрал бы путь аля немерле то давно бы язык зарелизил и кучу фенечек прикрутил.


Немерле уже в релизе?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Ой, чо с D деется-то!?
От: Gajdalager Украина  
Дата: 17.11.06 08:48
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ну Scala-лазы в первой версии тоже NET пытались поддерживать. А где теперь эта поддержка?


здесь

Scala 2 doesn't yet have support for .NET but it's in the making.
The .NET related information at the Scala website is only relevant for
Scala 1.4.

Re[2]: Ой, чо с D деется-то!?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.11.06 09:08
Оценка: 11 (1) -1
Здравствуйте, Андрей Хропов, Вы писали:

АХ>Для того чтобы почувствовать разницу вот тот же самый код на Nemerle


Это не тет же код. Для того, чтобы это был то, нужно привести исходный код lazy.

Кстати на счет сравнения. Я недавно проверял корректность одного простого алгоритма распределения транзакций по квантам времени. Для экспериментов я сделал версию на ruby:
def make_dist(trx_count, quantum_count)
  result = []
  remaining_trx = trx_count
  remaining_quantums = quantum_count
  (1..quantum_count).each do |i|
    result << (remaining_trx.to_f / remaining_quantums).round
    remaining_trx -= result.last
    remaining_quantums -= 1
  end

  result
end

r = make_dist( 2, 6 )
puts r.join(',')

Очень компактно и понятно что присходит.
Затем захотел проверить, насколько выразительно можно сделать это же на D и Scala. D вариант мне понравился:
import std.math;

int[] makeDistrib( int trxCount, int quantums )
  {
    auto r = new int[ quantums ];
    auto remainingTrx = trxCount;
    auto remainingQuantums = quantums;
    for( int i = 0; i != r.length; ++i )
      {
        r[ i ] = cast(int)std.math.round(
            cast(float)remainingTrx / remainingQuantums );
        remainingTrx -= r[ i ];
        --remainingQuantums;
      }

    return r;
  }

int main()
  {
    int[] d = makeDistrib( 2, 6 );
    foreach( i; d )
      printf( "%i,", i );

    return 0;
  }

Хотя, имхо, читабельность Ruby выше.

А вот для Scala я сделал три варианта. Первый был калькой с Ruby/D решения:
object BufferizatorDistrib
  {
    def makeDist( trxCount: int, quantums: int ) : Array[ int ] =
      {
        var r = new Array[ int ]( quantums )
        var i = 0
        var remainingTrx = trxCount
        var remainingQuantums = quantums
        while( i != quantums )
          {
            r(i) = Math.round(remainingTrx.toFloat / remainingQuantums)
            remainingTrx = remainingTrx - r(i)
            remainingQuantums = remainingQuantums - 1
            i = i + 1 
          }
        r
      }

    def main( args: Array[ String ] ) =
      {
        val d = makeDist( 2, 6 )
        for( val i <- d )
          System.out.print( i + "," )
      }
  }

Вариант на D мне понравился больше из-за того, что for явно показывает, что я хочу делать. А вот while() в Scala выглядит как workaround для компенсации отсутствия for и операторов ++, -- и -= (либо я их не нашел).

Тогда я попытался применить локальные функции и рекурсию. Сначала с сохранением возврата из makeDist именно Array[int]:
object BufferizatorDistrib2
  {
    def makeDist( trxCount: int, quantums: int ) : Array[ int ] =
      {
        def nextValue( r: Array[ int ],
            place: int,
            remainingTrx: int,
            remainingQuantums: int ) : Array[ int ] =
            {
              r(place) = Math.round(remainingTrx.toFloat / remainingQuantums)
              if( remainingQuantums > 1 )
                nextValue( r, place + 1, remainingTrx - r(place), remainingQuantums - 1 )
              else r
            }

        nextValue( new Array[ int ]( quantums ), 0, trxCount, quantums )
      }

    def main( args: Array[ String ] ) =
      {
        val d = makeDist( 2, 6 )
        for( val i <- d )
          System.out.print( i + "," )
      }
  }

Но здесь нужно протаскивать индекс place на каждой итерации, что как-то не правильно, имхо, для рекурсивного алгоритма. Поэтому появился третий вариант:
object BufferizatorDistrib3
  {
    def makeDist( trxCount: int, quantums: int ) : List[ int ] =
      {
        def nextValue( values: List[ int ],
            remainingTrx: int,
            remainingQuantums: int ) : List[ int ] =
            {
              val r = Math.round(remainingTrx.toFloat / remainingQuantums) :: values
              if( remainingQuantums > 1 )
                nextValue( r, remainingTrx - r.head, remainingQuantums - 1 )
              else r
            }

        nextValue( Nil, trxCount, quantums ).reverse
      }

    def main( args: Array[ String ] ) =
      {
        val d = makeDist( 2, 6 )
        for( val i <- d )
          System.out.print( i + "," )
      }
  }

Большей компактизации в Scala я достичь не смог. (Имхо, решение на Nemerle выиграло бы у Scala только за счет отсутствия типов аргументов для вложенной функции nextValue).

Так что выводы у меня сложились не однозначные. С одной стороны, лично для меня, D позволил сделать компактное и выразительное решение в императивном стиле. Плюс очень высокая скорость компиляции. Плюс D очень похож на C++, поэтому портирование (именно портирование, а не переписывание с нуля) имеющегося у меня C++ кода на D выглядит вполне реальным. Плюс D быстр (по крайней мере по тестам быстрее Scala), а производительность мне нужна. Но D не стабилен, хотя процесс его развития только ускоряется (мне так кажется). И библиотек для него кот наплакал, хотя можно пытаться C-ные использовать (вроде libxml2, openssl и пр.)

Но вот с другой стороны... Синтаксис Scala для меня после Ruby как-то ближе (например, все выражения имеют возвращаемые значения). Плюс Scala при критических ошибках (типа выхода за пределы массива) выдает полный stack trace, а D в release вообще помолчать может. Плюс Scala есть везде, где есть Java и для Scala есть все, что есть для Java (или так кажется). Плюс код на Scala можно интегрировать с кодом на Java. Минус то, что императивный код на Scala не так выразителен, как на D. А к функциональности еще привыкать нужно (например, необходимость вызова reverse после возврата из nextValue не слишком очевидна). Ну и под Scala все переписывать нужно

Так что чаша весов до недавнего времени для меня не качнулась пока ни в одну из сторон. Но вот в D появляется поддержка туплов и такие возможности для шаблонных наворотов, которые C++никам и не снились. Да только для меня это как еще один гвоздь в крышку гроба D выглядит, к сожалению


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
D и замыкания.
От: FR  
Дата: 17.11.06 09:27
Оценка:
Новый D стал нормально подерживать замыкания?

Такой код:
import std.stdio;

int delegate(int) test(int x)
{
return (int y) {return x + y;};    
}

void main()
{
writefln(test(123)(1));
writefln(test(10)(10));
}

Работает правильно.
Кто нибудь в курсе это так, или случайные совпадения , а то я в документации про замыкания ничего ни нашел.
Re[3]: Ой, чо с D деется-то!?
От: ie Россия http://ziez.blogspot.com/
Дата: 17.11.06 09:48
Оценка: 15 (1)
Здравствуйте, eao197, Вы писали:

E>Большей компактизации в Scala я достичь не смог. (Имхо, решение на Nemerle выиграло бы у Scala только за счет отсутствия типов аргументов для вложенной функции nextValue).


Прошу:

#pragma indent

using System.Console
using System.Math

def makeDistrib(trxCount : int, quantums : int)
    mutable r : list[int] = []
    mutable remainingTrx = trxCount
    mutable remainingQuantums = quantums
    foreach (_i in [1..quantums])
        r ::= Round(remainingTrx / (remainingQuantums :> double)) :> int
        remainingTrx -= r.Head
        --remainingQuantums
    r

def r = makeDistrib(2, 6)
WriteLine($"$r")
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[4]: Ой, чо с D деется-то!?
От: ie Россия http://ziez.blogspot.com/
Дата: 17.11.06 09:53
Оценка:
Здравствуйте, ie, Вы писали:

ie>
ie>#pragma indent

ie>using System.Console
ie>using System.Math

ie>def makeDistrib(trxCount : int, quantums : int)
ie>    mutable r : list[int] = []
ie>    mutable remainingTrx = trxCount
ie>    mutable remainingQuantums = quantums
ie>    foreach (_i in [1..quantums])
ie>        r ::= Round(remainingTrx / (remainingQuantums :> double)) :> int
ie>        remainingTrx -= r.Head
ie>        --remainingQuantums
ie>    r

ie>def r = makeDistrib(2, 6)
ie>WriteLine($"$r")
ie>


Выделенные декларации типов, безусловно, лишние. Для quantums декларация необходима, хотя мне кажется ее вполне можно было бы вывести из [1..quantums], но тут не уверен, надо смотреть.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Re[2]: Ой, чо с D деется-то!?
От: ie Россия http://ziez.blogspot.com/
Дата: 17.11.06 10:01
Оценка:
Здравствуйте, Андрей Хропов, Вы писали:

АХ>Да, а вот здесь некто Reiner Pope соорудил шаблон RealCurry, который делает из функций типа plus(1,2,3) функции типа curried_plus(1)(2)(3):


Набросал макрос работающий аналогично. В Немерле он, конечно, нафиг не нужен, но ....

  macro RealCurry (func)
  {
    def typer = Macros.ImplicitCTX ();
    def smtype = typer.TypeExpr (func).Type.Hint;
    match (smtype)
    {
      | Some (MType.Fun as mtype) => 
        match (mtype.from)
        {
          | MType.Tuple (args) => 
            def makeCurryFunction (argCount, argNames)
            {
              if (argCount == 0)
                <[ $func(.. $argNames) ]>
              else
              {
                def x = Macros.NewSymbol ();
                def pe = <[ $(x : name) ]>;
                <[ ($pe) => { $(makeCurryFunction (argCount-1, argNames + [pe])) } ]>
              }
            }
            makeCurryFunction(args.Length, []);
          | MType.Class => 
            <[ $func ]>
          | MType.Void => 
            Message.FatalError (func.Location, $"`$func' should have at least one parameter.");
          | _ => 
            Message.FatalError (func.Location, $"Hmmm... Some strange arguments...");
        }
      | _ => Message.FatalError (func.Location, $"`$func' should be a function.");
    }
  }


Тест:

  module RealCurryTest
  {
    public Run () : void
    {
      def plus = (x, y, z) => { x + y + z };
      def cplus = RealCurry(plus);
      WriteLine(cplus(1)(2)(3));

      def mult = (x, y, z) => { x + y * z };
      def cmult = RealCurry(mult);
      WriteLine(cmult(1)(2)(3));
    }
  }


Что по поводу замечания
Автор: FR
Дата: 17.11.06
FR то согласен с ним на все 100. Давайте уж тогда со всеми языками сравнивать. А то как-то действительно часто всплывают однобокие темы: Nemerle vs ?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Превратим окружающую нас среду в воскресенье.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.