Re[16]: Следующий язык программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.05 03:03
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Тады ой. Тады все. Хотя

ЗХ>
ЗХ>int complexSum = 0;
ЗХ>complexSum += select(array, _1 % 2 == 0);
ЗХ>complexSum *= select(array, _1 % 2 != 0);
ЗХ>


ЗХ>Но простые случаи, имхо, вполне неплохо бы смотрелись с таким штуками


Все украдено до нас (с)
var y = (from x in array where x % 2 == 0 select x).Sum();

C# 3.0 — query comprehensions

Или по простому:
var y = array.Where(x => x % 2 == 0).Sum();
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Следующий язык программирования
От: Зверёк Харьковский  
Дата: 10.10.05 03:13
Оценка:
Здравствуйте, VladD2, Вы писали:

ЗХ>>Тады ой. Тады все. Хотя

ЗХ>>
ЗХ>>int complexSum = 0;
ЗХ>>complexSum += select(array, _1 % 2 == 0);
ЗХ>>complexSum *= select(array, _1 % 2 != 0);
ЗХ>>


ЗХ>>Но простые случаи, имхо, вполне неплохо бы смотрелись с таким штуками


VD>Все украдено до нас (с)

VD>
VD>var y = (from x in array where x % 2 == 0 select x).Sum();
VD>

VD>C# 3.0 — query comprehensions

VD>Или по простому:

VD>
VD>var y = array.Where(x => x % 2 == 0).Sum();
VD>


Мне не нравится.
Слишком много "лишних концепций".
Хотя, конечно, дело вкуса.

ЗЫ: к слову, где-то кроме буст::лямбда используется "дефолтное имя" (типа _1, _2 ...) для переменной, выбираемой из контейнера?
В смысле, последнюю запись оччень хочется сократить до
VD>
VD>var y = array.Where(_1 % 2 == 0).Sum();
VD>


Где-то так принято?
FAQ — це мiй ай-кью!
Re[18]: Следующий язык программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.10.05 04:10
Оценка:
Здравствуйте, Зверёк Харьковский, Вы писали:

ЗХ>Мне не нравится.

ЗХ>Слишком много "лишних концепций".
ЗХ>Хотя, конечно, дело вкуса.

ЗХ>ЗЫ: к слову, где-то кроме буст::лямбда используется "дефолтное имя" (типа _1, _2 ...) для переменной, выбираемой из контейнера?

ЗХ>В смысле, последнюю запись оччень хочется сократить до
VD>>
VD>>var y = array.Where(_1 % 2 == 0).Sum();
VD>>


ЗХ>Где-то так принято?


В Смолтоке используются иенованные параметры. Только там их везде нужно указывать. Получается винигрет.

А то что предложил ты — это как раз очень плохо. И не ясно что обозначет этот _1, и вообще не видно, что присутствует лямбда.
Шарп же работат очень красиво. Он выводит типы параметров исходя из типа аргумента (который в данном случае явяется делегатом). По тому же приципу выводится тип "y". Полная запись была бы:
int y = array.Where((int x) => x % 2 == 0).Sum();


ЗЫ

А по первому случаю оно сложно потому, что действия тривиальные. Когда дело доходит до серьезных запростов, то sql-подобный синтаксис становится очень даже удобным, так как более декларативен. Ну, и как бенефит если запрос идет не к коллекциям размещенным в памяти, а к СУБД, то этот запрос автоматом передается серверу и выполняется удаленно. В коде же отличий нет. В общем, такое универсальное решение частной задачи. Например, вот как просто можно подсчитать количество одинаковых элементов в массиве и вывести сортированный список уникальных элеметов с указанием количества в группе:
int[] array = {1,2,3,2,4,5,7,6,7,2};

var y = from x in array
    where x < 7
    group x by x into z
    orderby z.Key
    select new { Value = z.Key, Встерчается = z.Group.Count() };

foreach (var varue in y)
    Console.WriteLine(varue);

Результат:
{Value=1, Встерчается=1}
{Value=2, Встерчается=3}
{Value=3, Встерчается=1}
{Value=4, Встерчается=1}
{Value=5, Встерчается=1}
{Value=6, Встерчается=1}


Представь себе гору кода которую нужно написать если бы всего этого небыло бы.
Даже на самом C# 3.0 без квари компрехеншона запрос выглядит менее понятно:
var y = array.Where(x => x < 7).GroupBy(x => x).OrderBy(z => z.Key)
    .Select(z => new { Value = z.Key, Встерчается = z.Group.Count() });

Хотя конечно функциональный стиль "рулит". По сравнению с императивным кодом это огромный прогресс.

ЗЫ

Но что по этому поводу скажут апологиты борьбы за производительность? Ведь тоже самое в императивном стиле будет куда быстрее.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Следующий язык программирования
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.10.05 05:20
Оценка:
Здравствуйте, VladD2, Вы писали:
VD>А ссыдлчку можно?
http://rsdn.ru/Forum/Message.aspx?mid=1424567&amp;only=1
Автор: Pavel Dvorkin
Дата: 07.10.05
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.05 06:17
Оценка: +1
Здравствуйте, VladD2, Вы писали:

C>>Эрланг Общение между потоками там происходит с помощью посылки асинхронных сообщений.


VD>Вот именно. Т.е. 1! А по мнению eao197 только он как бы ООЯ (хотя создатели этого языка считают его чистым ФЯ ), а остальные так пос... вышли.


Скромно замечу, что Эрланг я вообще не упоминал, а когда о нем сказал Cyberax, то я поинтересовался, является ли Эрланг ООЯ: Re[23]: Следующий язык программирования
Автор: eao197
Дата: 09.10.05


Так что в сад, батенька, с подобным сарказмом, в сад.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[24]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.05 06:17
Оценка: 1 (1)
Здравствуйте, VladD2, Вы писали:

VD>В общем, мы как всегда ушли от темы. Ты ничего не сказал ото, что помешает ООП если в языке будут использоваться методы, а не послка сообщений. И никак не опроверг утверждение, что с точки зреня ООП вызов метода == посылке сообщения. Вместо этого ты ударился в рассуждения о многопоточном взаимодействии.


Я не говорил, что "отсылка сообщений" как "вызов метода" помешает ООП. Я сказал, что в большинстве ООЯ этой политики просто нельзя изменить вообще. Даже когда очень сильно захочется. Хотя в самом ООП не сказано, что объекты взаимодействуют друг с другом посредством только вызовов методов друг друга.

Повторю то, что я говорил Sinclair-у вот здесь: Re[22]: Следующий язык программирования
Автор: eao197
Дата: 08.10.05

В том то и дело, что традиция эта в таких языках, как C++, Java, C# и пр. зашита намертво. Если нам в 5% случаев потребуется именно fire and forget, то сделать это в том же самом синтаксисе, что и обычный call, мы уже не сможем. А вот если бы смогли, это бы я и считал прорывом.


А ударился в рассуждения о многопоточности потому, что сейчас это актуально. Сам же в последнее время ссылки на concurrent c++
Автор: alexeiz
Дата: 05.10.05
приводишь при каждом удобном случае. А есть и еще такое свежее обсуждение: Язык и архитектура программирования будущего
Автор: GlebZ
Дата: 03.10.05
, в котором так же вопросы распараллеливания затрагиваются.

И лично я думаю, что многопоточнось в том, виде, как она поддерживается в том же C++ средствами Boost или ACE -- это примитив. От которого нужно уходить. А асинхронные делегаты в C# здесь не сильно далеко ушли. И, имхо, если бы в языке "отсылку сообщения" по выбору программиста можно было бы представить либо в виде "вызова метода", либо в виде "отсылки сообщения" (но в одинаковом синтаксисе), то это бы дейсвительно могло упростить создание многопоточных приложений.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[20]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.05 06:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>>>Кстати, даты нужно помнить. Ява 1.5 появилась в 2005.


E>>Это ты зря. Сентябрь 2004 года. Официального пресс-релиза на sun.com я не нашел, но вот, например: http://weblogs.java.net/blog/kgh/archive/2004/09/j2se_50_tiger_i.html


VD>ОК, в 2004. Дела это не меняет. Дженерики появились в конце 2004-го. И они только отдаленно напоминают С++-ные шаблоны. Так что вряд ли тут можно говорить том, что дело было втом, что авторы неуспели осознать. Приемущество шаблонов было очевидно еще в 1996-ом. И вряд ли стоило ждать 8 лет если это было просто упущение. Это был именно что идеологический выбор. В том виде в каком шаблоны были встроены в С++ они были не приемлемы для C# и Явы, так как невписывались в идеологию этих языков.


Имхо, существует большая разница между намерениями и возможностями. Может быть авторы Java и понимали преимущества шаблонов/generic-ов в 1996. Но вот реализовать их смогли только в 2003-2004. А между выходом Java 1.0 и Java 1.5 ведь еще были 1.1, 1.2, 1.3, 1.4. Но выпустили они generic-и только когда силенок хватило.

В Java вообще много такого, что на водит на мысль о "включили, потому что смогли сделать". А что не включили, то от лукавого Множественное наследование, например, нормальное (ведь в managed среде от множественного наследования совсем не много бед) или перегрузка операторов.

E>>Нет, это значит: "Много 'C с классами' и много с шаблонами". Много, но не черезмерно (камень в огород boost-а)


VD>Я бы сказал, так "и чуть-чуть ООП-а".


Ну тебе виднее. Мы же с тобой над общими проектами уже давно работаем, постоянно кодом обмениваемся

Случай, ты серьезно думаешь, что ООП -- это наше все? Что ООП -- вершина эволюции и дальше идти уже не куда?
Ах забыл, вершина -- это КОП.

E>> Главное противоречие в нем, что "отсылка" это асинхронное понятие, а "вызов" -- это синхронное.


VD>Ты в свои СОбжектс (или как их там) переиграл.


SObjectizer (Собжектайзер), пожалуйста, если не сложно

VD> Ассинхронность ортогональное понятие к ООП. За исключением Эрлэнг, и с наряжкой дотнетных, я низнаю ни одного ЯП который поддерживал бы поддерживал посылку ассинхронных сообщений.


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

E>>>> В Ruby, например, это так. Там можно вызовы методов (сообщения) перехватывать, сохранять, передавать другому или воспроизводить через какое-то время. В C# это возможно?


VD>>>Издевашся?


E>>Нет. Рассказываю о том, чего узнал.


VD>И что, Руби вызвает все ассинхронно, или это ты так пылася зачмырить вызов метода?


Зачмырить -- это перехватить?
Да я имел в виду именно это.

E>>Имхо, перехват методов и последующее их воспроизведение, или трансляция вызова в параллельный поток -- все это возможно и в статически типизированном языке.


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


Влад, есть два приниципиально разных способа взаимодействия параллельных процессов:
-- отсылка сообщений. Отославший сообщение процесс не знает о результатах обработки сообщения. Может даже не знать, дошло ли сообщение до получателя. Ответ так же приходит в виде сообщения. Это полностью асинхронный механизм взаимодействия;
-- удаленный вызов в той или иной форме. Та же самая CORBA или RPC.

Оба эти подхода имеют свои сильные и слабые стороны. Но самое главное, что они практически не совместимы друг с другом. Если система строится на основе обмена ссообщениями, то попытки выразить это через якобы синхронные операции только замутняют суть происходящего. В этом случае гораздо понятнее написать send(<что-то там>), чем делать вызовы BeginInvoke, EndInvoke. Имхо.

VD>В общем, подобные решения — это забота о текущем при полном наплевательстве на будущее. Помяни мое слово. Через некоторое время управляемые языки сначала догонят С++ по производительности, а потой выйдут вперд. Просто это непростая задача требующая времени. За управляемыми языками множество приемуществ вроде стройной мат.модели и отсуствия возможности влезть шаловливыми рученками программиста, а за С++ только одно — простота реализации.


Ok. Будем ждать.

E>>Когда на C# будет написанно столько же, сколько на C++ и таким же количеством ламеров, тогда и можно будет сравнить, кто и сколько жрет памяти и насколько что тормозит.


VD>Хм. На Яве уже пишется не меньше кода чем на С++. Тому свидетельством является сорсфордж. А если сложить C# и Яву, то пишется пожалуй по более. А уж про ламеров аргумент совсем "мимо кассы". Уж чего, чего, а в виду простоты на Яве и C# пишут куда больше ламеров.


Да?
Может это все за счет разработки enterprise систем? А то у меня из .Net-овских приложений только Janus и стоит. А Java-овских давно уже не было.

E>>А ситуация такая: deliver_sm_t и data_sm_t -- это инкапсуляция разных PDU. Между ними есть небольшие пересечения по функциональности. Оба они is-a PDU. Но deliver_sm_t не есть data_sm_t и наоборот.


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


А мы эту тему с Sinclair-ом уже пообсуждали.

E>>Вот только C++ шаблоны позволяют решать подобные задачи легко и без лишних усилий (со статической типизацией при этом).


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




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

E>>Принципиальная: рефлексия для любого типа или рефлексия только для того, что я явно заказал.


VD>Может пусть компиляторы и рантаймы думают об эффективности? Зачем мне еще одна головная боль?


Блин, да я тебе об этом и говорю. В C++ эта головная боль у меня. А в Java -- у компилятора.

E>>>>А расскажи мне, как третий модуль возьмет два типа из двух других модулей? Просто по имени? Не зная даже, какие интерфейсы они поддерживают?


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


Ок. Предположим, что модуль, который предоставляет generic-контейнер, содержит класс PriorityQueue с методами:
PushBack
PopFront
Front
Size

Модуль, который предоставляет класс, который должен быть помещен в контейнер, предоставляет класс Diagram с методами:
Initialize
Normalize
Calculate


Третий модуль, который должен использовать классы из двух предыдущих модулей, знает названия классов PriorityQueue и Diagram, но не знает их интерфейсов. Как он будет с ними работать в .Net-е?

E>>Признаю, что не знал, что есть асинхронные делегаты.


VD>Ну, тогда банальный логический вывод позволяет так же заключить, что раз ты считашь такую фичу прорывом, то только на этом основании дотнет и C# являются прорывом. А таких фич в них просто море. То что ты о них не знашь или незнашь как их применить — это твоя проблема. И именно по этому ты не считашь дотнет прорвом и перечисляешь довольно второстепенные вопросы как проры.


Влад, ты занимаешься КОП и тебе кажется, что все, что идет во благо КОП -- это прорывы, и КОП -- это следующая парадигма после ООП.
Я занимаюсь разработкой многпоточных и многопроцессовых систем. Для меня многопоточнось и асинхронность важны, но асинхронные делегаты, имхо, в этой области совсем не прорыв.

E>>С делегатом я сохраняю куда-то ссылку на объект и ссылку на метод (создаю делегат) и вручную вызваю BeginInvoke. Все это вручную.


VD>Какою еще ссылку? Получашь делегат от метода и вперед. Сахранея все дотнет.


В делегате. Он этом я и сказал. Но чтобы создать делегат мне ведь нужны ссылка на объект и ссылка не метод.

E>>Когда же я говорил про асинхронные методы, я подразумевал, что все эти вещи за меня сделает компилятор -- мне нужно только вызвать метод и все. Очень похоже на то, что Саттер предлагает в concurrent C++.


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


Ну и? Ты же смотришь на C++ через призму своих догм. Почему мне от такого подхода отказываться.
И если мне не нравятся паттерны распараллеливания, предлагаемые Саттером, то:
— я могу оказаться не один
— я ими не буду пользоваться в пользу более удобных мне.

E>>Если ты не видишь разницы между такими подходами, то вот аналогия: в С/Oberon виртуальные методы можно эмулировать вручную за счет ручного управления vtbl. А в ОО языках программисту это не нужно -- сам язык такими низкоуровневыми вещами занимается.


VD>Я же понял к чему ты клонишь. Так вот твой С/Oberon — это фрэймворк вроде MSMQ, а Саттер говорил о встраивании в язык паттернов упращающих арспараллеливание кода. Это разные вещи хотя они используют и похожие механизмы.


Именно. Но если паттерны распараллеливания встраивать в язык, то туда придется добавлять и другие штуки по управлению параллельностью:
— управление размером пула потоков;
— управление приоритетом потоков.

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

E>>Очень возможно. Мне так же кажется, что Ruby, как и C++ -- язык для небольших команд. Так же, как и Smalltalk.


VD>Ага. То-то на С++ пишут самые большие проекты. А на С еще больше.


Мне кажется, что размер проекта не 1 в 1 соответсвует размеру команды.

E>>Я же говорю про production систему.


VD>А кто будет в ней отладкой заниматься? И почему этот орел не может взять отладочную версию?


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

E>>У Rubyist-ов sourceforge не в почете. Есть www.rubyforge.org и Ruby Application Archive. Основные проекты там хостятся.


VD>Понятно. Такие же извращенцы как и Смолтокщики. Ну, у тех-то хоть особенности языка подталкивают. А Рубистам то зачем это?


А зачем им sourceforge?
Не, ну вы, мейнстримщики, меня иногда просто убиваете. Появился .Net, сразу вопрос: "Нафига нужно все остальное". Есть Windows: "Все остальные системы меня не интересуют". Существует в сети sourceforge, значит все OpenSource проекты должны быть только там.

У Ruby есть community. Имхо, вполне разумно, что все разработки этого community находятся в одном хорошо известном месте. А не раскиданы по какому-то монстрообразному sourceforge. К тому же rubyforge является хранилищем RubyGems, чего на sourceforge вряд ли можно было достичь. Да и в этом централизованном хранилище RubyGems есть проекты, которые на rubyforge и не хостятся.

VD> На этих левых серверах даже статистики нет.


На rubyforge она есть прямо на стартовой странице. Когда я тебе давал эту ссылку, там было 919 проектов.
А RAA -- это старый архив, его теперь по актуальности rubyforge переплюнул.

VD>Как и нет чисто Руби проектов на сорсфордже.


На rubyforge посмотри!!!
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[22]: Следующий язык программирования
От: GlebZ Россия  
Дата: 10.10.05 09:36
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Странный у тебя опыт, однако. Ты в курсе, что с современными БД общение ведется не на уровне императивных алгоритмов, а на уровне декларативных запросов? Мы и так занимаемся полнейшими извращениями с джетом пытаясь заствить его работать немного разумнее, но и это не особо удается. Пень он тупой. И то что он на С++ написан ему никак не помогате.

Оптимизация схемы БД дает выйгрыши на порядок большие чем императивщина и процессоры.

GZ>> Уже проходило, что для поиска — просто ничего не было сделано. Да и работу с БД там можно оптимизировать.


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

Не ты. Источник — Re[3]: Неэффективности программ -- ДА!
Автор: Odi$$ey
Дата: 07.10.05


VD>Итак, попробу так чтобы дошо до последнего рабочего с его колхозницей.

Ээээ. Я в данном случае, по моему, не имел ввиду зависимость от средства разработки, от unmanaged или managed Я не пытался утверждать о конкретике(в данном случае Янус), я пытался говорить о правилах.

VD>Что касается поиска, то его сразу делали без рассчета на великую скорость. Писать собственный индексирующий движок слишком тяжело. Бесплатных и вто же время качественных мы пока на горизонте не видим. А SQL-серверы, даже коммерческие еще пока что применяют те самые плохие алготимы которые приводят к тмоу, что простой запрос "%некий паттерн%" приводят поиску методом перебора, что приводит к тормозам на больших БД.

А разделить messages по форумам не пробовали? Или разделить ее на части другим способом? Всегда находится резерв на работе БД. Этим можно заниматься вечно.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[20]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.05 12:50
Оценка: 96 (3)
Здравствуйте, Зверёк Харьковский, Вы писали:

E>>Ну да бог с ним. Меня ты не переубедил, а правду пускай историки ищут.


ЗХ>Вот спасибо. Вот уж спасибочки...


Может тебе, как историку, интересна будет приведенная вот здесь схема эволюции языков (взято отсюда: http://www.levenez.com/lang/ только уж я не знаю, насколько этому источнику можно доверять, хотя на него и O'Reilly ссылается: http://www.oreilly.com/pub/a/oreilly/news/languageposter_0504.html).

Так вот получается, что Java произошла от Oak, который вобрал в себя: Ada 83, Objective C, C++, Cedar, Smalltalk-80, Scheme. Не хилая солянка, однако (но синтаксис-то C++ный ).
А у C# было всего три прародителя: Deplhi 5, C++, Java. (Но ведь и Java имеет в родителях C++, так что у C# с C++ довольно тесные родственные связи ).
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[19]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.10.05 19:27
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>
VD>int[] array = {1,2,3,2,4,5,7,6,7,2};

VD>var y = from x in array
VD>    where x < 7
VD>    group x by x into z
VD>    orderby z.Key
VD>    select new { Value = z.Key, Встерчается = z.Group.Count() };

VD>foreach (var varue in y)
VD>    Console.WriteLine(varue);
VD>

VD>Результат:
VD>
VD>{Value=1, Встерчается=1}
VD>{Value=2, Встерчается=3}
VD>{Value=3, Встерчается=1}
VD>{Value=4, Встерчается=1}
VD>{Value=5, Встерчается=1}
VD>{Value=6, Встерчается=1}
VD>


VD>Но что по этому поводу скажут апологиты борьбы за производительность? Ведь тоже самое в императивном стиле будет куда быстрее.


Ну что, Влад, помучать тебя длинными исходниками?
typedef std::map< int, int > tmp_map_t;
typedef std::map< int, std::string > result_map_t;

struct selector_t
    {
        tmp_map_t & m_tmp;
        selector_t( tmp_map_t & tmp ) : m_tmp( tmp ) {}

        void operator()( int x ) { if( x < 7 ) m_tmp[ x ]++; }
    };

result_map_t::value_type
transformer( const tmp_map_t::value_type & v )
    {
        char sz[ 16 ];
        std::sprintf( sz, "%d", v.second );

        return result_map_t::value_type( v.first, std::string( "occurencies: " ) + sz );
    }

int
main()
    {
        int array[] = { 1,2,3,2,4,5,7,6,7,2 };

        tmp_map_t tmp;
        std::for_each( array, array + sizeof( array ) / sizeof( array[ 0 ] ), selector_t( tmp ) );

        result_map_t r;
        std::transform( tmp.begin(), tmp.end(), std::inserter( r, r.begin() ), transformer );

        for( result_map_t::iterator it = r.begin(), it_end = r.end(); it != it_end; ++it )
            std::cout << it->first << " " << it->second << std::endl;
    }

Печатает:
1 occurencies: 1
2 occurencies: 3
3 occurencies: 1
4 occurencies: 1
5 occurencies: 1
6 occurencies: 1


Ну, а если у тебя хватило терпения дочитать до сюда, то бонус: решение на Ruby
array = [ 1,2,3,2,4,5,7,6,7,2 ]

y = array.
    select { |x| x < 7 }.
    inject( {} ) { |m, x| m[ x ] = m.fetch( x, 0 ) + 1; m }.
    sort.
    collect { |z| { z[ 0 ], "Occurencies: #{z[1]}" } }

y.each { |v| p v }

Печатает:
{1=>"Occurencies: 1"}
{2=>"Occurencies: 3"}
{3=>"Occurencies: 1"}
{4=>"Occurencies: 1"}
{5=>"Occurencies: 1"}
{6=>"Occurencies: 1"}


Мои решения работают и под Windows и под Linux. А твои?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[20]: Следующий язык программирования
От: alexeiz  
Дата: 10.10.05 21:40
Оценка: 11 (1)
Здравствуйте, eao197, Вы писали:

E>Ну что, Влад, помучать тебя длинными исходниками?

E>
E>typedef std::map< int, int > tmp_map_t;
E>typedef std::map< int, std::string > result_map_t;

E>struct selector_t
E>    {
E>        tmp_map_t & m_tmp;
E>        selector_t( tmp_map_t & tmp ) : m_tmp( tmp ) {}

E>        void operator()( int x ) { if( x < 7 ) m_tmp[ x ]++; }
E>    };

E>result_map_t::value_type
E>transformer( const tmp_map_t::value_type & v )
E>    {
E>        char sz[ 16 ];
E>        std::sprintf( sz, "%d", v.second );

E>        return result_map_t::value_type( v.first, std::string( "occurencies: " ) + sz );
E>    }

E>int
E>main()
E>    {
E>        int array[] = { 1,2,3,2,4,5,7,6,7,2 };

E>        tmp_map_t tmp;
E>        std::for_each( array, array + sizeof( array ) / sizeof( array[ 0 ] ), selector_t( tmp ) );

E>        result_map_t r;
E>        std::transform( tmp.begin(), tmp.end(), std::inserter( r, r.begin() ), transformer );

E>        for( result_map_t::iterator it = r.begin(), it_end = r.end(); it != it_end; ++it )
E>            std::cout << it->first << " " << it->second << std::endl;
E>    }
E>


Право слово, доисторический код какой-то. Так уже никто не пишет.
int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
typedef map<int, int> map_t;
typedef map_t::value_type val_t;
map_t occur;

for_each(begin(a), end(a),
        if_(_1 < 7) [ bind(&map_t::operator[], &occur, _1)++ ]);

for_each(begin(occur), end(occur),
        cout << bind(&val_t::first, _1) << ":" << bind(&val_t::second, _1) << "\n");


E>Ну, а если у тебя хватило терпения дочитать до сюда, то бонус: решение на Ruby

E>
E>array = [ 1,2,3,2,4,5,7,6,7,2 ]

E>y = array.
E>    select { |x| x < 7 }.
E>    inject( {} ) { |m, x| m[ x ] = m.fetch( x, 0 ) + 1; m }.
E>    sort.
E>    collect { |z| { z[ 0 ], "Occurencies: #{z[1]}" } }

E>y.each { |v| p v }
E>

E>Мои решения работают и под Windows и под Linux. А твои?

Мои тоже .
Re[20]: Следующий язык программирования
От: Павел Кузнецов  
Дата: 10.10.05 22:37
Оценка: +1
VladD2,

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

>
> Ага. Согласен. Я от желания побайтно скопировать объекты отвыкал где-то год. Страшно приставучее заболевание. <...>

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

> ПК> Разница не столько в явном или неявном задании контрактов, сколько в том, какого рода контракты предполагаются или явно задаются там и там.

>
> Нет, уж, позволь... Как раз это основное отличие. Оно и приводит к неприминимости шаблонов в дотете. Ведь шаблоны можно будет использовать только внутри одного модуля. <...>

Это и определяется тем, какого типа ограничения накладываются на аргументы шаблонов/generics: структурные или "подтиповые". С чем ты споришь-то?..

> ПК> В C++ -- требование к типу обладать некоторой структурой. Concepts это только позволят задавать явно. Наследования от каких-либо интерфейсов для этого нужно не будет.

>
> Ну, да. Те самые "утиные интерфейсы". В принципе удачное решение некоторых пробем С++.

Проблемы Си++ здесь совершенно ни при чем. Это просто-напросто возможность, которая либо есть, либо нет. Если ее нет, то часть техник становится недоступной. Если она есть, то появляется дополнительный уровень сложности, с ней ассоциированный. В C# такой возможности в непосредственном виде нет (можно получить некоторое подобие через reflection).

> ПК>Кроме явного задания concepts ничего от текущей ситуации в C++ не изменится.

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

Это изменится, безусловно. Не изменится принципиально то, какого рода контракты будут требоваться от аргументов шаблона. Это по-прежнему будет соответствие некоторым "структурным" требованиям, а не требование унаследовать тот или иной интерфейс/абстрактный класс. Точнее, такое требование, возможно, и можно будет задать, но вряд ли это будет основным способом выражения требований к аргументам шаблонов.

С другой стороны, вполне вероятно, что в CLI будут постепенно добавлять новые и новые структурные требования. Сейчас уже есть возможность указать допустимость использования new T(). В будущем может добавиться возможность указывать еще какие-нибудь "структурные" требования типа поддержки тех или иных перегруженных операторов и т.п.

Но сейчас шаблоны C++ именно в этом отношении лежат по другую сторону от водораздела "структурные"/"подтиповые" требования по отношению к generics C#/Java.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[20]: Следующий язык программирования
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.10.05 02:29
Оценка:
Здравствуйте, eao197, Вы писали:

Ну, о полной заднице вышедшей на С++ говорить наверно не стоит. Поговорим о Руби...

E>Ну, а если у тебя хватило терпения дочитать до сюда, то бонус: решение на Ruby

E>
E>array = [ 1,2,3,2,4,5,7,6,7,2 ]

E>y = array.
E>    select { |x| x < 7 }.
E>    inject( {} ) { |m, x| m[ x ] = m.fetch( x, 0 ) + 1; m }.
E>    sort.
E>    collect { |z| { z[ 0 ], "Occurencies: #{z[1]}" } }

E>y.each { |v| p v }
E>

E>Печатает:
E>
E>{1=>"Occurencies: 1"}
E>{2=>"Occurencies: 3"}
E>{3=>"Occurencies: 1"}
E>{4=>"Occurencies: 1"}
E>{5=>"Occurencies: 1"}
E>{6=>"Occurencies: 1"}
E>


Что же, это конечно намного лучше чем С++, но все же с квари компрехеншоном оно значительно понятнее получается. Да, и чесно говря даже без них все равно на Шарпе понятнее. Все эти методы с бессмысленными названиями вроде inject и fetch читаемость убивают полностью.

E>Мои решения работают и под Windows и под Linux. А твои?


Погоди, сделают в Моно поддержку второго фрэймворка и будет работать хоть на Мак ОСе. Хотя лично мне это до лампочки. Я на них в последнее время даже из под ВМВари не смотрю.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[21]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.10.05 05:37
Оценка: 10 (2) +1 :))
Здравствуйте, alexeiz, Вы писали:

A>Право слово, доисторический код какой-то.


A> Так уже никто не пишет.


Попробуй написать так там, где нет Boost-а.

A>
A>int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
A>typedef map<int, int> map_t;
A>typedef map_t::value_type val_t;
A>map_t occur;

A>for_each(begin(a), end(a),
A>        if_(_1 < 7) [ bind(&map_t::operator[], &occur, _1)++ ]);

A>for_each(begin(occur), end(occur),
A>        cout << bind(&val_t::first, _1) << ":" << bind(&val_t::second, _1) << "\n");
A>


Слушай, а оно точно работает? А откуда выражение end(a) узнает правую границу вектора a?

Вот за эти птичьи поддиалекты C++ мне и не нравится нынешнее направление развития C++. Что такое if_ -- это другой вариант if-а? А откуда берется переменная _1? А могу ли я обратиться к _2? А почему после if_ составной оператор записывается не в фигурных скобках, а в квадратных? А bind(&val_t::first, _1) -- это, надо полагать, завуалированный вызов _1.first? Определенно, с задачей скрыть смысл написанного bind хорошо справился


На самом деле, будучи фанатом C++ я раньше с интересом смотрел на подобные открытия и достижения. Только они кажутся достижениями пока не узнаешь, как удобно такие же вещи делаются в других языках. В том же Ruby, например, или в Python-е. После этого точка зрения меняется. Сейчас это выглядит как: "Вау, перцы, мы в очередной раз позанимались нетрадиционным сексом с шаблонами и вот чего родить смогли! Почти C++. Почти не ограниченный. Почти не нужно быть C++ гуру для понимания этого. Почти не нужно 10 летнего опыта, чтобы использовать это". Мне это уже не кажется привлекательным. Меня бы больше устроил какой-то такой вариант:
int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
typedef map<int, int> map_t;
typedef map_t::value_type val_t;
map_t occur;

for_each(begin(a), end(a),
        void lambda( const int & x ) { if( x < 7 ) occur[ x ]++; } );

for_each(begin(occur), end(occur),
        void lambda( const val_t & x ) { std::cout << x.first << ": " << x.second << std::endl; } );


И по объему не больше, и читабельность выше (нет птьичих расширений вида if_[]), и понятность (для новичков, изучающих C++), и мощность (т.е. внутри lambda любые возможности языка можно использовать, в том числе и вложенные lambda).

Только чего-то мне подсказывает, что я могу подобных расширений C++ и не дождаться. А пока буду ждать, для меня безопаснее по старинке. С рукописными объектами-функторами. Опыт показывает, что при сопровождении (в том числе и не мной) это оправдывается.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[21]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.10.05 05:37
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, о полной заднице вышедшей на С++ говорить наверно не стоит.

+1

Угу. Мне было просто самому интересно, как на C++ получится.

Я поразмышлял еще о коде в стиле select...from...orderby. Мне кажется, что у компилятора здесь появляются возможности для неслабой оптимизации выполнения. Например, неявно для программиста компилятор и run-time может распараллелить некоторые операции по доступным в системе процессорам. Скажем where x < 7 для вектора может паралелльно вычислятся по разным диапазонам вектора. Аналогично и сортировкой/группировкой.

Для некоторых классов приложений (однопоточной или с небольшим количеством потоков) это может дать существенный выигрыш в производительности без всякого участия программиста. А C++ное решение выглядит как оптимизированный ассемблер для конкретного процессора. Он будет отлично работать только на данном типе процессора, но на новых архитектурах вполне может проиграть декларативному коду в стиле select...from (хотя разные for_each-и и transform-ы так же могут быть распаралеллены, но мне в это с трудом верится).

VD> Поговорим о Руби...

VD>Что же, это конечно намного лучше чем С++, но все же с квари компрехеншоном оно значительно понятнее получается. Да, и чесно говря даже без них все равно на Шарпе понятнее.

Смотря в каком варианте. В варианте с select понятнее, хотя я так и не понял, откуда берется объект z с методами Key и Group.

VD> Все эти методы с бессмысленными названиями вроде inject и fetch читаемость убивают полностью.


Не, сложность только с inject. fetch очень простой метод -- он возвращает из Hash-мапа значение для ключа. Если ключа нет, то он возвращает указанное значение.

E>>Мои решения работают и под Windows и под Linux. А твои?


VD>Погоди, сделают в Моно поддержку второго фрэймворка и будет работать хоть на Мак ОСе. Хотя лично мне это до лампочки. Я на них в последнее время даже из под ВМВари не смотрю.


Влад, так все-таки, на какой версии C# сделаны приведенные тобой примеры? Мне показалось, что на 3.0, а не на 2.0.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[22]: Следующий язык программирования
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.10.05 05:46
Оценка:
Здравствуйте, eao197, Вы писали:

E>
E>int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
E>typedef map<int, int> map_t;
E>typedef map_t::value_type val_t;
E>map_t occur;

E>for_each(begin(a), end(a),
E>        void lambda( const int & x ) { if( x < 7 ) occur[ x ]++; } );

E>for_each(begin(occur), end(occur),
E>        void lambda( const val_t & x ) { std::cout << x.first << ": " << x.second << std::endl; } );
E>


А для того, чтобы не приявязывать lambda к локальному контексту (доступ к occur, например) можно применить такой метод bind-инга параметров:
for_each( begin(a), end(a),
        void lambda( const int & x, map_t & m = occur )
            { if( x < 7 ) m[ x ]++; }
    );
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[22]: Следующий язык программирования
От: Cyberax Марс  
Дата: 11.10.05 06:01
Оценка:
eao197 wrote:

> И по объему не больше, и читабельность выше (нет птьичих расширений

> вида if_[]), и понятность (для новичков, изучающих C++), и мощность
> (т.е. внутри lambda любые возможности языка можно использовать, в том
> числе и вложенные lambda).

А не получится так сделать, да еще чтобы нормально сочеталось с
остальными функциями. Например, какой у лямбда-функции будет тип? Какое
время жизни?

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

> Только чего-то мне подсказывает, что я могу подобных расширений C++ и

> не дождаться. А пока буду ждать, для меня безопаснее по старинке. С
> рукописными объектами-функторами. Опыт показывает, что при
> сопровождении (в том числе и не мной) это оправдывается.

На самом деле, стоит все-таки выучить boost::lambda — писать с ней
такие простые вещи получается быстрее. А в связке со Spirit'ом
становится удобно писать парсеры.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[22]: Следующий язык программирования
От: alexeiz  
Дата: 11.10.05 06:08
Оценка:
Здравствуйте, eao197, Вы писали:

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


A>>Право слово, доисторический код какой-то.

E>
A>> Так уже никто не пишет.
E>

E>Попробуй написать так там, где нет Boost-а.


Там, где нет Boost'а, нужно его сделать.

A>>
A>>int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
A>>typedef map<int, int> map_t;
A>>typedef map_t::value_type val_t;
A>>map_t occur;

A>>for_each(begin(a), end(a),
A>>        if_(_1 < 7) [ bind(&map_t::operator[], &occur, _1)++ ]);

A>>for_each(begin(occur), end(occur),
A>>        cout << bind(&val_t::first, _1) << ":" << bind(&val_t::second, _1) << "\n");
A>>


E>Слушай, а оно точно работает? А откуда выражение end(a) узнает правую границу вектора a?


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

E>Вот за эти птичьи поддиалекты C++ мне и не нравится нынешнее направление развития C++. Что такое if_ -- это другой вариант if-а? А откуда берется переменная _1? А могу ли я обратиться к _2? А почему после if_ составной оператор записывается не в фигурных скобках, а в квадратных? А bind(&val_t::first, _1) -- это, надо полагать, завуалированный вызов _1.first? Определенно, с задачей скрыть смысл написанного bind хорошо справился

E>

_1.first не работает, так как точка не перегружается. Вообще-то по идее там должно быть _1->first. Но это тоже не работает. _2 там есть, и т.д. вплоть до десяти параметров. if_ пришел из Spirit'а. В последствии был адаптирован для Boost.Lambda. Квадратные скобки, потому что это всё суть expression templates.

E>На самом деле, будучи фанатом C++ я раньше с интересом смотрел на подобные открытия и достижения. Только они кажутся достижениями пока не узнаешь, как удобно такие же вещи делаются в других языках. В том же Ruby, например, или в Python-е. После этого точка зрения меняется. Сейчас это выглядит как: "Вау, перцы, мы в очередной раз позанимались нетрадиционным сексом с шаблонами и вот чего родить смогли! Почти C++. Почти не ограниченный. Почти не нужно быть C++ гуру для понимания этого. Почти не нужно 10 летнего опыта, чтобы использовать это". Мне это уже не кажется привлекательным.


Чтобы использовать Boost.Bind или Boost.Lambda не нужно 10 летнего опыта. Нужно всего лишь изучить эту библиотеку. Правил там не много. Документация простая. А как это внутри работает и какие концепции использует знать вовсе не обязательно. Я, например, не знаю (т.е. почти не знаю, так как иногда мне интересно, и я в source поглядываю, но это не сильно помогает).

> Меня бы больше устроил какой-то такой вариант:

E>
E>int a[] = {1, 2, 3, 2, 4, 5, 7, 6, 7, 2};
E>typedef map<int, int> map_t;
E>typedef map_t::value_type val_t;
E>map_t occur;

E>for_each(begin(a), end(a),
E>        void lambda( const int & x ) { if( x < 7 ) occur[ x ]++; } );

E>for_each(begin(occur), end(occur),
E>        void lambda( const val_t & x ) { std::cout << x.first << ": " << x.second << std::endl; } );
E>


E>И по объему не больше, и читабельность выше (нет птьичих расширений вида if_[]), и понятность (для новичков, изучающих C++), и мощность (т.е. внутри lambda любые возможности языка можно использовать, в том числе и вложенные lambda).


Фиг его знает, какие lambda предложат в C++0x. Но то, что ты написал, это небольшой перебор. Можно и короче. Типы повыводить и прочее.

E>Только чего-то мне подсказывает, что я могу подобных расширений C++ и не дождаться. А пока буду ждать, для меня безопаснее по старинке. С рукописными объектами-функторами. Опыт показывает, что при сопровождении (в том числе и не мной) это оправдывается.


Пример с Boost.Lambda великолепно читается. Я, конечно, понимаю, что сперва такая запись может вызвать ступор. Но как только свыкнешся, что подобное возможно, в последствии не вызывает труда читать такой код, даже если ты не знаешь конкретно, что он делает. Код достаточно самодокументирующий.
Re[27]: Следующий язык программирования
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 11.10.05 06:29
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>То есть? В Эрланге используются именно явные сообщения, для которых

C>можно даже задавать грамматику (делать диалоги). Ну и еще Эрланг
C>является чисто функциональным (в нем нет деструктивного присваивания
C>вообще).

Процессы обмениваются сообщениями. Внутри процессов — функциональщина. Вроде бы так.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[4]: Что такое полиморфизм
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 11.10.05 06:54
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>в Яве решили сделать методы виртуальными по-умолчанию (хотя это был явняй перебор).


В C# наоборот. И за это его создателей нужно хорошенько пропесочить.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.